📄 vad1.c
字号:
l_temp1 = (abs(tmp_buf[132]) + abs(tmp_buf[148]) )<<1; l_temp2 = (Word16)(l_temp1 + st->sub_level[3] ); st->sub_level[3] = (Word16)(l_temp1 >= 0x7fff? 0x7fff : l_temp1); Lsum2 = abs(tmp_buf[4]) + abs(tmp_buf[20])+ abs(tmp_buf[36])+ abs(tmp_buf[52]); Lsum3 = abs(tmp_buf[68]) + abs(tmp_buf[84])+ abs(tmp_buf[100])+ abs(tmp_buf[116]); l_temp2 += (Lsum2+Lsum3)<<1; level[3] = (Word16)(l_temp2 >= 0x7fff ? 0x7fff :l_temp2); /* 500 - 750 Hz*/ l_temp1 = (abs(tmp_buf[140]) + abs(tmp_buf[156]) )<<1; l_temp2 = l_temp1 + st->sub_level[2]; st->sub_level[2] = (Word16)(l_temp1 >= 0x7fff ? 0x7fff : l_temp1); Lsum2 = abs(tmp_buf[12]) + abs(tmp_buf[28])+ abs(tmp_buf[44])+ abs(tmp_buf[60]); Lsum3 = abs(tmp_buf[76]) + abs(tmp_buf[92])+ abs(tmp_buf[108])+ abs(tmp_buf[124]); l_temp2 += (Lsum2+Lsum3)<<1; level[2] = (Word16)( l_temp2 >= 0x7fff ? 0x7fff :l_temp2 ); /* 250 - 500 Hz*/ l_temp1 = (abs(tmp_buf[136]) + abs(tmp_buf[152]) )<<1; l_temp2 = (Word16)(l_temp1 + st->sub_level[1]) ; st->sub_level[1] = (Word16)(l_temp1 >= 0x7fff? 0x7fff : l_temp1); Lsum2 = abs(tmp_buf[8]) + abs(tmp_buf[24]) + abs(tmp_buf[40]) + abs(tmp_buf[56]); Lsum3 = abs(tmp_buf[72]) + abs(tmp_buf[88])+ abs(tmp_buf[104])+ abs(tmp_buf[120]); l_temp2 += (Lsum2+Lsum3)<<1; level[1] = (Word16)( l_temp2 >= 0x7fff ? 0x7fff : l_temp2) ; /* 0 - 250 Hz*/ l_temp1 = (abs(tmp_buf[128]) + abs(tmp_buf[144]) )<<1; l_temp2 = l_temp1 + st->sub_level[0]; st->sub_level[0] = (Word16)(l_temp1 >= 0x7fff ? 0x7fff : l_temp1); Lsum2 = abs(tmp_buf[0]) + abs(tmp_buf[16])+ abs(tmp_buf[32])+ abs(tmp_buf[48]); Lsum3 = abs(tmp_buf[64]) + abs(tmp_buf[80])+ abs(tmp_buf[96])+ abs(tmp_buf[112]); l_temp2 += (Lsum2+Lsum3)<<1; level[0] = (Word16)( l_temp2 >= 0x7fff ? 0x7fff :l_temp2);
}/**************************************************************************** * * Function : update_cntrl * Purpose : Control update of the background noise estimate. * Inputs : pitch: flags for pitch detection * stat_count: stationary counter * tone: flags indicating presence of a tone * complex: flags for complex detection * vadreg: intermediate VAD flags * Output : stat_count: stationary counter * ***************************************************************************/static void update_cntrl(vadState1 *st, Word16 level[] )
{
Word16 i, stat_rat; Word16 num, denom; Word16 temp, exp; Word16 alpha; Word16* pLevel, *pStLevel; pLevel = level; pStLevel = st->ave_level; /* handle highband complex signal input separately */ /* if ther has been highband correlation for some time */ /* make sure that the VAD update speed is low for a while */ st->stat_count = (st->complex_warning != 0) && (st->stat_count < CAD_MIN_STAT_COUNT) ? CAD_MIN_STAT_COUNT :st->stat_count; /* NB stat_count is allowed to be decreased by one below again */ /* deadlock in speech is not possible unless the signal is very */ /* complex and need a high rate */ /* if fullband pitch or tone have been detected for a while, initialize stat_count */ if ( ((st->pitch & 0x6000)==0x6000) ||((st->tone & 0x7c00)== 0x7c00)) { st->stat_count = STAT_COUNT; } else { /* if 8 last vad-decisions have been "0", reinitialize stat_count */ if ((st->vadreg & 0x7f80) == 0) { st->stat_count = STAT_COUNT; } else { stat_rat = 0; for (i = 0; i < COMPLEN; i++) { num = pLevel[i]>pStLevel[i] ? pLevel[i] : pStLevel[i] ; denom = pLevel[i]>pStLevel[i] ? pStLevel[i] : pLevel[i] ; /* Limit nimimum value of num and denom to STAT_THR_LEVEL */ num = num <STAT_THR_LEVEL ? STAT_THR_LEVEL : num; denom = denom <STAT_THR_LEVEL ? STAT_THR_LEVEL : denom; exp = norm_s(denom); denom = (denom<<exp) ; /* stat_rat = num/denom * 64 */ temp = div_s((num>> 1), denom); stat_rat += ( temp >> (8 -exp)) ; } /* compare stat_rat with a threshold and update stat_count */ if (stat_rat > STAT_THR ) { st->stat_count = STAT_COUNT; } else { st->stat_count = ((st->vadreg & 0x4000) != 0) &&(st->stat_count != 0) ? st->stat_count -1: st->stat_count ; } } } /* Update average amplitude estimate for stationarity estimation */ alpha = st->stat_count == STAT_COUNT ? 32767 : ( (st->vadreg & 0x4000) == 0 ? ALPHA5 : ALPHA4 ); st->ave_level[0] += (alpha*(pLevel[0] -pStLevel[0]) >>15 ) ; st->ave_level[1] += (alpha*(pLevel[1] -pStLevel[1]) >>15 ) ; st->ave_level[2] += (alpha*(pLevel[2] -pStLevel[2]) >>15 ) ; st->ave_level[3] += (alpha*(pLevel[3] -pStLevel[3]) >>15 ) ; st->ave_level[4] += (alpha*(pLevel[4] -pStLevel[4]) >>15 ) ; st->ave_level[5] += (alpha*(pLevel[5] -pStLevel[5]) >>15 ) ; st->ave_level[6] += (alpha*(pLevel[6] -pStLevel[6]) >>15 ) ; st->ave_level[7] += (alpha*(pLevel[7] -pStLevel[7]) >>15 ) ; st->ave_level[8] += (alpha*(pLevel[8] -pStLevel[8]) >>15 ) ;
}/**************************************************************************** * * Function : hangover_addition * Purpose : Add hangover for complex signal or after speech bursts * Inputs : burst_count: counter for the length of speech bursts * hang_count: hangover counter * vadreg: intermediate VAD decision * Outputs : burst_count: counter for the length of speech bursts * hang_count: hangover counter * Return value : VAD_flag indicating final VAD decision * ***************************************************************************/static Word16 hangover_addition( vadState1 *st, Word16 noise_level, Word16 low_power )
{
Word16 hang_len, burst_len; /* Calculate burst_len and hang_len burst_len: number of consecutive intermediate vad flags with "1"-decision required for hangover addition hang_len: length of the hangover */
burst_len = (noise_level > HANG_NOISE_THR )? BURST_LEN_HIGH_NOISE : BURST_LEN_LOW_NOISE;
hang_len = (noise_level > HANG_NOISE_THR )? HANG_LEN_HIGH_NOISE : HANG_LEN_LOW_NOISE;
/* if the input power (pow_sum) is lower than a threshold, clear counters and set VAD_flag to "0" "fast exit" */ if (low_power != 0) { st->burst_count = 0; st->hang_count = 0; st->complex_hang_count = 0; st->complex_hang_timer = 0; return 0; } st->complex_hang_count = (st->complex_hang_timer >CVAD_HANG_LIMIT) &&( st->complex_hang_count < CVAD_HANG_LENGTH) ? CVAD_HANG_LENGTH : st->complex_hang_count ; /* long time very complex signal override VAD output function */ if (st->complex_hang_count != 0) { st->burst_count = BURST_LEN_HIGH_NOISE; st->complex_hang_count --; return 1; } else { /* let hp_corr work in from a noise_period indicated by the VAD */ if (((st->vadreg & 0x3ff0) == 0) && (st->corr_hp_fast > CVAD_THRESH_IN_NOISE) ) { return 1; } } /* update the counters (hang_count, burst_count) */ if ((st->vadreg & 0x4000) != 0) { st->burst_count ++; st->hang_count = st->burst_count >= burst_len? hang_len : st->hang_count; return 1; } else { st->burst_count = 0; if (st->hang_count > 0) { st->hang_count --; return 1; } }
return 0;}/**************************************************************************** * * Function : noise_estimate_update * Purpose : Update of background noise estimate * Inputs :
bckr_est: background noise estimate
* pitch: flags for pitch detection
* stat_count: stationary counter
* Outputs : bckr_est: background noise estimate * ***************************************************************************/static void noise_estimate_update(vadState1 *st, Word16 level[] )
{
Word16 alpha_up, alpha_down, bckr_add,temp0,temp1,temp2,temp3,temp4,temp5,temp6,temp7,temp8 ; Word16 *pLevel, *pOldLevel,*pBckEst; pLevel = level; pOldLevel = st->old_level; pBckEst = st->bckr_est; /* Control update of bckr_est[] */ update_cntrl(st, level); /* Choose update speed */ bckr_add = 2; if (((0x7800 & st->vadreg) == 0) && ((st->pitch & 0x7800) == 0) && (st->complex_hang_count == 0)) { alpha_up = ALPHA_UP1; alpha_down = ALPHA_DOWN1; } else { if ((st->stat_count == 0) && (st->complex_hang_count == 0)) { alpha_up = ALPHA_UP2; alpha_down = ALPHA_DOWN2; } else { alpha_up = 0; alpha_down = ALPHA3; bckr_add = 0; } } /* Update noise estimate (bckr_est) */ // for (i = 0; i < COMPLEN; i++) temp0 = pOldLevel[0] - pBckEst[0]; temp1 = pOldLevel[1] - pBckEst[1]; temp2 = pOldLevel[2] - pBckEst[2]; temp3 = pOldLevel[3] - pBckEst[3]; temp4 = pOldLevel[4] - pBckEst[4]; temp5 = pOldLevel[5] - pBckEst[5]; temp6 = pOldLevel[6] - pBckEst[6]; temp7 = pOldLevel[7] - pBckEst[7]; temp8 = pOldLevel[8] - pBckEst[8]; pBckEst[0] = (Word16)(temp0 < 0 ? -2 + pBckEst[0]+ ((alpha_down*temp0 +0x00004000L )>>15 ) : bckr_add + pBckEst[0]+( (alpha_up* temp0 + 0x00004000L ) >>15)); pBckEst[0] = temp0 < 0 ? ( pBckEst[0] < NOISE_MIN ? NOISE_MIN : pBckEst[0] ) :( pBckEst[0] > NOISE_MAX ? NOISE_MAX :pBckEst[0] ); pBckEst[1] = (Word16)(temp1 < 0 ? -2 + pBckEst[1]+ ((alpha_down*temp1 +0x00004000L )>>15 ) : bckr_add + pBckEst[1]+( (alpha_up* temp1 + 0x00004000L ) >>15)); pBckEst[1] = temp1 < 0 ? ( pBckEst[1] < NOISE_MIN ? NOISE_MIN : pBckEst[1] ) :( pBckEst[1] > NOISE_MAX ? NOISE_MAX :pBckEst[1] ); pBckEst[2] = (Word16)(temp2 < 0 ? -2 + pBckEst[2]+ ((alpha_down*temp2 +0x00004000L )>>15 ) : bckr_add + pBckEst[2]+( (alpha_up* temp2 + 0x00004000L ) >>15)); pBckEst[2] = temp2 < 0 ? ( pBckEst[2] < NOISE_MIN ? NOISE_MIN : pBckEst[2] ) :( pBckEst[2] > NOISE_MAX ? NOISE_MAX :pBckEst[2] ); pBckEst[3] = (Word16)(temp3 < 0 ? -2 + pBckEst[3]+ ((alpha_down*temp3 +0x00004000L )>>15 ) : bckr_add + pBckEst[3]+( (alpha_up* temp3 + 0x00004000L ) >>15)); pBckEst[3] = temp3 < 0 ? ( pBckEst[3] < NOISE_MIN ? NOISE_MIN : pBckEst[3] ) :( pBckEst[3] > NOISE_MAX ? NOISE_MAX :pBckEst[3] ); pBckEst[4] = (Word16)(temp4 < 0 ? -2 + pBckEst[4]+ ((alpha_down*temp4 +0x00004000L )>>15 ) : bckr_add + pBckEst[4]+( (alpha_up* temp4 + 0x00004000L ) >>15)); pBckEst[4] = temp4 < 0 ? ( pBckEst[4] < NOISE_MIN ? NOISE_MIN : pBckEst[4] ) :( pBckEst[4] > NOISE_MAX ? NOISE_MAX :pBckEst[4] ); pBckEst[5] = (Word16)(temp5 < 0 ? -2 + pBckEst[5]+ ((alpha_down*temp5 +0x00004000L )>>15 ) : bckr_add + pBckEst[5]+( (alpha_up* temp5 + 0x00004000L ) >>15)); pBckEst[5] = temp5 < 0 ? ( pBckEst[5] < NOISE_MIN ? NOISE_MIN : pBckEst[5] ) :( pBckEst[5] > NOISE_MAX ? NOISE_MAX :pBckEst[5] ); pBckEst[6] = (Word16)(temp6 < 0 ? -2 + pBckEst[6]+ ((alpha_down*temp6 +0x00004000L )>>15 ) : bckr_add + pBckEst[6]+( (alpha_up* temp6 + 0x00004000L ) >>15)); pBckEst[6] = temp6 < 0 ? ( pBckEst[6] < NOISE_MIN ? NOISE_MIN : pBckEst[6] ) :( pBckEst[6] > NOISE_MAX ? NOISE_MAX :pBckEst[6] ); pBckEst[7] = (Word16)(temp7 < 0 ? -2 + pBckEst[7]+ ((alpha_down*temp7 +0x00004000L )>>15 ) : bckr_add + pBckEst[7]+( (alpha_up* temp7 + 0x00004000L ) >>15)); pBckEst[7] = temp7 < 0 ? ( pBckEst[7] < NOISE_MIN ? NOISE_MIN : pBckEst[7] ) :( pBckEst[7] > NOISE_MAX ? NOISE_MAX :pBckEst[7] ); pBckEst[8] = (Word16)(temp8 < 0 ? -2 + pBckEst[8]+ ((alpha_down*temp8 +0x00004000L )>>15 ) : bckr_add + pBckEst[8]+( (alpha_up* temp8+ 0x00004000L ) >>15)); pBckEst[8] = temp8 < 0 ? ( pBckEst[8] < NOISE_MIN ? NOISE_MIN : pBckEst[8] ) :( pBckEst[8] > NOISE_MAX ? NOISE_MAX :pBckEst[8] ); /* Update signal levels of the previous frame (old_level) */ pOldLevel[0] = pLevel[0] ; pOldLevel[1] = pLevel[1] ; pOldLevel[2] = pLevel[2] ; pOldLevel[3] = pLevel[3] ; pOldLevel[4] = pLevel[4] ; pOldLevel[5] = pLevel[5] ; pOldLevel[6] = pLevel[6] ; pOldLevel[7] = pLevel[7] ; pOldLevel[8] = pLevel[8] ; // memcpy(pOldLevel, pLevel, COMPLEN*sizeof(Word16) );
}/****************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -