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