您的位置:首页 > 其它

#Webrtc AGC 算法原理介绍(五)

2017-02-03 11:00 495 查看

Webrtc AGC 算法原理介绍(五)

零、前言

本系列介绍Webrtc的agc算法。webrtc的agc算法对各种情况作了较为详尽的考虑,而且使用了的定点数的方法来实现,因此内容比较多。尽量在这几篇文章中描述清楚。

一、WebRtcAgc_AddFarend

该函数调用了WebRtcAgc_AddFarToDigital函数,其中仅仅是对远端使用WebRtcAgc_ProcessVad函数。该函数的目的是计算远端信号的VAD可信度,用于在Process_Digital中使用,保证远端信号出现的地方信号增益有所减弱。这么做的原因是相信,远端信号出现出很可能出现回声信号。

这里默认信号与近端信号已经做了延时估计对齐处理,然而在Webrtc的程序中,调用WebRtcAgc_AddFarToDigital与调用WebRtcAgc_Process处的信号显然没有严格对齐,此处存在一定的误差。

二、WebRtcAgc_SaturationCtrl

该判断信号是否饱和,注意到在Webrtc_AddMic中计算了包络env的值,16khz采样的数据,10ms的数据是160个samples,分成10块,每块是16个。求每块16个点中平方值最大的点作为包络。

/* compute envelope */
if ((M == 10) && (stt->inQueue > 0)){
ptr = stt->env[1];
} else{
ptr = stt->env[0];
}
for (i = 0; i < M; i++){
/* iterate over samples */
max_nrg = 0;
for (n = 0; n < L; n++){
nrg = WEBRTC_SPL_MUL_16_16(in_mic[i * L + n], in_mic[i * L + n]);
if (nrg > max_nrg){
max_nrg = nrg;
}
}
ptr[i] = max_nrg;


当有一块值大于-0.683dB(30290)就为envSum累加一次。如果没有累计超过25000,则算饱和。然后按照0.99的值衰减envSum。此处,如果每次包络都是0dB(32767)需要连续28块数据(相当于28ms)才饱和。如果是-0.683dB需要连续34ms才能饱和。若是小于-0.683dB永远也不能饱和了。

void WebRtcAgc_SaturationCtrl(Agc_t *stt, WebRtc_UWord8 *saturated, WebRtc_Word32 *env)
{
WebRtc_Word16 i, tmpW16;
/* Check if the signal is saturated */
for (i = 0; i < 10; i++){
tmpW16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(env[i], 20);
if (tmpW16 > 875){
stt->envSum += tmpW16;
}
}
if (stt->envSum > 25000){
*saturated = 1;
stt->envSum = 0;
}
/* stt->envSum *= 0.99; */
stt->envSum = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(stt->envSum,
(WebRtc_Word16)32440, 15);
}


三、WebRtcAgc_ZeroCtrl

该函数计算信号的大小,用msZero记数,用来控制语音活度(actgiveSpeech)和块低频能量最大值(Rxx16_LPw32Max)。这两个变量在ProcessAnalog中使用影响低频能量Rxx160_LPw32。

具体来说,如果10ms的包络平均值小于-73.31(7)那么就算10ms的全0,msZero增加10。

当静音时间大于500ms的时候,设置语音活度(actgiveSpeech)和块低频能量最大值(Rxx16_LPw32Max)为0(影响看前面描述)。

并且加大输入的麦克风等级inMicLevel(实际对应硬件音量)。

另外本函数会无条件对muteGuardMs操作。

for (i = 0; i < 10; i++){
tmp32 += env[i];
}
if (tmp32 < 500){
stt->msZero += 10;
} else{
stt->msZero = 0;
}
if (stt->muteGuardMs > 0){
stt->muteGuardMs -= 10;
}
if (stt->msZero > 500){
stt->msZero = 0;
/* Increase microphone level only if it's less than 50% */
midVal = WEBRTC_SPL_RSHIFT_W32(stt->maxAnalog + stt->minLevel + 1, 1);
if (*inMicLevel < midVal) {
/* *inMicLevel *= 1.1; */
tmp32 = WEBRTC_SPL_MUL(1126, *inMicLevel);
*inMicLevel = WEBRTC_SPL_RSHIFT_W32(tmp32, 10);
/* Reduces risk of a muted mic repeatedly triggering excessive levels due
* to zero signal detection. */
*inMicLevel = WEBRTC_SPL_MIN(*inMicLevel, stt->zeroCtrlMax);
stt->micVol = *inMicLevel;
}
stt->activeSpeech = 0;
stt->Rxx16_LPw32Max = 0;
/* The AGC has a tendency (due to problems with the VAD parameters), to
* vastly increase the volume after a muting event. This timer prevents
* upwards adaptation for a short period. */
stt->muteGuardMs = kMuteGuardTimeMs;
}


四、WebRtcAgc_ExpCurve

该函数是一个曲线函数,在ProcessAnalog中调用。用于将volNormFix转换成对应的分段曲线。用于模拟指数曲线,调节音量。该函数比较简单,不再累述。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息