⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vad1.c

📁 AMR-NB 的编码实现,纯C, VC下建立工程即可用.
💻 C
📖 第 1 页 / 共 3 页
字号:
	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 + -