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

📄 vad2.c

📁 AMR-NB 的编码实现,纯C, VC下建立工程即可用.
💻 C
📖 第 1 页 / 共 2 页
字号:
			hi1+= 3 ;	hi2+= 3 ;	hi3+= 3 ;	hi4+= 3 ;	
			
			Ltmp1 =  Pow2(hi1, lo1) ; Ltmp2 =  Pow2(hi2, lo2) ;Ltmp3 =  Pow2(hi3, lo3) ;Ltmp4 =  Pow2(hi4, lo4) ;
			Ltmp0 += Ltmp1+Ltmp2+Ltmp3+Ltmp4;
			
		}
		
		xt = fn10Log10(Ltmp0, 7);			
		/* Estimate long-term "peak" SNR */						
		if (xt > pst->tsnr )
		{			/* tsnr = 0.9*tsnr + 0.1*xt; */			
			tmp32 =  58982*pst->tsnr + 6554*xt ;
			pst->tsnr = (tmp32 > 0) & ((tmp32 + 0x00008000)<0)  ? MAX_32 : (tmp32 + 0x00008000) >> 16;
						
		}		/* else if (xt > 0.625*tsnr) */			else if ( xt  > (20480*pst->tsnr>>15) )
		{			/* tsnr = 0.998*tsnr + 0.002*xt; */			
			tmp32 =  65404*pst->tsnr + 132*xt ;
			pst->tsnr = (tmp32 > 0) & ((tmp32 + 0x00008000)<0)  ? MAX_32 : (tmp32 + 0x00008000) >> 16;
			
			
		}	}	/* Quantize the long-term SNR in 3 dB steps, limit to 0 <= tsnrq <= 19 */	tsnrq = pst->tsnr*10923 >> 23 ;
	tsnrq = tsnrq > 19 ? 19 : ( tsnrq < 0?  0: tsnrq);
	
	/* Calculate the negative SNR sensitivity bias */													
	if (xt < 0)	{		/* negSNRvar = 0.99*negSNRvar + 0.01*xt*xt; */
		/*   xt scaled as 7,8 => xt*xt scaled as 14,17, shift to 7,8 and round */
		tmp32 = xt*xt > (MAX_32 >>8) ? MAX_32 : xt*xt << 8;
		tmp = (tmp32 > 0)&((tmp32+0x00008000) < 0 )? MAX_32 : (tmp32+0x00008000)>>16;

		tmp32 = 64880*pst->negSNRvar  + 656*tmp;
		pst->negSNRvar  = (tmp32>0)&((tmp32+0x00008000) < 0) ? MAX_32 : (tmp32+0x00008000)>> 16;
		pst->negSNRvar = pst->negSNRvar>1024 ? 1024: pst->negSNRvar;

		tmp =  (  ((pst->negSNRvar -166)<<4 ) *24576 + 0x00004000)>>15;
		pst->negSNRbias = tmp < 0 ? 0 : tmp>>8;
		
	}	/* Determine VAD as a function of the voice metric sum and quantized SNR */	tmp =  vm_threshold_table[tsnrq] + st->negSNRbias;			
	
	if ( vm_sum > tmp)
	{		ivad = 1;										
		pst->burstcount ++ ;	
		pst->hangover = (pst->burstcount > burstcount_table[tsnrq]) ? hangover_table[tsnrq] :st->hangover ;
		
	}	else	{		pst->burstcount = 0;									
		pst->hangover -- ;	
		ivad = pst->hangover <= 0 ? 0 : 1;
		pst->hangover  = pst->hangover <= 0 ? 0 : pst->hangover;
		
	}
	/* Calculate log spectral deviation */	ch_enrg_dev = 0;										
													
	if ( st->Lframe_cnt == 1)
	{
		pst->ch_enrg_long_db[0]  = ch_enrg_db[0];	pst->ch_enrg_long_db[1] = ch_enrg_db[1];    pst->ch_enrg_long_db[2] = ch_enrg_db[2];	      pst->ch_enrg_long_db[3] = ch_enrg_db[3];	
		pst->ch_enrg_long_db[4]  = ch_enrg_db[4];	pst->ch_enrg_long_db[5] = ch_enrg_db[5];    pst->ch_enrg_long_db[6] = ch_enrg_db[6];	       pst->ch_enrg_long_db[7] = ch_enrg_db[7];
		pst->ch_enrg_long_db[8]  = ch_enrg_db[8];	pst->ch_enrg_long_db[9] = ch_enrg_db[9];    pst->ch_enrg_long_db[10] = ch_enrg_db[10];	pst->ch_enrg_long_db[11] = ch_enrg_db[11];
		pst->ch_enrg_long_db[12] = ch_enrg_db[12];	pst->ch_enrg_long_db[13] = ch_enrg_db[13]; pst->ch_enrg_long_db[14] = ch_enrg_db[14];	pst->ch_enrg_long_db[15] = ch_enrg_db[15];		
	}	else	{		for (i = LO_CHAN; i <= HI_CHAN; i+=4)
		{	
		        tmp = pst->ch_enrg_long_db[i] > ch_enrg_db[i] ? pst->ch_enrg_long_db[i]-ch_enrg_db[i] : ch_enrg_db[i] - pst->ch_enrg_long_db[i];					
			tmp1 = pst->ch_enrg_long_db[i+1] > ch_enrg_db[i+1] ? pst->ch_enrg_long_db[i+1]-ch_enrg_db[i+1] : ch_enrg_db[i+1] - pst->ch_enrg_long_db[i+1];	
			tmp2 = pst->ch_enrg_long_db[i+2] > ch_enrg_db[i+2] ? pst->ch_enrg_long_db[i+2]-ch_enrg_db[i+2] : ch_enrg_db[i+2] - pst->ch_enrg_long_db[i+2];
			tmp3 = pst->ch_enrg_long_db[i+3] > ch_enrg_db[i+3] ? pst->ch_enrg_long_db[i+3]-ch_enrg_db[i+3] : ch_enrg_db[i+3] - pst->ch_enrg_long_db[i+3];
			ch_enrg_dev += tmp+tmp1+tmp2+tmp3 ;
		}	}

	
	/*
	 * Calculate long term integration constant as a function of instantaneous SNR	 * (i.e., high SNR (tsnr dB) -> slower integration (alpha = HIGH_ALPHA),	 *         low SNR (0 dB) -> faster integration (alpha = LOW_ALPHA)	 */	/* alpha = HIGH_ALPHA - ALPHA_RANGE * (tsnr - xt) / tsnr, low <= alpha <= high */
	tmp =  	pst->tsnr - xt;						
	if (tmp <= 0 || pst->tsnr <= 0)
	{		alpha = HIGH_ALPHA;								
		one_m_alpha = 3277;						
	}	else if (tmp > pst->tsnr )
	{		alpha = LOW_ALPHA;								
		one_m_alpha = 9830;							
	}	else	{		tmp = div_s(tmp, pst->tsnr);		
		alpha =  HIGH_ALPHA -  ( ALPHA_RANGE* tmp >>15 );
		one_m_alpha = (32767-alpha);
	}
	/* Calc long term log spectral energy */	for (i = LO_CHAN; i <= HI_CHAN; i+=4 )
	{
		pst->ch_enrg_long_db[i] = (((one_m_alpha*ch_enrg_db[i]+alpha*pst->ch_enrg_long_db[i])<<1) + 0x00008000)>>16;
              pst->ch_enrg_long_db[i+1] = (((one_m_alpha*ch_enrg_db[i+1]+alpha*pst->ch_enrg_long_db[i+1])<<1) + 0x00008000)>>16;
              pst->ch_enrg_long_db[i+2] = (((one_m_alpha*ch_enrg_db[i+2]+alpha*pst->ch_enrg_long_db[i+2])<<1) + 0x00008000)>>16;
              pst->ch_enrg_long_db[i+3] = (((one_m_alpha*ch_enrg_db[i+3]+alpha*pst->ch_enrg_long_db[i+3])<<1) + 0x00008000)>>16;
	}
	/* Set or clear the noise update flags */	update_flag = FALSE;										
	pst->fupdate_flag = FALSE;									
													
	if (vm_sum <=  UPDATE_THLD )
	{	
		update_flag = pst->burstcount == 0 ? TRUE : update_flag;
		pst->update_cnt = pst->burstcount == 0 ? 0 : pst->update_cnt ;
	}
	else if (Ltce > noise_floor_chan[pst->shift_state])
	{												
		if (ch_enrg_dev <  DEV_THLD)
		{											
			if (p2a_flag == FALSE)			{										
				if (pst->LTP_flag == FALSE)
				{					pst->update_cnt ++;	
					update_flag = ( pst->update_cnt >= UPDATE_CNT_THLD) ? TRUE : update_flag ;					
				       pst->fupdate_flag = ( pst->update_cnt >= UPDATE_CNT_THLD) ? TRUE : pst->fupdate_flag;
					
				}			}		}
	}

	pst->hyster_cnt = ( pst->update_cnt ==  pst->last_update_cnt) ? pst->hyster_cnt +1 : 0;

	pst->last_update_cnt = pst->update_cnt;								

       pst->update_cnt = ( pst->hyster_cnt >  HYSTER_CNT_THLD) ?  0 : pst->update_cnt;

	/* Conditionally update the channel noise estimates */													
	if (update_flag == TRUE)	{
              tmp = (st->shift_state == 1) ? state_change_shift_r[0] : 0;
			  	
		/* Update noise energy estimate */		for (i = LO_CHAN; i <= HI_CHAN; i++)		{											
			/* integrate over time: en[i] = (1-alpha)*en[i] + alpha*e[n] */			/* (extract with shift compensation for state 1) */
			tmp32 = tmp > 0 ? st->Lch_enrg[i] >> tmp :(st->Lch_enrg[i] >= (MAX_32 >> -tmp) ? MAX_32: st->Lch_enrg[i] << - tmp ) ;			
		
			hi1 = (Word16)(tmp32>>16);
			lo1 = (tmp32 - (hi1<<16))>>1;
			
			Ltmp = hi1*6554 + ((lo1*3277>>15)<<1);
			hi1 = (Word16)(pst->Lch_noise[i]>>16);
			lo1 = (pst->Lch_noise[i] - (hi1 << 16 ))>>1;
			pst->Lch_noise[i] = Ltmp + hi1*58982 + ((lo1*ONE_MINUS_CNE_SM_FAC>>15)<< 1);	
			/* Limit low level noise */	
			pst->Lch_noise[i] =  ( pst->Lch_noise[i] < MIN_NOISE_ENRG_0) ? MIN_NOISE_ENRG_0 : pst->Lch_noise[i];	
                
		}	}	return(ivad);
}			

/***************************************************************************  Function:   vad2_init*  Purpose:    Allocates state memory and initializes state memory****************************************************************************/
int vad2_init (vadState2 **state){
    vadState2* pvadState2;    Word16	*ptr;	    if (state == (vadState2 **) NULL){        fprintf(stderr, "vad2_init: invalid parameter\n");        return -1;    }    *state = NULL;        /* allocate memory */    if ((pvadState2 = (vadState2 *) malloc(sizeof(vadState2))) == NULL)   {        fprintf(stderr, "vad2_init: can not malloc state structure\n");        return -1;    }       // vad2_reset(pvadState2);    ptr = (Word16 *)pvadState2;	    memset(ptr, 0,  sizeof(vadState2));
        *state = pvadState2;
    return 0;}

/***************************************************************************  Function:   vad2_exit*  Purpose:    The memory used for state memory is freed****************************************************************************/
void vad2_exit (vadState2 **state){    if (state == NULL || *state == NULL)        return;        /* deallocate memory */    free(*state);    *state = NULL;        return;}
#define			SIZE			128#define			SIZE_BY_TWO		64#define			NUM_STAGE		6
static Word16 phs_tbl[] ={	32767, 0, 32729, -1608, 32610, -3212, 32413, -4808,	32138, -6393, 31786, -7962, 31357, -9512, 30853, -11039,	30274, -12540, 29622, -14010, 28899, -15447, 28106, -16846,	27246, -18205, 26320, -19520, 25330, -20788, 24279, -22006,	23170, -23170, 22006, -24279, 20788, -25330, 19520, -26320,	18205, -27246, 16846, -28106, 15447, -28899, 14010, -29622,	12540, -30274, 11039, -30853, 9512, -31357, 7962, -31786,	6393, -32138, 4808, -32413, 3212, -32610, 1608, -32729,	0, -32768, -1608, -32729, -3212, -32610, -4808, -32413,	-6393, -32138, -7962, -31786, -9512, -31357, -11039, -30853,	-12540, -30274, -14010, -29622, -15447, -28899, -16846, -28106,	-18205, -27246, -19520, -26320, -20788, -25330, -22006, -24279,	-23170, -23170, -24279, -22006, -25330, -20788, -26320, -19520,	-27246, -18205, -28106, -16846, -28899, -15447, -29622, -14010,	-30274, -12540, -30853, -11039, -31357, -9512, -31786, -7962,	-32138, -6393, -32413, -4808, -32610, -3212, -32729, -1608};static Word16 ii_table[] ={SIZE / 2, SIZE / 4, SIZE / 8, SIZE / 16, SIZE / 32, SIZE / 64};/* FFT function for complex sequences *//* * The decimation-in-time complex FFT is implemented below. * The input complex numbers are presented as real part followed by * imaginary part for each sample.  The counters are therefore * incremented by two to access the complex valued samples. */void c_fft(Word16 * farray_ptr){
	Word16 i, j, k, ii, jj, kk, ji, kj, ii2;	Word32 ftmp, ftmp_real, ftmp_imag;	Word16 tmp, tmp1, tmp2;	/* Rearrange the input array in bit reversed order */	for (i = 0, j = 0; i < SIZE - 2; i = i + 2)	{										
		if ( j > i )
		{			ftmp = *(farray_ptr + i);					
			*(farray_ptr + i) = *(farray_ptr + j);				
			*(farray_ptr + j) = (Word16)ftmp;					
			ftmp = *(farray_ptr + i + 1);					
			*(farray_ptr + i + 1) = *(farray_ptr + j + 1);			
			*(farray_ptr + j + 1) = (Word16)ftmp;					
		}		k = SIZE_BY_TWO;							
											
		while (j>= k )
		{			j -= k;
			k >>= 1;
		}		j +=k;
	}	/* The FFT part */	for (i = 0; i < NUM_STAGE; i++)	{				       /* i is stage counter */
		jj = (2<< i);		/* FFT size */
		kk = (jj<<1);	       /* 2 * FFT size */
		ii = ii_table[i];	/* 2 * number of FFT's */			
		ii2 = (ii<< 1);
		ji = 0;			/* ji is phase table index */			
		for (j = 0; j < jj; j = j + 2)		{					/* j is sample counter */			for (k = j; k < SIZE; k = k + kk)			{				/* k is butterfly top */				kj = k+ jj;	/* kj is butterfly bottom */
				/* Butterfly computations */				ftmp_real = (*(farray_ptr + kj)*phs_tbl[ji] << 1);
				
				ftmp_real =  ftmp_real - ( *(farray_ptr + kj + 1)* phs_tbl[ji + 1] << 1);
				ftmp_imag = (*(farray_ptr + kj + 1) * phs_tbl[ji] << 1);
				
				ftmp_imag += *(farray_ptr + kj)* phs_tbl[ji + 1]<<1;
				tmp1 = (ftmp_real + 0x00008000)>>16;
				tmp2 = (ftmp_imag + 0x00008000)>>16;
				tmp = *(farray_ptr + k) - tmp1;
				*(farray_ptr + kj) = tmp>> 1 ;			
				tmp = *(farray_ptr + k + 1) -tmp2;
				*(farray_ptr + kj + 1) = tmp >> 1;			
				tmp = *(farray_ptr + k) +tmp1;
				
				*(farray_ptr + k) = tmp>> 1;			
				tmp = *(farray_ptr + k + 1)+ tmp2;
				*(farray_ptr + k + 1) = tmp>> 1;			
			}			ji += ii2 ;
		}	}


}								/* end of c_fft () */
void r_fft(Word16 * farray_ptr){
	Word16 ftmp1_real, ftmp1_imag, ftmp2_real, ftmp2_imag;
	Word32 Lftmp1_real, Lftmp1_imag;
	Word16 i, j;
	Word32 Ltmp1;

	/* Perform the complex FFT */
	c_fft(farray_ptr);

	/* First, handle the DC and foldover frequencies */
	ftmp1_real     = *farray_ptr;							
	ftmp2_real     = *(farray_ptr + 1);							
	*farray_ptr  = ftmp1_real + ftmp2_real;					
	*(farray_ptr + 1) = ftmp1_real - ftmp2_real;				

	/* Now, handle the remaining positive frequencies */
	for (i = 2, j = SIZE - i; i <= SIZE_BY_TWO; i = i + 2, j = SIZE - i)
	{
		ftmp1_real    = *(farray_ptr + i) + *(farray_ptr + j);
		ftmp1_imag   = *(farray_ptr + i + 1) - *(farray_ptr + j + 1);
		ftmp2_real    = *(farray_ptr + i + 1) + *(farray_ptr + j + 1);
		ftmp2_imag   = *(farray_ptr + j) -*(farray_ptr + i);

		Lftmp1_real  = (ftmp1_real<<16);
		Lftmp1_imag = (ftmp1_imag << 16);

		Ltmp1 =  Lftmp1_real + (ftmp2_real*phs_tbl[i] << 1);

		Ltmp1 = Ltmp1 - (ftmp2_imag*phs_tbl[i + 1] << 1 );

		*(farray_ptr + i) = ((Ltmp1>> 1) + 0x00008000)>>16;	

		Ltmp1 =    Lftmp1_imag + (ftmp2_imag*phs_tbl[i] << 1 );
		Ltmp1 +=  ftmp2_real*phs_tbl[i + 1] << 1;

		*(farray_ptr + i + 1) =  ((Ltmp1>>1) + 0x00008000)>>16;				

		Ltmp1 = Lftmp1_real +( ftmp2_real* phs_tbl[j] << 1);

		Ltmp1 +=  ftmp2_imag*phs_tbl[j + 1] << 1;

		*(farray_ptr + j) = ((Ltmp1>>1)+0x00008000) >> 16;		

		Ltmp1 = (Lftmp1_imag == MIN_32) ? MAX_32 : -Lftmp1_imag;		
		Ltmp1 -=  ftmp2_imag*phs_tbl[j]<<1;
		Ltmp1 +=  ftmp2_real*phs_tbl[j + 1] << 1;
		*(farray_ptr + j + 1) = ((Ltmp1>>1) + 0x00008000)>> 16;				

	}

}		

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -