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

📄 vad2.c

📁 arm音频编解码库
💻 C
📖 第 1 页 / 共 2 页
字号:
			Lpeak = st->Lch_enrg [i];							move32();		}	}	/* Set p2a_flag if peak (dB) > average channel energy (dB) + 10 dB */	/*   Lpeak > Ltce/num_channels * 10^(10/10)                        */	/*   Lpeak > (10/16)*Ltce                                          */	L_Extract (Ltce, &hi1, &lo1);	Ltmp = Mpy_32_16(hi1, lo1, 20480);													test();	if (L_sub(Lpeak, Ltmp) > 0)	{		p2a_flag = TRUE;									move16();	}	else	{		p2a_flag = FALSE;									move16();	}	/* Initialize channel noise estimate to either the channel energy or fixed level  */	/*   Scale the energy appropriately to yield state 0 (22,9) scaling for noise */													test();	if (L_sub(st->Lframe_cnt, 4) <= 0)	{												test();		if (p2a_flag == TRUE)		{			for (i = LO_CHAN; i <= HI_CHAN; i++)			{				st->Lch_noise[i] = INE_NOISE_0;						move32();			}		}		else		{			for (i = LO_CHAN; i <= HI_CHAN; i++)			{										test();				if (L_sub(st->Lch_enrg[i], ine_noise[st->shift_state]) < 0)				{					st->Lch_noise[i] = INE_NOISE_0;					move32();				}				else				{									test();					if (st->shift_state == 1)					{						st->Lch_noise[i] = L_shr(st->Lch_enrg[i], state_change_shift_r[0]);													move32();					}					else					{						st->Lch_noise[i] = st->Lch_enrg[i];			move32();					}				}			}		}	}	/* Compute the channel energy (in dB), the channel SNRs, and the sum of voice metrics */	vm_sum = 0;											move16();	for (i = LO_CHAN; i <= HI_CHAN; i++)	{		ch_enrg_db[i] = fn10Log10(st->Lch_enrg[i], fbits[st->shift_state]);			move16();		ch_noise_db = fn10Log10(st->Lch_noise[i], FRACTIONAL_BITS_0);		ch_snr[i] = sub(ch_enrg_db[i], ch_noise_db);						move16();		/* quantize channel SNR in 3/8 dB steps (scaled 7,8 => 15,0) */		/*   ch_snr = round((snr/(3/8))>>8)                          */		/*          = round(((0.6667*snr)<<2)>>8)                    */		/*          = round((0.6667*snr)>>6)                         */		ch_snrq = shr_r(mult(21845, ch_snr[i]), 6);		/* Accumulate the sum of voice metrics	*/						test();		if (sub(ch_snrq, 89) < 0)		{											test();			if (ch_snrq > 0)			{				j = ch_snrq;								move16();			}			else			{				j = 0;									move16();			}		}		else		{			j = 89;										move16();		}		vm_sum = add(vm_sum, vm_tbl[j]);	}	/* Initialize NOMINAL peak voice energy and average noise energy, calculate instantaneous SNR */ 												test(),test(),logic16();	if (L_sub(st->Lframe_cnt, 4) <= 0 || st->fupdate_flag == TRUE)	{		/* tce_db = (96 - 22 - 10*log10(64) (due to FFT)) scaled as 7,8 */		tce_db = 14320;										move16();		st->negSNRvar = 0;									move16();		st->negSNRbias = 0;									move16();		/* Compute the total noise estimate (Ltne) */		Ltne = 0;										move32();		for (i = LO_CHAN; i <= HI_CHAN; i++)		{			Ltne = L_add(Ltne, st->Lch_noise[i]);		}		/* Get total noise in dB */		tne_db = fn10Log10(Ltne, FRACTIONAL_BITS_0);		/* Initialise instantaneous and long-term peak signal-to-noise ratios */		xt = sub(tce_db, tne_db);		st->tsnr = xt;										move16();	}	else	{		/* Calculate instantaneous frame signal-to-noise ratio */		/* xt = 10*log10( sum(2.^(ch_snr*0.1*log2(10)))/length(ch_snr) ) */		Ltmp1 = 0;										move32();		for (i=LO_CHAN; i<=HI_CHAN; i++) {			/* Ltmp2 = ch_snr[i] * 0.1 * log2(10); (ch_snr scaled as 7,8) */			Ltmp2 = L_shr(L_mult(ch_snr[i], 10885), 8);			L_Extract(Ltmp2, &hi1, &lo1);			hi1 = add(hi1, 3);			/* 2^3 to compensate for negative SNR */			Ltmp1 = L_add(Ltmp1, Pow2(hi1, lo1));		}		xt = fn10Log10(Ltmp1, 4+3);			/* average by 16, inverse compensation 2^3 */		/* Estimate long-term "peak" SNR */							test(),test();		if (sub(xt, st->tsnr) > 0)		{			/* tsnr = 0.9*tsnr + 0.1*xt; */			st->tsnr = round(L_add(L_mult(29491, st->tsnr), L_mult(3277, xt)));		}		/* else if (xt > 0.625*tsnr) */			else if (sub(xt, mult(20480, st->tsnr)) > 0)		{			/* tsnr = 0.998*tsnr + 0.002*xt; */			st->tsnr = round(L_add(L_mult(32702, st->tsnr), L_mult(66, xt)));		}	}	/* Quantize the long-term SNR in 3 dB steps, limit to 0 <= tsnrq <= 19 */	tsnrq = shr(mult(st->tsnr, 10923), 8);	/* tsnrq = min(19, max(0, tsnrq)); */								test(),test();	if (sub(tsnrq, 19) > 0)	{		tsnrq = 19;										move16();	}	else if (tsnrq < 0)	{		tsnrq = 0;										move16();	}	/* Calculate the negative SNR sensitivity bias */													test();	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 */		tmp = round(L_shl(L_mult(xt, xt), 7));		st->negSNRvar = round(L_add(L_mult(32440, st->negSNRvar), L_mult(328, tmp)));		/* if (negSNRvar > 4.0) negSNRvar = 4.0;  */						test();		if (sub(st->negSNRvar, 1024) > 0)		{			st->negSNRvar = 1024;								move16();		}		/* negSNRbias = max(12.0*(negSNRvar - 0.65), 0.0); */		tmp = mult_r(shl(sub(st->negSNRvar, 166), 4), 24576);					test();		if (tmp < 0)		{			st->negSNRbias = 0;								move16();		}		else		{			st->negSNRbias = shr(tmp, 8);		}	}	/* Determine VAD as a function of the voice metric sum and quantized SNR */	tmp = add(vm_threshold_table[tsnrq], st->negSNRbias);						test();	if (sub(vm_sum, tmp) > 0)	{		ivad = 1;										move16();		st->burstcount = add(st->burstcount, 1);						test();		if (sub(st->burstcount, burstcount_table[tsnrq]) > 0)		{			st->hangover = hangover_table[tsnrq];						move16();		}	}	else	{		st->burstcount = 0;									move16();		st->hangover = sub(st->hangover, 1);							test();		if (st->hangover <= 0)		{			ivad = 0;									move16();			st->hangover = 0;								move16();		}		else		{			ivad = 1;									move16();		}	}	/* Calculate log spectral deviation */	ch_enrg_dev = 0;										move16();													test();	if (L_sub(st->Lframe_cnt, 1) == 0)	{		for (i = LO_CHAN; i <= HI_CHAN; i++)		{			st->ch_enrg_long_db[i] = ch_enrg_db[i];						move16();		}	}	else	{		for (i = LO_CHAN; i <= HI_CHAN; i++)		{			tmp = abs_s(sub(st->ch_enrg_long_db[i], ch_enrg_db[i]));			ch_enrg_dev = add(ch_enrg_dev, tmp);		}	}	/*	 * 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 = sub(st->tsnr, xt);						test(),logic16(),test(),test();	if (tmp <= 0 || st->tsnr <= 0)	{		alpha = HIGH_ALPHA;								move16();		one_m_alpha = 32768L-HIGH_ALPHA;						move16();	}	else if (sub(tmp, st->tsnr) > 0)	{		alpha = LOW_ALPHA;								move16();		one_m_alpha = 32768L-LOW_ALPHA;							move16();	}	else	{		tmp = div_s(tmp, st->tsnr);		alpha = sub(HIGH_ALPHA, mult(ALPHA_RANGE, tmp));		one_m_alpha = sub(32767, alpha);	}	/* Calc long term log spectral energy */	for (i = LO_CHAN; i <= HI_CHAN; i++)	{		Ltmp1 = L_mult(one_m_alpha, ch_enrg_db[i]);		Ltmp2 = L_mult(alpha, st->ch_enrg_long_db[i]);		st->ch_enrg_long_db[i] = round(L_add(Ltmp1, Ltmp2));	}	/* Set or clear the noise update flags */	update_flag = FALSE;										move16();	st->fupdate_flag = FALSE;									move16();													test(),test();	if (sub(vm_sum, UPDATE_THLD) <= 0)	{												test();		if (st->burstcount == 0)		{			update_flag = TRUE;								move16();			st->update_cnt = 0;								move16();		}	}	else if (L_sub(Ltce, noise_floor_chan[st->shift_state]) > 0)	{												test();		if (sub(ch_enrg_dev, DEV_THLD) < 0)		{											test();			if (p2a_flag == FALSE)			{										test();				if (st->LTP_flag == FALSE)				{					st->update_cnt = add(st->update_cnt, 1);			test();					if (sub(st->update_cnt, UPDATE_CNT_THLD) >= 0)					{						update_flag = TRUE;					move16();						st->fupdate_flag = TRUE;				move16();					}				}			}		}	}													test();	if (sub(st->update_cnt, st->last_update_cnt) == 0)	{		st->hyster_cnt = add(st->hyster_cnt, 1);	}	else	{		st->hyster_cnt = 0;									move16();	}	st->last_update_cnt = st->update_cnt;								move16();													test();	if (sub(st->hyster_cnt, HYSTER_CNT_THLD) > 0)	{		st->update_cnt = 0;									move16();	}	/* Conditionally update the channel noise estimates */													test();	if (update_flag == TRUE)	{		/* Check shift state */									test();		if (st->shift_state == 1)		{			/* get factor to shift ch_enrg[] from state 1 to 0 (noise always state 0) */			tmp = state_change_shift_r[0];							move16();		}		else		{			/* No shift if already state 0 */			tmp = 0;									move16();		}		/* Update noise energy estimate */		for (i = LO_CHAN; i <= HI_CHAN; i++)		{											test();			/* integrate over time: en[i] = (1-alpha)*en[i] + alpha*e[n] */			/* (extract with shift compensation for state 1) */			L_Extract (L_shr(st->Lch_enrg[i], tmp), &hi1, &lo1);			Ltmp = Mpy_32_16(hi1, lo1, CNE_SM_FAC);			L_Extract (st->Lch_noise[i], &hi1, &lo1);			st->Lch_noise[i] = L_add(Ltmp, Mpy_32_16(hi1, lo1, ONE_MINUS_CNE_SM_FAC));	move32();			/* Limit low level noise */							test();			if (L_sub(st->Lch_noise[i], MIN_NOISE_ENRG_0) < 0)			{				st->Lch_noise[i] = MIN_NOISE_ENRG_0;					move32();			}		}	}	return(ivad);}								/* end of vad2 () *//**** Other related functions *****//***************************************************************************  Function:   vad2_init*  Purpose:    Allocates state memory and initializes state memory****************************************************************************/int vad2_init (vadState2 **state){    vadState2* s;        if (state == (vadState2 **) NULL){        fprintf(stderr, "vad2_init: invalid parameter\n");        return -1;    }    *state = NULL;        /* allocate memory */    if ((s = (vadState2 *) malloc(sizeof(vadState2))) == NULL){        fprintf(stderr, "vad2_init: can not malloc state structure\n");        return -1;    }        vad2_reset(s);        *state = s;        return 0;}/*************************************************************************** * *   FUNCTION NAME: vad2_reset() * *   PURPOSE: *     The purpose of this function is to initialise the vad2() state *     variables. * *   INPUTS: * *     &st *                     pointer to data structure of vad2 state variables * *   OUTPUTS: * *     none * *   RETURN VALUE: * *     none * *   DESCRIPTION: * *                     Set all values in vad2 state to zero.  Since it is *                     known that all elements in the structure contain *                     16 and 32 bit fixed point elements, the initialisation *                     is performed by zeroing out the number of bytes in the *                     structure divided by two. * *************************************************************************/int vad2_reset (vadState2 * st){	Word16	i;	Word16	*ptr;	if (st == (vadState2 *) NULL){		fprintf(stderr, "vad2_reset: invalid parameter\n");		return -1;	}	ptr = (Word16 *)st;				move16();	for (i = 0; i < sizeof(vadState2)/2; i++)	{		*ptr++ = 0;				move16();	}	return 0;}						/* end of vad2_reset () *//***************************************************************************  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;}

⌨️ 快捷键说明

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