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: dtx.c                                                    *
19e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*                                                                      *
20e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*	    Description:DTX functions                                  *
21e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*                                                                      *
22e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard************************************************************************/
23e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
24e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include <stdio.h>
25e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include <stdlib.h>
26e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "typedef.h"
27e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "basic_op.h"
28e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "oper_32b.h"
29e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "math_op.h"
30e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "cnst.h"
31e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "acelp.h"                         /* prototype of functions    */
32e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "bits.h"
33e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "dtx.h"
34e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "log2.h"
35e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "mem_align.h"
36e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
37e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic void aver_isf_history(
38e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 isf_old[],
39e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 indices[],
40e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word32 isf_aver[]
41e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		);
42e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
43e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic void find_frame_indices(
44e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 isf_old_tx[],
45e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 indices[],
46e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		dtx_encState * st
47e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		);
48e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
49e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic Word16 dithering_control(
50e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		dtx_encState * st
51e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		);
52e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
53e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/* excitation energy adjustment depending on speech coder mode used, Q7 */
54e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic Word16 en_adjust[9] =
55e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
56e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	230,                                   /* mode0 = 7k  :  -5.4dB  */
57e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	179,                                   /* mode1 = 9k  :  -4.2dB  */
58e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	141,                                   /* mode2 = 12k :  -3.3dB  */
59e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	128,                                   /* mode3 = 14k :  -3.0dB  */
60e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	122,                                   /* mode4 = 16k :  -2.85dB */
61e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	115,                                   /* mode5 = 18k :  -2.7dB  */
62e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	115,                                   /* mode6 = 20k :  -2.7dB  */
63e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	115,                                   /* mode7 = 23k :  -2.7dB  */
64e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	115                                    /* mode8 = 24k :  -2.7dB  */
65e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard};
66e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
67e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/**************************************************************************
68e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*
69e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Function    : dtx_enc_init
70e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*
71e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard**************************************************************************/
72e2e838afcf03e603a41a0455846eaf9614537c16Mans RullgardWord16 dtx_enc_init(dtx_encState ** st, Word16 isf_init[], VO_MEM_OPERATOR *pMemOP)
73e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
74e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	dtx_encState *s;
75e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
76e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	if (st == (dtx_encState **) NULL)
77e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
78e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		fprintf(stderr, "dtx_enc_init: invalid parameter\n");
79e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		return -1;
80e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
81e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	*st = NULL;
82e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
83e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* allocate memory */
84e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	if ((s = (dtx_encState *)mem_malloc(pMemOP, sizeof(dtx_encState), 32, VO_INDEX_ENC_AMRWB)) == NULL)
85e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
86e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		fprintf(stderr, "dtx_enc_init: can not malloc state structure\n");
87e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		return -1;
88e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
89e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	dtx_enc_reset(s, isf_init);
90e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	*st = s;
91e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	return 0;
92e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
93e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
94e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/**************************************************************************
95e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*
96e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Function    : dtx_enc_reset
97e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*
98e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard**************************************************************************/
99e2e838afcf03e603a41a0455846eaf9614537c16Mans RullgardWord16 dtx_enc_reset(dtx_encState * st, Word16 isf_init[])
100e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
101e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word32 i;
102e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
103e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	if (st == (dtx_encState *) NULL)
104e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
105e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		fprintf(stderr, "dtx_enc_reset: invalid parameter\n");
106e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		return -1;
107e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
108b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	st->hist_ptr = 0;
109b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	st->log_en_index = 0;
110e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
111e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Init isf_hist[] */
112e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = 0; i < DTX_HIST_SIZE; i++)
113e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
114e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Copy(isf_init, &st->isf_hist[i * M], M);
115e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
116b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	st->cng_seed = RANDOM_INITSEED;
117e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
118e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Reset energy history */
119e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Set_zero(st->log_en_hist, DTX_HIST_SIZE);
120e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
121b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	st->dtxHangoverCount = DTX_HANG_CONST;
122b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	st->decAnaElapsedCount = 32767;
123e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
124e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = 0; i < 28; i++)
125e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
126b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		st->D[i] = 0;
127e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
128e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
129e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = 0; i < DTX_HIST_SIZE - 1; i++)
130e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
131b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		st->sumD[i] = 0;
132e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
133e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
134e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	return 1;
135e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
136e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
137e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/**************************************************************************
138e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*
139e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Function    : dtx_enc_exit
140e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*
141e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard**************************************************************************/
142e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardvoid dtx_enc_exit(dtx_encState ** st, VO_MEM_OPERATOR *pMemOP)
143e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
144e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	if (st == NULL || *st == NULL)
145e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		return;
146e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* deallocate memory */
147e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	mem_free(pMemOP, *st, VO_INDEX_ENC_AMRWB);
148e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	*st = NULL;
149e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	return;
150e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
151e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
152e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
153e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/**************************************************************************
154e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*
155e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Function    : dtx_enc
156e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*
157e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard**************************************************************************/
158e2e838afcf03e603a41a0455846eaf9614537c16Mans RullgardWord16 dtx_enc(
159e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		dtx_encState * st,                    /* i/o : State struct                                         */
160e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 isf[M],                        /* o   : CN ISF vector                                        */
161e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 * exc2,                        /* o   : CN excitation                                        */
162e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 ** prms
163e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	      )
164e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
165e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word32 i, j;
166e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 indice[7];
167e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 log_en, gain, level, exp, exp0, tmp;
168e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 log_en_int_e, log_en_int_m;
169e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word32 L_isf[M], ener32, level32;
170e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 isf_order[3];
171e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 CN_dith;
172e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
173e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* VOX mode computation of SID parameters */
174e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	log_en = 0;
175e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = 0; i < M; i++)
176e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
177e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		L_isf[i] = 0;
178e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
179e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* average energy and isf */
180e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = 0; i < DTX_HIST_SIZE; i++)
181e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
182e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		/* Division by DTX_HIST_SIZE = 8 has been done in dtx_buffer. log_en is in Q10 */
183e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		log_en = add(log_en, st->log_en_hist[i]);
184e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
185e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
186e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	find_frame_indices(st->isf_hist, isf_order, st);
187e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	aver_isf_history(st->isf_hist, isf_order, L_isf);
188e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
189e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (j = 0; j < M; j++)
190e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
191e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		isf[j] = (Word16)(L_isf[j] >> 3);  /* divide by 8 */
192e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
193e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
194e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* quantize logarithmic energy to 6 bits (-6 : 66 dB) which corresponds to -2:22 in log2(E).  */
195e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* st->log_en_index = (short)( (log_en + 2.0) * 2.625 ); */
196e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
197e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* increase dynamics to 7 bits (Q8) */
198e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	log_en = (log_en >> 2);
199e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
200e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Add 2 in Q8 = 512 to get log2(E) between 0:24 */
201e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	log_en = add(log_en, 512);
202e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
203e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Multiply by 2.625 to get full 6 bit range. 2.625 = 21504 in Q13. The result is in Q6 */
204e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	log_en = mult(log_en, 21504);
205e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
206e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Quantize Energy */
207e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	st->log_en_index = shr(log_en, 6);
208e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
209e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	if(st->log_en_index > 63)
210e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
211e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		st->log_en_index = 63;
212e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
213e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	if (st->log_en_index < 0)
214e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
215e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		st->log_en_index = 0;
216e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
217e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Quantize ISFs */
218e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Qisf_ns(isf, isf, indice);
219e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
220e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
221e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Parm_serial(indice[0], 6, prms);
222e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Parm_serial(indice[1], 6, prms);
223e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Parm_serial(indice[2], 6, prms);
224e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Parm_serial(indice[3], 5, prms);
225e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Parm_serial(indice[4], 5, prms);
226e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
227e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Parm_serial((st->log_en_index), 6, prms);
228e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
229e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	CN_dith = dithering_control(st);
230e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Parm_serial(CN_dith, 1, prms);
231e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
232e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* level = (float)( pow( 2.0f, (float)st->log_en_index / 2.625 - 2.0 ) );    */
233e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* log2(E) in Q9 (log2(E) lies in between -2:22) */
234e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	log_en = shl(st->log_en_index, 15 - 6);
235e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
236e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Divide by 2.625; log_en will be between 0:24  */
237e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	log_en = mult(log_en, 12483);
238e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* the result corresponds to log2(gain) in Q10 */
239e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
240e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Find integer part  */
241e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	log_en_int_e = (log_en >> 10);
242e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
243e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Find fractional part */
244e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	log_en_int_m = (Word16) (log_en & 0x3ff);
245e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	log_en_int_m = shl(log_en_int_m, 5);
246e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
247e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Subtract 2 from log_en in Q9, i.e divide the gain by 2 (energy by 4) */
248e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Add 16 in order to have the result of pow2 in Q16 */
249e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	log_en_int_e = add(log_en_int_e, 16 - 1);
250e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
251e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	level32 = Pow2(log_en_int_e, log_en_int_m); /* Q16 */
252e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	exp0 = norm_l(level32);
253e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	level32 = (level32 << exp0);        /* level in Q31 */
254e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	exp0 = (15 - exp0);
255e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	level = extract_h(level32);            /* level in Q15 */
256e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
257e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* generate white noise vector */
258e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = 0; i < L_FRAME; i++)
259e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
260e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		exc2[i] = (Random(&(st->cng_seed)) >> 4);
261e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
262e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
263e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* gain = level / sqrt(ener) * sqrt(L_FRAME) */
264e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
265e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* energy of generated excitation */
266e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	ener32 = Dot_product12(exc2, exc2, L_FRAME, &exp);
267e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
268e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Isqrt_n(&ener32, &exp);
269e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
270e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	gain = extract_h(ener32);
271e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
272e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	gain = mult(level, gain);              /* gain in Q15 */
273e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
274e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	exp = add(exp0, exp);
275e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
276e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Multiply by sqrt(L_FRAME)=16, i.e. shift left by 4 */
277e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	exp += 4;
278e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
279e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = 0; i < L_FRAME; i++)
280e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
281e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		tmp = mult(exc2[i], gain);         /* Q0 * Q15 */
282b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		exc2[i] = shl(tmp, exp);
283e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
284e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
285e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	return 0;
286e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
287e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
288e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/**************************************************************************
289e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*
290e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Function    : dtx_buffer Purpose     : handles the DTX buffer
291e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*
292e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard**************************************************************************/
293e2e838afcf03e603a41a0455846eaf9614537c16Mans RullgardWord16 dtx_buffer(
294e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		dtx_encState * st,                    /* i/o : State struct                    */
295e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 isf_new[],                     /* i   : isf vector                      */
296e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word32 enr,                           /* i   : residual energy (in L_FRAME)    */
297e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 codec_mode
298e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		)
299e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
300e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 log_en;
301e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
302e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 log_en_e;
303e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 log_en_m;
304b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	st->hist_ptr = add(st->hist_ptr, 1);
305e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	if(st->hist_ptr == DTX_HIST_SIZE)
306e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
307e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		st->hist_ptr = 0;
308e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
309e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* copy lsp vector into buffer */
310e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Copy(isf_new, &st->isf_hist[st->hist_ptr * M], M);
311e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
312e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* log_en = (float)log10(enr*0.0059322)/(float)log10(2.0f);  */
313e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Log2(enr, &log_en_e, &log_en_m);
314e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
315e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* convert exponent and mantissa to Word16 Q7. Q7 is used to simplify averaging in dtx_enc */
316e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	log_en = shl(log_en_e, 7);             /* Q7 */
317e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	log_en = add(log_en, shr(log_en_m, 15 - 7));
318e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
319e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Find energy per sample by multiplying with 0.0059322, i.e subtract log2(1/0.0059322) = 7.39722 The
320e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 * constant 0.0059322 takes into account windowings and analysis length from autocorrelation
321e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	 * computations; 7.39722 in Q7 = 947  */
322e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Subtract 3 dB = 0.99658 in log2(E) = 127 in Q7. */
323e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* log_en = sub( log_en, 947 + en_adjust[codec_mode] ); */
324e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
325e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Find energy per sample (divide by L_FRAME=256), i.e subtract log2(256) = 8.0  (1024 in Q7) */
326e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Subtract 3 dB = 0.99658 in log2(E) = 127 in Q7. */
327e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
328e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	log_en = sub(log_en, add(1024, en_adjust[codec_mode]));
329e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
330e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Insert into the buffer */
331e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	st->log_en_hist[st->hist_ptr] = log_en;
332e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	return 0;
333e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
334e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
335e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/**************************************************************************
336e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*
337e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Function    : tx_dtx_handler Purpose     : adds extra speech hangover
338e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*                                            to analyze speech on
339e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*                                            the decoding side.
340e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard**************************************************************************/
341e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardvoid tx_dtx_handler(dtx_encState * st,     /* i/o : State struct           */
342e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 vad_flag,                      /* i   : vad decision           */
343e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 * usedMode                     /* i/o : mode changed or not    */
344e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		)
345e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
346e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
347e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* this state machine is in synch with the GSMEFR txDtx machine      */
348b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	st->decAnaElapsedCount = add(st->decAnaElapsedCount, 1);
349e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
350e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	if (vad_flag != 0)
351e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
352e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		st->dtxHangoverCount = DTX_HANG_CONST;
353e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	} else
354e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{                                      /* non-speech */
355e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		if (st->dtxHangoverCount == 0)
356e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{                                  /* out of decoder analysis hangover  */
357b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			st->decAnaElapsedCount = 0;
358b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			*usedMode = MRDTX;
359e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		} else
360e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{                                  /* in possible analysis hangover */
361e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			st->dtxHangoverCount = sub(st->dtxHangoverCount, 1);
362e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
363e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			/* decAnaElapsedCount + dtxHangoverCount < DTX_ELAPSED_FRAMES_THRESH */
364e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			if (sub(add(st->decAnaElapsedCount, st->dtxHangoverCount),
365e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard						DTX_ELAPSED_FRAMES_THRESH) < 0)
366e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			{
367e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				*usedMode = MRDTX;
368e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				/* if short time since decoder update, do not add extra HO */
369e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			}
370e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			/* else override VAD and stay in speech mode *usedMode and add extra hangover */
371e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
372e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
373e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
374e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	return;
375e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
376e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
377e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
378e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
379e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic void aver_isf_history(
380e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 isf_old[],
381e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 indices[],
382e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word32 isf_aver[]
383e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		)
384e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
385e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word32 i, j, k;
386e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 isf_tmp[2 * M];
387e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word32 L_tmp;
388e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
389e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Memorize in isf_tmp[][] the ISF vectors to be replaced by */
390e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* the median ISF vector prior to the averaging               */
391e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (k = 0; k < 2; k++)
392e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
393e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		if ((indices[k] + 1) != 0)
394e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
395e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			for (i = 0; i < M; i++)
396e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			{
397b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				isf_tmp[k * M + i] = isf_old[indices[k] * M + i];
398b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard				isf_old[indices[k] * M + i] = isf_old[indices[2] * M + i];
399e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			}
400e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
401e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
402e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
403e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Perform the ISF averaging */
404e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (j = 0; j < M; j++)
405e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
406b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		L_tmp = 0;
407e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
408e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		for (i = 0; i < DTX_HIST_SIZE; i++)
409e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
410e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			L_tmp = L_add(L_tmp, L_deposit_l(isf_old[i * M + j]));
411e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
412b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		isf_aver[j] = L_tmp;
413e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
414e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
415e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Retrieve from isf_tmp[][] the ISF vectors saved prior to averaging */
416e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (k = 0; k < 2; k++)
417e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
418e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		if ((indices[k] + 1) != 0)
419e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
420e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			for (i = 0; i < M; i++)
421e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			{
422e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard				isf_old[indices[k] * M + i] = isf_tmp[k * M + i];
423e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			}
424e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
425e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
426e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
427e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	return;
428e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
429e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
430e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic void find_frame_indices(
431e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 isf_old_tx[],
432e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 indices[],
433e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		dtx_encState * st
434e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		)
435e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
436e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word32 L_tmp, summin, summax, summax2nd;
437e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 i, j, tmp;
438e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 ptr;
439e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
440e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Remove the effect of the oldest frame from the column */
441e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* sum sumD[0..DTX_HIST_SIZE-1]. sumD[DTX_HIST_SIZE] is    */
442e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* not updated since it will be removed later.           */
443e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
444b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	tmp = DTX_HIST_SIZE_MIN_ONE;
445b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	j = -1;
446e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = 0; i < DTX_HIST_SIZE_MIN_ONE; i++)
447e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
448e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		j = add(j, tmp);
449b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		st->sumD[i] = L_sub(st->sumD[i], st->D[j]);
450e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		tmp = sub(tmp, 1);
451e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
452e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
453e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Shift the column sum sumD. The element sumD[DTX_HIST_SIZE-1]    */
454e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* corresponding to the oldest frame is removed. The sum of     */
455e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* the distances between the latest isf and other isfs, */
456e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* i.e. the element sumD[0], will be computed during this call. */
457e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Hence this element is initialized to zero.                   */
458e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
459e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = DTX_HIST_SIZE_MIN_ONE; i > 0; i--)
460e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
461b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		st->sumD[i] = st->sumD[i - 1];
462e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
463b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	st->sumD[0] = 0;
464e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
465e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Remove the oldest frame from the distance matrix.           */
466e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Note that the distance matrix is replaced by a one-         */
467e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* dimensional array to save static memory.                    */
468e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
469b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	tmp = 0;
470e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = 27; i >= 12; i = (Word16) (i - tmp))
471e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
472e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		tmp = add(tmp, 1);
473e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		for (j = tmp; j > 0; j--)
474e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
475b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			st->D[i - j + 1] = st->D[i - j - tmp];
476e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
477e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
478e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
479e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Compute the first column of the distance matrix D            */
480e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* (squared Euclidean distances from isf1[] to isf_old_tx[][]). */
481e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
482b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	ptr = st->hist_ptr;
483e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = 1; i < DTX_HIST_SIZE; i++)
484e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
485e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		/* Compute the distance between the latest isf and the other isfs. */
486e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		ptr = sub(ptr, 1);
487e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		if (ptr < 0)
488e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
489b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			ptr = DTX_HIST_SIZE_MIN_ONE;
490e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
491b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		L_tmp = 0;
492e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		for (j = 0; j < M; j++)
493e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
494e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			tmp = sub(isf_old_tx[st->hist_ptr * M + j], isf_old_tx[ptr * M + j]);
495e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard			L_tmp = L_mac(L_tmp, tmp, tmp);
496e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
497b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		st->D[i - 1] = L_tmp;
498e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
499e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		/* Update also the column sums. */
500b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		st->sumD[0] = L_add(st->sumD[0], st->D[i - 1]);
501b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		st->sumD[i] = L_add(st->sumD[i], st->D[i - 1]);
502e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
503e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
504e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Find the minimum and maximum distances */
505b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	summax = st->sumD[0];
506b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	summin = st->sumD[0];
507b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	indices[0] = 0;
508b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	indices[2] = 0;
509e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = 1; i < DTX_HIST_SIZE; i++)
510e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
511e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		if (L_sub(st->sumD[i], summax) > 0)
512e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
513b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			indices[0] = i;
514b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			summax = st->sumD[i];
515e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
516e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		if (L_sub(st->sumD[i], summin) < 0)
517e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
518b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			indices[2] = i;
519b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			summin = st->sumD[i];
520e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
521e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
522e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
523e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Find the second largest distance */
524b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	summax2nd = -2147483647L;
525b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	indices[1] = -1;
526e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = 0; i < DTX_HIST_SIZE; i++)
527e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
528e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		if ((L_sub(st->sumD[i], summax2nd) > 0) && (sub(i, indices[0]) != 0))
529e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
530b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			indices[1] = i;
531b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			summax2nd = st->sumD[i];
532e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
533e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
534e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
535e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = 0; i < 3; i++)
536e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
537b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		indices[i] = sub(st->hist_ptr, indices[i]);
538e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		if (indices[i] < 0)
539e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		{
540b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard			indices[i] = add(indices[i], DTX_HIST_SIZE);
541e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		}
542e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
543e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
544e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* If maximum distance/MED_THRESH is smaller than minimum distance */
545e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* then the median ISF vector replacement is not performed         */
546e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	tmp = norm_l(summax);
547e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	summax = (summax << tmp);
548e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	summin = (summin << tmp);
549e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	L_tmp = L_mult(voround(summax), INV_MED_THRESH);
550e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	if(L_tmp <= summin)
551e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
552b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		indices[0] = -1;
553e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
554e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* If second largest distance/MED_THRESH is smaller than     */
555e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* minimum distance then the median ISF vector replacement is    */
556e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* not performed                                                 */
557e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	summax2nd = L_shl(summax2nd, tmp);
558e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	L_tmp = L_mult(voround(summax2nd), INV_MED_THRESH);
559e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	if(L_tmp <= summin)
560e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
561b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		indices[1] = -1;
562e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
563e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	return;
564e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
565e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
566e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic Word16 dithering_control(
567e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		dtx_encState * st
568e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		)
569e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
570e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 tmp, mean, CN_dith, gain_diff;
571e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word32 i, ISF_diff;
572e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
573e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* determine how stationary the spectrum of background noise is */
574e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	ISF_diff = 0;
575e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = 0; i < 8; i++)
576e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
577e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		ISF_diff = L_add(ISF_diff, st->sumD[i]);
578e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
579e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	if ((ISF_diff >> 26) > 0)
580e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
581e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		CN_dith = 1;
582e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	} else
583e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
584e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		CN_dith = 0;
585e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
586e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
587e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* determine how stationary the energy of background noise is */
588e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	mean = 0;
589e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = 0; i < DTX_HIST_SIZE; i++)
590e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
591e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		mean = add(mean, st->log_en_hist[i]);
592e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
593e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	mean = (mean >> 3);
594e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	gain_diff = 0;
595e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = 0; i < DTX_HIST_SIZE; i++)
596e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
597e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		tmp = abs_s(sub(st->log_en_hist[i], mean));
598e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		gain_diff = add(gain_diff, tmp);
599e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
600e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	if (gain_diff > GAIN_THR)
601e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
602e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		CN_dith = 1;
603e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
604e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	return CN_dith;
605e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
606