📄 vad1.c
字号:
Calculate squared sum of the input levels (level) divided by the background noise components (bckr_est). */ L_temp = 0; move32(); for (i = 0; i < COMPLEN; i++) { Word16 exp; exp = norm_s(st->bckr_est[i]); temp = shl(st->bckr_est[i], exp); temp = div_s(shr(level[i], 1), temp); temp = shl(temp, sub(exp, UNIRSHFT-1)); L_temp = L_mac(L_temp, temp, temp); } snr_sum = extract_h(L_shl(L_temp, 6)); snr_sum = mult(snr_sum, INV_COMPLEN); /* Calculate average level of estimated background noise */ L_temp = 0; move32(); for (i = 0; i < COMPLEN; i++) { L_temp = L_add(L_temp, st->bckr_est[i]); } noise_level = extract_h(L_shl(L_temp, 13)); /* Calculate VAD threshold */ vad_thr = add(mult(VAD_SLOPE, sub(noise_level, VAD_P1)), VAD_THR_HIGH); test (); if (sub(vad_thr, VAD_THR_LOW) < 0) { vad_thr = VAD_THR_LOW; move16 (); } /* Shift VAD decision register */ st->vadreg = shr(st->vadreg, 1); move16 (); /* Make intermediate VAD decision */ test (); if (sub(snr_sum, vad_thr) > 0) { st->vadreg = st->vadreg | 0x4000; logic16 (); move16 (); } /* primary vad decsion made */ /* check if the input power (pow_sum) is lower than a threshold" */ test (); if (L_sub(pow_sum, VAD_POW_LOW) < 0) { low_power_flag = 1; move16 (); } else { low_power_flag = 0; move16 (); } /* update complex signal estimate st->corr_hp_fast and hangover reset timer using */ /* low_power_flag and corr_hp_fast and various adaptation speeds */ complex_estimate_adapt(st, low_power_flag); /* check multiple thresholds of the st->corr_hp_fast value */ st->complex_warning = complex_vad(st, low_power_flag); move16(); /* Update speech subband vad background noise estimates */ noise_estimate_update(st, level); /* Add speech and complex hangover and return speech VAD_flag */ /* long term complex hangover may be added */ st->speech_vad_decision = hangover_addition(st, noise_level, low_power_flag); move16 (); return (st->speech_vad_decision);}/******************************************************************************* PUBLIC PROGRAM CODE******************************************************************************//*************************************************************************** Function: vad1_init* Purpose: Allocates state memory and initializes state memory****************************************************************************/int vad1_init (vadState1 **state){ vadState1* s; if (state == (vadState1 **) NULL){ fprintf(stderr, "vad_init: invalid parameter\n"); return -1; } *state = NULL; /* allocate memory */ if ((s = (vadState1 *) malloc(sizeof(vadState1))) == NULL){ fprintf(stderr, "vad_init: can not malloc state structure\n"); return -1; } vad1_reset(s); *state = s; return 0;} /*************************************************************************** Function: vad1_reset* Purpose: Initializes state memory to zero****************************************************************************/int vad1_reset (vadState1 *state){ Word16 i, j; if (state == (vadState1 *) NULL){ fprintf(stderr, "vad_reset: invalid parameter\n"); return -1; } /* Initialize pitch detection variables */ state->oldlag_count = 0; state->oldlag = 0; state->pitch = 0; state->tone = 0; state->complex_high = 0; state->complex_low = 0; state->complex_hang_timer = 0; state->vadreg = 0; state->stat_count = 0; state->burst_count = 0; state->hang_count = 0; state->complex_hang_count = 0; /* initialize memory used by the filter bank */ for (i = 0; i < 3; i++) { for (j = 0; j < 2; j++) { state->a_data5[i][j] = 0; } } for (i = 0; i < 5; i++) { state->a_data3[i] = 0; } /* initialize the rest of the memory */ for (i = 0; i < COMPLEN; i++) { state->bckr_est[i] = NOISE_INIT; state->old_level[i] = NOISE_INIT; state->ave_level[i] = NOISE_INIT; state->sub_level[i] = 0; } state->best_corr_hp = CVAD_LOWPOW_RESET; state->speech_vad_decision = 0; state->complex_warning = 0; state->sp_burst_count = 0; state->corr_hp_fast = CVAD_LOWPOW_RESET; return 0;}/*************************************************************************** Function: vad1_exit* Purpose: The memory used for state memory is freed****************************************************************************/void vad1_exit (vadState1 **state){ if (state == NULL || *state == NULL) return; /* deallocate memory */ free(*state); *state = NULL; return;}/**************************************************************************** * * Function : vad_complex_detection_update * Purpose : update vad->bestCorr_hp complex signal feature state * ***************************************************************************/void vad_complex_detection_update (vadState1 *st, /* i/o : State struct */ Word16 best_corr_hp /* i : best Corr */ ){ st->best_corr_hp = best_corr_hp; move16();}/**************************************************************************** * * Function : vad_tone_detection * Purpose : Set tone flag if pitch gain is high. This is used to detect * signaling tones and other signals with high pitch gain. * Inputs : tone: flags indicating presence of a tone * Outputs : tone: flags indicating presence of a tone * ***************************************************************************/void vad_tone_detection (vadState1 *st, /* i/o : State struct */ Word32 t0, /* i : autocorrelation maxima */ Word32 t1 /* i : energy */ ){ Word16 temp; /* if (t0 > TONE_THR * t1) set tone flag */ temp = round(t1); test (); test (); if ((temp > 0) && (L_msu(t0, temp, TONE_THR) > 0)) { st->tone = st->tone | 0x4000; logic16 (); move16 (); }}/**************************************************************************** * * Function : vad_tone_detection_update * Purpose : Update the tone flag register. Tone flags are shifted right * by one bit. This function should be called from the speech * encoder before call to Vad_tone_detection() function. * ***************************************************************************/void vad_tone_detection_update ( vadState1 *st, /* i/o : State struct */ Word16 one_lag_per_frame /* i : 1 if one open-loop lag is calculated per each frame, otherwise 0 */ ){ /* Shift tone flags right by one bit */ st->tone = shr(st->tone, 1); move16 (); /* If open-loop lag is calculated only once in each frame, do extra update and assume that the other tone flag of the frame is one. */ if (one_lag_per_frame != 0) { st->tone = shr(st->tone, 1); st->tone = st->tone | 0x2000; logic16 (); move16 (); }}/**************************************************************************** * * Function : vad_pitch_detection * Purpose : Test whether signal contains pitch or other periodic * component. * Return value : Boolean voiced / unvoiced decision in state variable * ***************************************************************************/void vad_pitch_detection (vadState1 *st, /* i/o : State struct */ Word16 T_op[] /* i : speech encoder open loop lags */ ){ Word16 lagcount, i; lagcount = 0; move16 (); for (i = 0; i < 2; i++) { test (); if (sub (abs_s (sub (st->oldlag, T_op[i])), LTHRESH) < 0) { lagcount = add (lagcount, 1); } /* Save the current LTP lag */ st->oldlag = T_op[i]; move16 (); } /* Make pitch decision. Save flag of the pitch detection to the variable pitch. */ st->pitch = shr(st->pitch, 1); move16(); test (); if (sub ( add (st->oldlag_count, lagcount), NTHRESH) >= 0) { st->pitch = st->pitch | 0x4000; logic16(); move16(); } /* Update oldlagcount */ st->oldlag_count = lagcount; move16 ();}/**************************************************************************** * * Function : vad * Purpose : Main program for Voice Activity Detection (VAD) for AMR * Return value : VAD Decision, 1 = speech, 0 = noise * ***************************************************************************/Word16 vad1(vadState1 *st, /* i/o : State struct */ Word16 in_buf[] /* i : samples of the input frame */ ){ Word16 level[COMPLEN]; Word32 pow_sum; Word16 i; /* Calculate power of the input frame. */ pow_sum = 0L; move32 (); for (i = 0; i < FRAME_LEN; i++) { pow_sum = L_mac(pow_sum, in_buf[i-LOOKAHEAD], in_buf[i-LOOKAHEAD]); } /* If input power is very low, clear pitch flag of the current frame */ test (); if (L_sub(pow_sum, POW_PITCH_THR) < 0) { st->pitch = st->pitch & 0x3fff; logic16 (); move16 (); } /* If input power is very low, clear complex flag of the "current" frame */ test (); if (L_sub(pow_sum, POW_COMPLEX_THR) < 0) { st->complex_low = st->complex_low & 0x3fff; logic16 (); move16 (); } /* Run the filter bank which calculates signal levels at each band */ filter_bank(st, in_buf, level); return (vad_decision(st, level, pow_sum));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -