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 */ 475d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 mant /* i: value to be converted */ 485d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ) 49e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 505d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 ex, ex2, res; 515d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word32 i, l_temp; 525d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 535d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if (mant <= 0) 545d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 555d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen mant = 1; 565d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 575d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ex = norm_s(mant); 585d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen mant = mant << ex; 595d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 605d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < 3; i++) 615d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen mant = vo_mult(mant, mant); 625d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen l_temp = vo_L_mult(mant, mant); 635d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 645d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ex2 = norm_l(l_temp); 655d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen mant = extract_h(l_temp << ex2); 665d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 675d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen res = (ex + 16) << 10; 685d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen res = add1(res, (ex2 << 6)); 695d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen res = vo_sub(add1(res, 127), (mant >> 8)); 705d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 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( 825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 * in0, /* i/o : input values; output low-pass part */ 835d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 * in1, /* i/o : input values; output high-pass part */ 845d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 data[] /* i/o : filter memory */ 855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ) 86e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 875d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 temp0, temp1, temp2; 88e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 895d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen temp0 = vo_sub(*in0, vo_mult(COEFF5_1, data[0])); 905d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen temp1 = add1(data[0], vo_mult(COEFF5_1, temp0)); 915d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen data[0] = temp0; 92e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 935d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen temp0 = vo_sub(*in1, vo_mult(COEFF5_2, data[1])); 945d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen temp2 = add1(data[1], vo_mult(COEFF5_2, temp0)); 955d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen data[1] = temp0; 96e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 975d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen *in0 = extract_h((vo_L_add(temp1, temp2) << 15)); 985d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen *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( 1105d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 * in0, /* i/o : input values; output low-pass part */ 1115d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 * in1, /* i/o : input values; output high-pass part */ 1125d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 * data /* i/o : filter memory */ 1135d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ) 114e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 1155d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 temp1, temp2; 116e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 1175d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen temp1 = vo_sub(*in1, vo_mult(COEFF3, *data)); 1185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen temp2 = add1(*data, vo_mult(COEFF3, temp1)); 1195d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen *data = temp1; 120e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 1215d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen *in1 = extract_h((vo_L_sub(*in0, temp2) << 15)); 1225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen *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 */ 1385d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 data[], /* i : signal buffer */ 1395d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 * sub_level, /* i : level calculated at the end of the previous frame*/ 1405d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* o : level of signal calculated from the last */ 1415d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* (count2 - count1) samples */ 1425d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 count1, /* i : number of samples to be counted */ 1435d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 count2, /* i : number of samples to be counted */ 1445d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 ind_m, /* i : step size for the index of the data buffer */ 1455d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 ind_a, /* i : starting index of the data buffer */ 1465d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 scale /* i : scaling for the level calculation */ 1475d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ) 148e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 1495d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word32 i, l_temp1, l_temp2; 1505d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 level; 151e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 1525d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen l_temp1 = 0L; 1535d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = count1; i < count2; i++) 1545d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 1555d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen l_temp1 += (abs_s(data[ind_m * i + ind_a])<<1); 1565d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 157e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 1585d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen l_temp2 = vo_L_add(l_temp1, L_shl(*sub_level, 16 - scale)); 1595d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen *sub_level = extract_h(L_shl(l_temp1, scale)); 160e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 1615d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < count1; i++) 1625d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 1635d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen l_temp2 += (abs_s(data[ind_m * i + ind_a])<<1); 1645d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 1655d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen level = extract_h(L_shl2(l_temp2, scale)); 166e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 1675d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 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( 1795d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen VadVars * st, /* i/o : State struct */ 1805d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 in[], /* i : input frame */ 1815d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 level[] /* o : signal levels at each band */ 1825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ) 183e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 1845d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word32 i; 1855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 tmp_buf[FRAME_LEN]; 1865d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 1875d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* shift input 1 bit down for safe scaling */ 1885d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < FRAME_LEN; i++) 1895d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 1905d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen tmp_buf[i] = in[i] >> 1; 1915d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 1925d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 1935d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* run the filter bank */ 1945d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < 128; i++) 1955d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 1965d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen filter5(&tmp_buf[2 * i], &tmp_buf[2 * i + 1], st->a_data5[0]); 1975d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 1985d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < 64; i++) 1995d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 2005d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen filter5(&tmp_buf[4 * i], &tmp_buf[4 * i + 2], st->a_data5[1]); 2015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen filter5(&tmp_buf[4 * i + 1], &tmp_buf[4 * i + 3], st->a_data5[2]); 2025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 2035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < 32; i++) 2045d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 2055d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen filter5(&tmp_buf[8 * i], &tmp_buf[8 * i + 4], st->a_data5[3]); 2065d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen filter5(&tmp_buf[8 * i + 2], &tmp_buf[8 * i + 6], st->a_data5[4]); 2075d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen filter3(&tmp_buf[8 * i + 3], &tmp_buf[8 * i + 7], &st->a_data3[0]); 2085d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 2095d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < 16; i++) 2105d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 2115d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen filter3(&tmp_buf[16 * i + 0], &tmp_buf[16 * i + 8], &st->a_data3[1]); 2125d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen filter3(&tmp_buf[16 * i + 4], &tmp_buf[16 * i + 12], &st->a_data3[2]); 2135d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen filter3(&tmp_buf[16 * i + 6], &tmp_buf[16 * i + 14], &st->a_data3[3]); 2145d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 2155d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2165d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < 8; i++) 2175d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 2185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen filter3(&tmp_buf[32 * i + 0], &tmp_buf[32 * i + 16], &st->a_data3[4]); 2195d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen filter3(&tmp_buf[32 * i + 8], &tmp_buf[32 * i + 24], &st->a_data3[5]); 2205d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 2215d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* calculate levels in each frequency band */ 2235d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2245d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* 4800 - 6400 Hz */ 2255d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen level[11] = level_calculation(tmp_buf, &st->sub_level[11], 16, 64, 4, 1, 14); 2265d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* 4000 - 4800 Hz */ 2275d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen level[10] = level_calculation(tmp_buf, &st->sub_level[10], 8, 32, 8, 7, 15); 2285d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* 3200 - 4000 Hz */ 2295d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen level[9] = level_calculation(tmp_buf, &st->sub_level[9],8, 32, 8, 3, 15); 2305d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* 2400 - 3200 Hz */ 2315d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen level[8] = level_calculation(tmp_buf, &st->sub_level[8],8, 32, 8, 2, 15); 2325d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* 2000 - 2400 Hz */ 2335d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen level[7] = level_calculation(tmp_buf, &st->sub_level[7],4, 16, 16, 14, 16); 2345d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* 1600 - 2000 Hz */ 2355d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen level[6] = level_calculation(tmp_buf, &st->sub_level[6],4, 16, 16, 6, 16); 2365d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* 1200 - 1600 Hz */ 2375d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen level[5] = level_calculation(tmp_buf, &st->sub_level[5],4, 16, 16, 4, 16); 2385d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* 800 - 1200 Hz */ 2395d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen level[4] = level_calculation(tmp_buf, &st->sub_level[4],4, 16, 16, 12, 16); 2405d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* 600 - 800 Hz */ 2415d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen level[3] = level_calculation(tmp_buf, &st->sub_level[3],2, 8, 32, 8, 17); 2425d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* 400 - 600 Hz */ 2435d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen level[2] = level_calculation(tmp_buf, &st->sub_level[2],2, 8, 32, 24, 17); 2445d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* 200 - 400 Hz */ 2455d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen level[1] = level_calculation(tmp_buf, &st->sub_level[1],2, 8, 32, 16, 17); 2465d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* 0 - 200 Hz */ 2475d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 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( 2585d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen VadVars * st, /* i/o : State structure */ 2595d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 level[] /* i : sub-band levels of the input frame */ 2605d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ) 261e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 2625d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word32 i; 2635d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 num, temp, stat_rat, exp, denom; 2645d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 alpha; 2655d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2665d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* if a tone has been detected for a while, initialize stat_count */ 2675d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if (sub((Word16) (st->tone_flag & 0x7c00), 0x7c00) == 0) 2685d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 2695d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->stat_count = STAT_COUNT; 2705d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } else 2715d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 2725d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* if 8 last vad-decisions have been "0", reinitialize stat_count */ 2735d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if ((st->vadreg & 0x7f80) == 0) 2745d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 2755d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->stat_count = STAT_COUNT; 2765d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } else 2775d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 2785d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen stat_rat = 0; 2795d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < COMPLEN; i++) 2805d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 2815d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if(level[i] > st->ave_level[i]) 2825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 2835d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen num = level[i]; 2845d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen denom = st->ave_level[i]; 2855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } else 2865d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 2875d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen num = st->ave_level[i]; 2885d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen denom = level[i]; 2895d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 2905d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Limit nimimum value of num and denom to STAT_THR_LEVEL */ 2915d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if(num < STAT_THR_LEVEL) 2925d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 2935d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen num = STAT_THR_LEVEL; 2945d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 2955d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if(denom < STAT_THR_LEVEL) 2965d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 2975d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen denom = STAT_THR_LEVEL; 2985d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 2995d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen exp = norm_s(denom); 3005d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen denom = denom << exp; 3015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 3025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* stat_rat = num/denom * 64 */ 3035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen temp = div_s(num >> 1, denom); 3045d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen stat_rat = add1(stat_rat, shr(temp, (8 - exp))); 3055d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 3065d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 3075d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* compare stat_rat with a threshold and update stat_count */ 3085d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if(stat_rat > STAT_THR) 3095d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 3105d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->stat_count = STAT_COUNT; 3115d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } else 3125d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 3135d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if ((st->vadreg & 0x4000) != 0) 3145d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 3155d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 3165d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if (st->stat_count != 0) 3175d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 3185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->stat_count = st->stat_count - 1; 3195d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 3205d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 3215d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 3225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 3235d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 3245d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 3255d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Update average amplitude estimate for stationarity estimation */ 3265d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen alpha = ALPHA4; 3275d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if(st->stat_count == STAT_COUNT) 3285d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 3295d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen alpha = 32767; 3305d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } else if ((st->vadreg & 0x4000) == 0) 3315d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 3325d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen alpha = ALPHA5; 3335d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 3345d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < COMPLEN; i++) 3355d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 3365d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->ave_level[i] = add1(st->ave_level[i], vo_mult_r(alpha, vo_sub(level[i], st->ave_level[i]))); 3375d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 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 */ 3485d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen VadVars * st, /* i/o : State structure */ 3495d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 low_power, /* i : flag power of the input frame */ 3505d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 hang_len, /* i : hangover length */ 3515d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 burst_len /* i : minimum burst length for hangover addition */ 3525d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ) 353e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 3545d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* if the input power (pow_sum) is lower than a threshold, clear counters and set VAD_flag to "0" */ 3555d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if (low_power != 0) 3565d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 3575d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->burst_count = 0; 3585d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->hang_count = 0; 3595d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen return 0; 3605d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 3615d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* update the counters (hang_count, burst_count) */ 3625d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if ((st->vadreg & 0x4000) != 0) 3635d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 3645d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->burst_count = st->burst_count + 1; 3655d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if(st->burst_count >= burst_len) 3665d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 3675d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->hang_count = hang_len; 3685d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 3695d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen return 1; 3705d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } else 3715d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 3725d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->burst_count = 0; 3735d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if (st->hang_count > 0) 3745d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 3755d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->hang_count = st->hang_count - 1; 3765d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen return 1; 3775d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 3785d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 3795d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 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( 3905d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen VadVars * st, /* i/o : State structure */ 3915d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 level[] /* i : sub-band levels of the input frame */ 3925d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ) 393e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 3945d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word32 i; 3955d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 alpha_up, alpha_down, bckr_add = 2; 3965d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 3975d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Control update of bckr_est[] */ 3985d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen update_cntrl(st, level); 3995d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 4005d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Choose update speed */ 4015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if ((0x7800 & st->vadreg) == 0) 4025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 4035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen alpha_up = ALPHA_UP1; 4045d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen alpha_down = ALPHA_DOWN1; 4055d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } else 4065d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 4075d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if (st->stat_count == 0) 4085d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 4095d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen alpha_up = ALPHA_UP2; 4105d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen alpha_down = ALPHA_DOWN2; 4115d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } else 4125d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 4135d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen alpha_up = 0; 4145d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen alpha_down = ALPHA3; 4155d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen bckr_add = 0; 4165d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 4175d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 4185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 4195d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Update noise estimate (bckr_est) */ 4205d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < COMPLEN; i++) 4215d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 4225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 temp; 4235d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen temp = (st->old_level[i] - st->bckr_est[i]); 4245d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 4255d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if (temp < 0) 4265d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { /* update downwards */ 4275d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->bckr_est[i] = add1(-2, add(st->bckr_est[i],vo_mult_r(alpha_down, temp))); 4285d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* limit minimum value of the noise estimate to NOISE_MIN */ 4295d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if(st->bckr_est[i] < NOISE_MIN) 4305d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 4315d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->bckr_est[i] = NOISE_MIN; 4325d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 4335d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } else 4345d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { /* update upwards */ 4355d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->bckr_est[i] = add1(bckr_add, add1(st->bckr_est[i],vo_mult_r(alpha_up, temp))); 4365d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 4375d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* limit maximum value of the noise estimate to NOISE_MAX */ 4385d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if(st->bckr_est[i] > NOISE_MAX) 4395d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 4405d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->bckr_est[i] = NOISE_MAX; 4415d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 4425d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 4435d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 4445d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 4455d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Update signal levels of the previous frame (old_level) */ 4465d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < COMPLEN; i++) 4475d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 4485d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->old_level[i] = level[i]; 4495d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 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 */ 4605d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen VadVars * st, /* i/o : State structure */ 4615d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 level[COMPLEN], /* i : sub-band levels of the input frame */ 4625d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word32 pow_sum /* i : power of the input frame */ 4635d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ) 464e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 4655d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word32 i; 4665d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word32 L_snr_sum; 4675d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word32 L_temp; 4685d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 vad_thr, temp, noise_level; 4695d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 low_power_flag; 4705d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 hang_len, burst_len; 4715d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 ilog2_speech_level, ilog2_noise_level; 4725d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 temp2; 4735d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 4745d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Calculate squared sum of the input levels (level) divided by the background noise components 4755d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * (bckr_est). */ 4765d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_snr_sum = 0; 4775d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < COMPLEN; i++) 4785d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 4795d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 exp; 4805d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 4815d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen exp = norm_s(st->bckr_est[i]); 4825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen temp = (st->bckr_est[i] << exp); 4835d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen temp = div_s((level[i] >> 1), temp); 4845d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen temp = shl(temp, (exp - (UNIRSHFT - 1))); 4855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_snr_sum = L_mac(L_snr_sum, temp, temp); 4865d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 4875d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 4885d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Calculate average level of estimated background noise */ 4895d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_temp = 0; 4905d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 1; i < COMPLEN; i++) /* ignore lowest band */ 4915d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 4925d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_temp = vo_L_add(L_temp, st->bckr_est[i]); 4935d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 4945d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 4955d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen noise_level = extract_h((L_temp << 12)); 4965d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* if SNR is lower than a threshold (MIN_SPEECH_SNR), and increase speech_level */ 4975d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen temp = vo_mult(noise_level, MIN_SPEECH_SNR) << 3; 4985d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 4995d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if(st->speech_level < temp) 5005d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 5015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->speech_level = temp; 5025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 5035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ilog2_noise_level = ilog2(noise_level); 5045d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 5055d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* If SNR is very poor, speech_level is probably corrupted by noise level. This is correctred by 5065d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * subtracting MIN_SPEECH_SNR*noise_level from speech level */ 5075d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ilog2_speech_level = ilog2(st->speech_level - temp); 5085d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 5095d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen temp = add1(vo_mult(NO_SLOPE, (ilog2_noise_level - NO_P1)), THR_HIGH); 5105d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 5115d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen temp2 = add1(SP_CH_MIN, vo_mult(SP_SLOPE, (ilog2_speech_level - SP_P1))); 5125d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if (temp2 < SP_CH_MIN) 5135d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 5145d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen temp2 = SP_CH_MIN; 5155d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 5165d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if (temp2 > SP_CH_MAX) 5175d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 5185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen temp2 = SP_CH_MAX; 5195d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 5205d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen vad_thr = temp + temp2; 5215d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 5225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if(vad_thr < THR_MIN) 5235d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 5245d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen vad_thr = THR_MIN; 5255d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 5265d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Shift VAD decision register */ 5275d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->vadreg = (st->vadreg >> 1); 5285d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 5295d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Make intermediate VAD decision */ 5305d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if(L_snr_sum > vo_L_mult(vad_thr, (512 * COMPLEN))) 5315d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 5325d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->vadreg = (Word16) (st->vadreg | 0x4000); 5335d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 5345d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* check if the input power (pow_sum) is lower than a threshold" */ 5355d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if(pow_sum < VAD_POW_LOW) 5365d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 5375d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen low_power_flag = 1; 5385d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } else 5395d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 5405d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen low_power_flag = 0; 5415d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 5425d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Update background noise estimates */ 5435d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen noise_estimate_update(st, level); 5445d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 5455d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Calculate values for hang_len and burst_len based on vad_thr */ 5465d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen hang_len = add1(vo_mult(HANG_SLOPE, (vad_thr - HANG_P1)), HANG_HIGH); 5475d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if(hang_len < HANG_LOW) 5485d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 5495d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen hang_len = HANG_LOW; 5505d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 5515d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen burst_len = add1(vo_mult(BURST_SLOPE, (vad_thr - BURST_P1)), BURST_HIGH); 5525d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 5535d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 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( 5695d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen VadVars * st, /* i/o : State structure */ 5705d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 in_level /* level of the input frame */ 5715d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ) 572e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 5735d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 alpha; 5745d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 5755d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* if the required activity count cannot be achieved, reset counters */ 5765d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if((st->sp_est_cnt - st->sp_max_cnt) > (SP_EST_COUNT - SP_ACTIVITY_COUNT)) 5775d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 5785d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->sp_est_cnt = 0; 5795d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->sp_max = 0; 5805d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->sp_max_cnt = 0; 5815d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 5825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->sp_est_cnt += 1; 5835d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 5845d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if (((st->vadreg & 0x4000)||(in_level > st->speech_level)) && (in_level > MIN_SPEECH_LEVEL1)) 5855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 5865d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* update sp_max */ 5875d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if(in_level > st->sp_max) 5885d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 5895d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->sp_max = in_level; 5905d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 5915d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->sp_max_cnt += 1; 5925d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 5935d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if(st->sp_max_cnt >= SP_ACTIVITY_COUNT) 5945d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 5955d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 tmp; 5965d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* update speech estimate */ 5975d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen tmp = (st->sp_max >> 1); /* scale to get "average" speech level */ 5985d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 5995d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* select update speed */ 6005d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if(tmp > st->speech_level) 6015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 6025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen alpha = ALPHA_SP_UP; 6035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } else 6045d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 6055d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen alpha = ALPHA_SP_DOWN; 6065d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 6075d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if(tmp > MIN_SPEECH_LEVEL2) 6085d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 6095d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->speech_level = add1(st->speech_level, vo_mult_r(alpha, vo_sub(tmp, st->speech_level))); 6105d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 6115d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* clear all counters used for speech estimation */ 6125d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->sp_max = 0; 6135d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->sp_max_cnt = 0; 6145d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->sp_est_cnt = 0; 6155d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 6165d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 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. */ 6275d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen VadVars ** state, /* i/o : State structure */ 6285d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen VO_MEM_OPERATOR *pMemOP 6295d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ) 630e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 6315d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen VadVars *s; 6325d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 6335d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if (state == (VadVars **) NULL) 6345d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 6355d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen fprintf(stderr, "vad_init: invalid parameter\n"); 6365d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen return -1; 6375d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 6385d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen *state = NULL; 6395d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 6405d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* allocate memory */ 6415d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if ((s = (VadVars *) mem_malloc(pMemOP, sizeof(VadVars), 32, VO_INDEX_ENC_AMRWB)) == NULL) 6425d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 6435d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen fprintf(stderr, "vad_init: can not malloc state structure\n"); 6445d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen return -1; 6455d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 6465d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen wb_vad_reset(s); 6475d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 6485d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen *state = s; 6495d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 6505d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 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. */ 6615d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen VadVars * state /* i/o : State structure */ 6625d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ) 663e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 6645d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word32 i, j; 6655d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 6665d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if (state == (VadVars *) NULL) 6675d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 6685d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen fprintf(stderr, "vad_reset: invalid parameter\n"); 6695d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen return -1; 6705d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 6715d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen state->tone_flag = 0; 6725d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen state->vadreg = 0; 6735d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen state->hang_count = 0; 6745d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen state->burst_count = 0; 6755d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen state->hang_count = 0; 6765d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 6775d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* initialize memory used by the filter bank */ 6785d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < F_5TH_CNT; i++) 6795d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 6805d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (j = 0; j < 2; j++) 6815d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 6825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen state->a_data5[i][j] = 0; 6835d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 6845d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 6855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 6865d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < F_3TH_CNT; i++) 6875d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 6885d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen state->a_data3[i] = 0; 6895d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 6905d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 6915d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* initialize the rest of the memory */ 6925d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < COMPLEN; i++) 6935d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 6945d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen state->bckr_est[i] = NOISE_INIT; 6955d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen state->old_level[i] = NOISE_INIT; 6965d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen state->ave_level[i] = NOISE_INIT; 6975d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen state->sub_level[i] = 0; 6985d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 6995d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 7005d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen state->sp_est_cnt = 0; 7015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen state->sp_max = 0; 7025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen state->sp_max_cnt = 0; 7035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen state->speech_level = SPEECH_LEVEL_INIT; 7045d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen state->prev_pow_sum = 0; 7055d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 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( 7165d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen VadVars ** state, /* i/o : State structure */ 7175d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen VO_MEM_OPERATOR *pMemOP 7185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ) 719e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 7205d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if (state == NULL || *state == NULL) 7215d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen return; 7225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* deallocate memory */ 7235d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen mem_free(pMemOP, *state, VO_INDEX_ENC_AMRWB); 7245d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen *state = NULL; 7255d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 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( 7385d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen VadVars * st, /* i/o : State struct */ 7395d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 p_gain /* pitch gain */ 7405d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ) 741e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 7425d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* update tone flag */ 7435d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->tone_flag = (st->tone_flag >> 1); 7445d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 7455d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* if (pitch_gain > TONE_THR) set tone flag */ 7465d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if (p_gain > TONE_THR) 7475d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 7485d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->tone_flag = (Word16) (st->tone_flag | 0x4000); 7495d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 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 */ 7605d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen VadVars * st, /* i/o : State structure */ 7615d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 in_buf[] /* i : samples of the input frame */ 7625d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ) 763e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 7645d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 level[COMPLEN]; 7655d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word32 i; 7665d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 VAD_flag, temp; 7675d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word32 L_temp, pow_sum; 7685d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 7695d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Calculate power of the input frame. */ 7705d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_temp = 0L; 7715d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < FRAME_LEN; i++) 7725d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 7735d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_temp = L_mac(L_temp, in_buf[i], in_buf[i]); 7745d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 7755d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 7765d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* pow_sum = power of current frame and previous frame */ 7775d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen pow_sum = L_add(L_temp, st->prev_pow_sum); 7785d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 7795d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* save power of current frame for next call */ 7805d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->prev_pow_sum = L_temp; 7815d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 7825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* If input power is very low, clear tone flag */ 7835d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if (pow_sum < POW_TONE_THR) 7845d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 7855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen st->tone_flag = (Word16) (st->tone_flag & 0x1fff); 7865d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 7875d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Run the filter bank and calculate signal levels at each band */ 7885d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen filter_bank(st, in_buf, level); 7895d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 7905d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* compute VAD decision */ 7915d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen VAD_flag = vad_decision(st, level, pow_sum); 7925d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 7935d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Calculate input level */ 7945d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_temp = 0; 7955d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 1; i < COMPLEN; i++) /* ignore lowest band */ 7965d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 7975d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_temp = vo_L_add(L_temp, level[i]); 7985d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 7995d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 8005d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen temp = extract_h(L_temp << 12); 8015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 8025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Estimate_Speech(st, temp); /* Estimate speech level */ 8035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen return (VAD_flag); 804e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 805e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 806e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 807e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 808e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 809