📄 vad2.c
字号:
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 + -