1e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/* 2e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Copyright 2003-2010, VisualOn, Inc. 3e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** 4e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Licensed under the Apache License, Version 2.0 (the "License"); 5e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** you may not use this file except in compliance with the License. 6e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** You may obtain a copy of the License at 7e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** 8e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** http://www.apache.org/licenses/LICENSE-2.0 9e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** 10e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Unless required by applicable law or agreed to in writing, software 11e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** distributed under the License is distributed on an "AS IS" BASIS, 12e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** See the License for the specific language governing permissions and 14e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** limitations under the License. 15e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard */ 16e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 17e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/*********************************************************************** 18e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* File: wb_vad.c * 19e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* * 20e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Description: Voice Activity Detection * 21e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* * 22e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard************************************************************************/ 23e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 24e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include <stdlib.h> 25e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include <stdio.h> 26e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "cnst.h" 27e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "wb_vad.h" 28e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "typedef.h" 29e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "basic_op.h" 30e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "math_op.h" 31e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "wb_vad_c.h" 32e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "mem_align.h" 33e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 34e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/****************************************************************************** 35e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Calculate Log2 and scale the signal: 36e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 37e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* ilog2(Word32 in) = -1024*log10(in * 2^-31)/log10(2), where in = [1, 2^31-1] 38e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 39e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* input output 40e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 32768 16384 41e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 1 31744 42e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 43e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* When input is in the range of [1,2^16], max error is 0.0380%. 44e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*********************************************************************************/ 45e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 46e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic Word16 ilog2( /* return: output value of the log2 */ 47e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 mant /* i: value to be converted */ 48e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ) 49e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 50e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 ex, ex2, res; 51e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 i, l_temp; 52e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 53e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (mant <= 0) 54e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 55b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard mant = 1; 56e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 57e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ex = norm_s(mant); 58e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard mant = mant << ex; 59e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 60e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < 3; i++) 61e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard mant = vo_mult(mant, mant); 62e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard l_temp = vo_L_mult(mant, mant); 63e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 64e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ex2 = norm_l(l_temp); 65e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard mant = extract_h(l_temp << ex2); 66e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 67e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard res = (ex + 16) << 10; 68e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard res = add1(res, (ex2 << 6)); 69e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard res = vo_sub(add1(res, 127), (mant >> 8)); 70e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return (res); 71e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 72e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 73e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/****************************************************************************** 74e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 75e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Function : filter5 76e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Purpose : Fifth-order half-band lowpass/highpass filter pair with 77e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* decimation. 78e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 79e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*******************************************************************************/ 80e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 81e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic void filter5( 82e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 * in0, /* i/o : input values; output low-pass part */ 83e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 * in1, /* i/o : input values; output high-pass part */ 84e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 data[] /* i/o : filter memory */ 85e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ) 86e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 87e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 temp0, temp1, temp2; 88e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 89e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard temp0 = vo_sub(*in0, vo_mult(COEFF5_1, data[0])); 90e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard temp1 = add1(data[0], vo_mult(COEFF5_1, temp0)); 91b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard data[0] = temp0; 92e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 93e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard temp0 = vo_sub(*in1, vo_mult(COEFF5_2, data[1])); 94e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard temp2 = add1(data[1], vo_mult(COEFF5_2, temp0)); 95b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard data[1] = temp0; 96e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 97b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard *in0 = extract_h((vo_L_add(temp1, temp2) << 15)); 98b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard *in1 = extract_h((vo_L_sub(temp1, temp2) << 15)); 99e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 100e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 101e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/****************************************************************************** 102e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 103e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Function : filter3 104e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Purpose : Third-order half-band lowpass/highpass filter pair with 105e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* decimation. 106e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 107e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*******************************************************************************/ 108e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 109e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic void filter3( 110e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 * in0, /* i/o : input values; output low-pass part */ 111e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 * in1, /* i/o : input values; output high-pass part */ 112e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 * data /* i/o : filter memory */ 113e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ) 114e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 115e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 temp1, temp2; 116e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 117e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard temp1 = vo_sub(*in1, vo_mult(COEFF3, *data)); 118e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard temp2 = add1(*data, vo_mult(COEFF3, temp1)); 119b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard *data = temp1; 120e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 121b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard *in1 = extract_h((vo_L_sub(*in0, temp2) << 15)); 122b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard *in0 = extract_h((vo_L_add(*in0, temp2) << 15)); 123e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 124e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 125e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/****************************************************************************** 126e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 127e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Function : level_calculation 128e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Purpose : Calculate signal level in a sub-band. Level is calculated 129e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* by summing absolute values of the input data. 130e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 131e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Signal level calculated from of the end of the frame 132e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* (data[count1 - count2]) is stored to (*sub_level) 133e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* and added to the level of the next frame. 134e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 135e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard******************************************************************************/ 136e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 137e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic Word16 level_calculation( /* return: signal level */ 138e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 data[], /* i : signal buffer */ 139e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 * sub_level, /* i : level calculated at the end of the previous frame*/ 140e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* o : level of signal calculated from the last */ 141e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* (count2 - count1) samples */ 142e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 count1, /* i : number of samples to be counted */ 143e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 count2, /* i : number of samples to be counted */ 144e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 ind_m, /* i : step size for the index of the data buffer */ 145e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 ind_a, /* i : starting index of the data buffer */ 146e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 scale /* i : scaling for the level calculation */ 147e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ) 148e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 149e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 i, l_temp1, l_temp2; 150e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 level; 151e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 152b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard l_temp1 = 0L; 153e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = count1; i < count2; i++) 154e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 155e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard l_temp1 += (abs_s(data[ind_m * i + ind_a])<<1); 156e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 157e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 158e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard l_temp2 = vo_L_add(l_temp1, L_shl(*sub_level, 16 - scale)); 159b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard *sub_level = extract_h(L_shl(l_temp1, scale)); 160e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 161e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < count1; i++) 162e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 163e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard l_temp2 += (abs_s(data[ind_m * i + ind_a])<<1); 164e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 165e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard level = extract_h(L_shl2(l_temp2, scale)); 166e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 167e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return level; 168e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 169e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 170e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/****************************************************************************** 171e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 172e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Function : filter_bank 173e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Purpose : Divide input signal into bands and calculate level of 174e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* the signal in each band 175e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 176e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*******************************************************************************/ 177e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 178e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic void filter_bank( 179e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard VadVars * st, /* i/o : State struct */ 180e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 in[], /* i : input frame */ 181e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 level[] /* o : signal levels at each band */ 182e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ) 183e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 184e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 i; 185e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 tmp_buf[FRAME_LEN]; 186e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 187e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* shift input 1 bit down for safe scaling */ 188e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < FRAME_LEN; i++) 189e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 190b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tmp_buf[i] = in[i] >> 1; 191e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 192e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 193e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* run the filter bank */ 194e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < 128; i++) 195e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 196e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard filter5(&tmp_buf[2 * i], &tmp_buf[2 * i + 1], st->a_data5[0]); 197e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 198e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < 64; i++) 199e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 200e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard filter5(&tmp_buf[4 * i], &tmp_buf[4 * i + 2], st->a_data5[1]); 201e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard filter5(&tmp_buf[4 * i + 1], &tmp_buf[4 * i + 3], st->a_data5[2]); 202e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 203e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < 32; i++) 204e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 205e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard filter5(&tmp_buf[8 * i], &tmp_buf[8 * i + 4], st->a_data5[3]); 206e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard filter5(&tmp_buf[8 * i + 2], &tmp_buf[8 * i + 6], st->a_data5[4]); 207e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard filter3(&tmp_buf[8 * i + 3], &tmp_buf[8 * i + 7], &st->a_data3[0]); 208e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 209e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < 16; i++) 210e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 211e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard filter3(&tmp_buf[16 * i + 0], &tmp_buf[16 * i + 8], &st->a_data3[1]); 212e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard filter3(&tmp_buf[16 * i + 4], &tmp_buf[16 * i + 12], &st->a_data3[2]); 213e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard filter3(&tmp_buf[16 * i + 6], &tmp_buf[16 * i + 14], &st->a_data3[3]); 214e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 215e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 216e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < 8; i++) 217e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 218e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard filter3(&tmp_buf[32 * i + 0], &tmp_buf[32 * i + 16], &st->a_data3[4]); 219e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard filter3(&tmp_buf[32 * i + 8], &tmp_buf[32 * i + 24], &st->a_data3[5]); 220e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 221e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 222e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* calculate levels in each frequency band */ 223e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 224e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* 4800 - 6400 Hz */ 225b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard level[11] = level_calculation(tmp_buf, &st->sub_level[11], 16, 64, 4, 1, 14); 226e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* 4000 - 4800 Hz */ 227b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard level[10] = level_calculation(tmp_buf, &st->sub_level[10], 8, 32, 8, 7, 15); 228e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* 3200 - 4000 Hz */ 229b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard level[9] = level_calculation(tmp_buf, &st->sub_level[9],8, 32, 8, 3, 15); 230e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* 2400 - 3200 Hz */ 231b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard level[8] = level_calculation(tmp_buf, &st->sub_level[8],8, 32, 8, 2, 15); 232e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* 2000 - 2400 Hz */ 233b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard level[7] = level_calculation(tmp_buf, &st->sub_level[7],4, 16, 16, 14, 16); 234e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* 1600 - 2000 Hz */ 235b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard level[6] = level_calculation(tmp_buf, &st->sub_level[6],4, 16, 16, 6, 16); 236e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* 1200 - 1600 Hz */ 237b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard level[5] = level_calculation(tmp_buf, &st->sub_level[5],4, 16, 16, 4, 16); 238e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* 800 - 1200 Hz */ 239b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard level[4] = level_calculation(tmp_buf, &st->sub_level[4],4, 16, 16, 12, 16); 240e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* 600 - 800 Hz */ 241b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard level[3] = level_calculation(tmp_buf, &st->sub_level[3],2, 8, 32, 8, 17); 242e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* 400 - 600 Hz */ 243b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard level[2] = level_calculation(tmp_buf, &st->sub_level[2],2, 8, 32, 24, 17); 244e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* 200 - 400 Hz */ 245b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard level[1] = level_calculation(tmp_buf, &st->sub_level[1],2, 8, 32, 16, 17); 246e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* 0 - 200 Hz */ 247b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard level[0] = level_calculation(tmp_buf, &st->sub_level[0],2, 8, 32, 0, 17); 248e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 249e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 250e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/****************************************************************************** 251e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 252e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Function : update_cntrl 253e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Purpose : Control update of the background noise estimate. 254e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 255e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*******************************************************************************/ 256e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 257e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic void update_cntrl( 258e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard VadVars * st, /* i/o : State structure */ 259e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 level[] /* i : sub-band levels of the input frame */ 260e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ) 261e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 262e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 i; 263e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 num, temp, stat_rat, exp, denom; 264e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 alpha; 265e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 266e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* if a tone has been detected for a while, initialize stat_count */ 267e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (sub((Word16) (st->tone_flag & 0x7c00), 0x7c00) == 0) 268e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 269b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->stat_count = STAT_COUNT; 270e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } else 271e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 272e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* if 8 last vad-decisions have been "0", reinitialize stat_count */ 273e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if ((st->vadreg & 0x7f80) == 0) 274e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 275b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->stat_count = STAT_COUNT; 276e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } else 277e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 278b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard stat_rat = 0; 279e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < COMPLEN; i++) 280e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 281e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(level[i] > st->ave_level[i]) 282e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 283b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard num = level[i]; 284b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard denom = st->ave_level[i]; 285e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } else 286e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 287e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard num = st->ave_level[i]; 288b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard denom = level[i]; 289e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 290e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Limit nimimum value of num and denom to STAT_THR_LEVEL */ 291e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(num < STAT_THR_LEVEL) 292e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 293b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard num = STAT_THR_LEVEL; 294e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 295e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(denom < STAT_THR_LEVEL) 296e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 297e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard denom = STAT_THR_LEVEL; 298e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 299e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard exp = norm_s(denom); 300e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard denom = denom << exp; 301e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 302e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* stat_rat = num/denom * 64 */ 303e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard temp = div_s(num >> 1, denom); 304e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard stat_rat = add1(stat_rat, shr(temp, (8 - exp))); 305e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 306e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 307e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* compare stat_rat with a threshold and update stat_count */ 308e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(stat_rat > STAT_THR) 309e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 310b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->stat_count = STAT_COUNT; 311e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } else 312e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 313e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if ((st->vadreg & 0x4000) != 0) 314e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 315e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 316e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (st->stat_count != 0) 317e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 318b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->stat_count = st->stat_count - 1; 319e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 320e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 321e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 322e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 323e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 324e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 325e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Update average amplitude estimate for stationarity estimation */ 326b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard alpha = ALPHA4; 327e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(st->stat_count == STAT_COUNT) 328e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 329b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard alpha = 32767; 330e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } else if ((st->vadreg & 0x4000) == 0) 331e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 332b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard alpha = ALPHA5; 333e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 334e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < COMPLEN; i++) 335e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 336b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->ave_level[i] = add1(st->ave_level[i], vo_mult_r(alpha, vo_sub(level[i], st->ave_level[i]))); 337e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 338e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 339e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 340e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/****************************************************************************** 341e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 342e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Function : hangover_addition 343e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Purpose : Add hangover after speech bursts 344e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 345e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*******************************************************************************/ 346e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 347e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic Word16 hangover_addition( /* return: VAD_flag indicating final VAD decision */ 348e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard VadVars * st, /* i/o : State structure */ 349e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 low_power, /* i : flag power of the input frame */ 350e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 hang_len, /* i : hangover length */ 351e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 burst_len /* i : minimum burst length for hangover addition */ 352e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ) 353e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 354e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* if the input power (pow_sum) is lower than a threshold, clear counters and set VAD_flag to "0" */ 355e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (low_power != 0) 356e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 357b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->burst_count = 0; 358b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->hang_count = 0; 359e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return 0; 360e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 361e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* update the counters (hang_count, burst_count) */ 362e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if ((st->vadreg & 0x4000) != 0) 363e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 364b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->burst_count = st->burst_count + 1; 365e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(st->burst_count >= burst_len) 366e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 367b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->hang_count = hang_len; 368e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 369e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return 1; 370e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } else 371e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 372b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->burst_count = 0; 373e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (st->hang_count > 0) 374e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 375b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->hang_count = st->hang_count - 1; 376e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return 1; 377e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 378e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 379e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return 0; 380e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 381e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 382e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/****************************************************************************** 383e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 384e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Function : noise_estimate_update 385e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Purpose : Update of background noise estimate 386e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 387e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*******************************************************************************/ 388e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 389e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic void noise_estimate_update( 390e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard VadVars * st, /* i/o : State structure */ 391e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 level[] /* i : sub-band levels of the input frame */ 392e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ) 393e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 394b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard Word32 i; 395e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 alpha_up, alpha_down, bckr_add = 2; 396e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 397e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Control update of bckr_est[] */ 398e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard update_cntrl(st, level); 399e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 400e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Choose update speed */ 401e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if ((0x7800 & st->vadreg) == 0) 402e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 403b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard alpha_up = ALPHA_UP1; 404b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard alpha_down = ALPHA_DOWN1; 405e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } else 406e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 407e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if ((st->stat_count == 0)) 408e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 409b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard alpha_up = ALPHA_UP2; 410b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard alpha_down = ALPHA_DOWN2; 411e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } else 412e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 413b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard alpha_up = 0; 414b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard alpha_down = ALPHA3; 415b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard bckr_add = 0; 416e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 417e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 418e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 419e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Update noise estimate (bckr_est) */ 420e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < COMPLEN; i++) 421e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 422e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 temp; 423e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard temp = (st->old_level[i] - st->bckr_est[i]); 424e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 425e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (temp < 0) 426e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { /* update downwards */ 427b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->bckr_est[i] = add1(-2, add(st->bckr_est[i],vo_mult_r(alpha_down, temp))); 428e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* limit minimum value of the noise estimate to NOISE_MIN */ 429e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(st->bckr_est[i] < NOISE_MIN) 430e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 431b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->bckr_est[i] = NOISE_MIN; 432e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 433e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } else 434e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { /* update upwards */ 435b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->bckr_est[i] = add1(bckr_add, add1(st->bckr_est[i],vo_mult_r(alpha_up, temp))); 436e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 437e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* limit maximum value of the noise estimate to NOISE_MAX */ 438e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(st->bckr_est[i] > NOISE_MAX) 439e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 440b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->bckr_est[i] = NOISE_MAX; 441e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 442e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 443e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 444e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 445e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Update signal levels of the previous frame (old_level) */ 446e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < COMPLEN; i++) 447e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 448b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->old_level[i] = level[i]; 449e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 450e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 451e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 452e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/****************************************************************************** 453e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 454e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Function : vad_decision 455e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Purpose : Calculates VAD_flag 456e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 457e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*******************************************************************************/ 458e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 459e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic Word16 vad_decision( /* return value : VAD_flag */ 460e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard VadVars * st, /* i/o : State structure */ 461e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 level[COMPLEN], /* i : sub-band levels of the input frame */ 462e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 pow_sum /* i : power of the input frame */ 463e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ) 464e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 465e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 i; 466e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 L_snr_sum; 467e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 L_temp; 468e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 vad_thr, temp, noise_level; 469e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 low_power_flag; 470e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 hang_len, burst_len; 471e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 ilog2_speech_level, ilog2_noise_level; 472e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 temp2; 473e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 474e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Calculate squared sum of the input levels (level) divided by the background noise components 475e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * (bckr_est). */ 476b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard L_snr_sum = 0; 477e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < COMPLEN; i++) 478e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 479e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 exp; 480e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 481e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard exp = norm_s(st->bckr_est[i]); 482e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard temp = (st->bckr_est[i] << exp); 483e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard temp = div_s((level[i] >> 1), temp); 484e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard temp = shl(temp, (exp - (UNIRSHFT - 1))); 485e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_snr_sum = L_mac(L_snr_sum, temp, temp); 486e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 487e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 488e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Calculate average level of estimated background noise */ 489b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard L_temp = 0; 490e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 1; i < COMPLEN; i++) /* ignore lowest band */ 491e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 492e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_temp = vo_L_add(L_temp, st->bckr_est[i]); 493e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 494e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 495e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard noise_level = extract_h((L_temp << 12)); 496e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* if SNR is lower than a threshold (MIN_SPEECH_SNR), and increase speech_level */ 497e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard temp = vo_mult(noise_level, MIN_SPEECH_SNR) << 3; 498e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 499e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(st->speech_level < temp) 500e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 501b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->speech_level = temp; 502e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 503e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ilog2_noise_level = ilog2(noise_level); 504e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 505e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* If SNR is very poor, speech_level is probably corrupted by noise level. This is correctred by 506e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * subtracting MIN_SPEECH_SNR*noise_level from speech level */ 507e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ilog2_speech_level = ilog2(st->speech_level - temp); 508e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 509e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard temp = add1(vo_mult(NO_SLOPE, (ilog2_noise_level - NO_P1)), THR_HIGH); 510e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 511e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard temp2 = add1(SP_CH_MIN, vo_mult(SP_SLOPE, (ilog2_speech_level - SP_P1))); 512e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (temp2 < SP_CH_MIN) 513e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 514b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard temp2 = SP_CH_MIN; 515e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 516e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (temp2 > SP_CH_MAX) 517e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 518b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard temp2 = SP_CH_MAX; 519e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 520e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard vad_thr = temp + temp2; 521e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 522e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(vad_thr < THR_MIN) 523e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 524b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard vad_thr = THR_MIN; 525e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 526e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Shift VAD decision register */ 527b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->vadreg = (st->vadreg >> 1); 528e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 529e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Make intermediate VAD decision */ 530e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(L_snr_sum > vo_L_mult(vad_thr, (512 * COMPLEN))) 531e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 532b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->vadreg = (Word16) (st->vadreg | 0x4000); 533e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 534e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* check if the input power (pow_sum) is lower than a threshold" */ 535e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(pow_sum < VAD_POW_LOW) 536e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 537b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard low_power_flag = 1; 538e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } else 539e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 540b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard low_power_flag = 0; 541e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 542e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Update background noise estimates */ 543e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard noise_estimate_update(st, level); 544e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 545e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Calculate values for hang_len and burst_len based on vad_thr */ 546e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard hang_len = add1(vo_mult(HANG_SLOPE, (vad_thr - HANG_P1)), HANG_HIGH); 547e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(hang_len < HANG_LOW) 548e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 549b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard hang_len = HANG_LOW; 550e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 551e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard burst_len = add1(vo_mult(BURST_SLOPE, (vad_thr - BURST_P1)), BURST_HIGH); 552e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 553e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return (hangover_addition(st, low_power_flag, hang_len, burst_len)); 554e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 555e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 556e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/****************************************************************************** 557e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 558e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Function : Estimate_Speech() 559e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Purpose : Estimate speech level 560e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 561e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Maximum signal level is searched and stored to the variable sp_max. 562e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* The speech frames must locate within SP_EST_COUNT number of frames. 563e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Thus, noisy frames having occasional VAD = "1" decisions will not 564e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* affect to the estimated speech_level. 565e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 566e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*******************************************************************************/ 567e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 568e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic void Estimate_Speech( 569e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard VadVars * st, /* i/o : State structure */ 570e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 in_level /* level of the input frame */ 571e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ) 572e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 573e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 alpha; 574e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 575e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* if the required activity count cannot be achieved, reset counters */ 576e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if((st->sp_est_cnt - st->sp_max_cnt) > (SP_EST_COUNT - SP_ACTIVITY_COUNT)) 577e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 578b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->sp_est_cnt = 0; 579b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->sp_max = 0; 580b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->sp_max_cnt = 0; 581e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 582b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->sp_est_cnt += 1; 583e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 584e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (((st->vadreg & 0x4000)||(in_level > st->speech_level)) && (in_level > MIN_SPEECH_LEVEL1)) 585e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 586e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* update sp_max */ 587e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(in_level > st->sp_max) 588e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 589b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->sp_max = in_level; 590e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 591b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->sp_max_cnt += 1; 592e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 593e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(st->sp_max_cnt >= SP_ACTIVITY_COUNT) 594e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 595e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 tmp; 596e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* update speech estimate */ 597e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard tmp = (st->sp_max >> 1); /* scale to get "average" speech level */ 598e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 599e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* select update speed */ 600e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(tmp > st->speech_level) 601e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 602b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard alpha = ALPHA_SP_UP; 603e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } else 604e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 605b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard alpha = ALPHA_SP_DOWN; 606e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 607e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(tmp > MIN_SPEECH_LEVEL2) 608e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 609b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->speech_level = add1(st->speech_level, vo_mult_r(alpha, vo_sub(tmp, st->speech_level))); 610e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 611e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* clear all counters used for speech estimation */ 612b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->sp_max = 0; 613b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->sp_max_cnt = 0; 614b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->sp_est_cnt = 0; 615e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 616e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 617e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 618e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 619e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/****************************************************************************** 620e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 621e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Function: wb_vad_init 622e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Purpose: Allocates state memory and initializes state memory 623e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 624e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*******************************************************************************/ 625e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 626e2e838afcf03e603a41a0455846eaf9614537c16Mans RullgardWord16 wb_vad_init( /* return: non-zero with error, zero for ok. */ 627e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard VadVars ** state, /* i/o : State structure */ 628e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard VO_MEM_OPERATOR *pMemOP 629e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ) 630e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 631e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard VadVars *s; 632e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 633e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (state == (VadVars **) NULL) 634e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 635e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard fprintf(stderr, "vad_init: invalid parameter\n"); 636e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return -1; 637e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 638e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard *state = NULL; 639e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 640e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* allocate memory */ 641e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if ((s = (VadVars *) mem_malloc(pMemOP, sizeof(VadVars), 32, VO_INDEX_ENC_AMRWB)) == NULL) 642e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 643e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard fprintf(stderr, "vad_init: can not malloc state structure\n"); 644e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return -1; 645e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 646e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard wb_vad_reset(s); 647e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 648e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard *state = s; 649e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 650e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return 0; 651e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 652e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 653e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/****************************************************************************** 654e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 655e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Function: wb_vad_reset 656e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Purpose: Initializes state memory 657e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 658e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*******************************************************************************/ 659e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 660e2e838afcf03e603a41a0455846eaf9614537c16Mans RullgardWord16 wb_vad_reset( /* return: non-zero with error, zero for ok. */ 661e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard VadVars * state /* i/o : State structure */ 662e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ) 663e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 664e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 i, j; 665e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 666e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (state == (VadVars *) NULL) 667e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 668e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard fprintf(stderr, "vad_reset: invalid parameter\n"); 669e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return -1; 670e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 671e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard state->tone_flag = 0; 672e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard state->vadreg = 0; 673e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard state->hang_count = 0; 674e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard state->burst_count = 0; 675e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard state->hang_count = 0; 676e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 677e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* initialize memory used by the filter bank */ 678e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < F_5TH_CNT; i++) 679e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 680e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (j = 0; j < 2; j++) 681e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 682e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard state->a_data5[i][j] = 0; 683e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 684e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 685e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 686e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < F_3TH_CNT; i++) 687e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 688e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard state->a_data3[i] = 0; 689e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 690e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 691e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* initialize the rest of the memory */ 692e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < COMPLEN; i++) 693e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 694e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard state->bckr_est[i] = NOISE_INIT; 695e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard state->old_level[i] = NOISE_INIT; 696e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard state->ave_level[i] = NOISE_INIT; 697e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard state->sub_level[i] = 0; 698e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 699e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 700e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard state->sp_est_cnt = 0; 701e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard state->sp_max = 0; 702e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard state->sp_max_cnt = 0; 703e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard state->speech_level = SPEECH_LEVEL_INIT; 704e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard state->prev_pow_sum = 0; 705e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return 0; 706e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 707e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 708e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/****************************************************************************** 709e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 710e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Function: wb_vad_exit 711e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Purpose: The memory used for state memory is freed 712e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 713e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*******************************************************************************/ 714e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 715e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardvoid wb_vad_exit( 716e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard VadVars ** state, /* i/o : State structure */ 717e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard VO_MEM_OPERATOR *pMemOP 718e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ) 719e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 720e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (state == NULL || *state == NULL) 721e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return; 722e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* deallocate memory */ 723e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard mem_free(pMemOP, *state, VO_INDEX_ENC_AMRWB); 724e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard *state = NULL; 725e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return; 726e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 727e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 728e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/****************************************************************************** 729e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 730e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Function : wb_vad_tone_detection 731e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Purpose : Search maximum pitch gain from a frame. Set tone flag if 732e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* pitch gain is high. This is used to detect 733e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* signaling tones and other signals with high pitch gain. 734e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 735e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*******************************************************************************/ 736e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 737e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardvoid wb_vad_tone_detection( 738e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard VadVars * st, /* i/o : State struct */ 739e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 p_gain /* pitch gain */ 740e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ) 741e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 742e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* update tone flag */ 743e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard st->tone_flag = (st->tone_flag >> 1); 744e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 745e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* if (pitch_gain > TONE_THR) set tone flag */ 746e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (p_gain > TONE_THR) 747e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 748e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard st->tone_flag = (Word16) (st->tone_flag | 0x4000); 749e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 750e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 751e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 752e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/****************************************************************************** 753e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 754e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Function : wb_vad 755e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Purpose : Main program for Voice Activity Detection (VAD) for AMR 756e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* 757e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*******************************************************************************/ 758e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 759e2e838afcf03e603a41a0455846eaf9614537c16Mans RullgardWord16 wb_vad( /* Return value : VAD Decision, 1 = speech, 0 = noise */ 760e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard VadVars * st, /* i/o : State structure */ 761e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 in_buf[] /* i : samples of the input frame */ 762e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ) 763e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 764e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 level[COMPLEN]; 765e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 i; 766e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 VAD_flag, temp; 767e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 L_temp, pow_sum; 768e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 769e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Calculate power of the input frame. */ 770b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard L_temp = 0L; 771e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < FRAME_LEN; i++) 772e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 773e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_temp = L_mac(L_temp, in_buf[i], in_buf[i]); 774e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 775e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 776e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* pow_sum = power of current frame and previous frame */ 777b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard pow_sum = L_add(L_temp, st->prev_pow_sum); 778e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 779e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* save power of current frame for next call */ 780b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->prev_pow_sum = L_temp; 781e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 782e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* If input power is very low, clear tone flag */ 783e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (pow_sum < POW_TONE_THR) 784e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 785b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard st->tone_flag = (Word16) (st->tone_flag & 0x1fff); 786e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 787e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Run the filter bank and calculate signal levels at each band */ 788e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard filter_bank(st, in_buf, level); 789e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 790e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* compute VAD decision */ 791e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard VAD_flag = vad_decision(st, level, pow_sum); 792e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 793e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Calculate input level */ 794b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard L_temp = 0; 795e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 1; i < COMPLEN; i++) /* ignore lowest band */ 796e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 797e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_temp = vo_L_add(L_temp, level[i]); 798e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 799e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 800e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard temp = extract_h(L_temp << 12); 801e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 802e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Estimate_Speech(st, temp); /* Estimate speech level */ 803e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return (VAD_flag); 804e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 805e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 806e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 807e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 808e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 809