1a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber/* ------------------------------------------------------------------
2a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber * Copyright (C) 1998-2009 PacketVideo
3a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber *
4a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber * you may not use this file except in compliance with the License.
6a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber * You may obtain a copy of the License at
7a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber *
8a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber *
10a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber * Unless required by applicable law or agreed to in writing, software
11a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber * express or implied.
14a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber * See the License for the specific language governing permissions
15a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber * and limitations under the License.
16a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber * -------------------------------------------------------------------
17a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber */
18a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber/****************************************************************************************
19a30d40083856cb4edd225faf8b488fab156e5976Andreas HuberPortions of this file are derived from the following 3GPP standard:
20a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
21a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    3GPP TS 26.173
22a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec
23a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    Available from http://www.3gpp.org
24a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
25a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber(C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
26a30d40083856cb4edd225faf8b488fab156e5976Andreas HuberPermission to distribute, modify and use this file under the standard license
27a30d40083856cb4edd225faf8b488fab156e5976Andreas Huberterms listed above has been obtained from the copyright holder.
28a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber****************************************************************************************/
29a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber/*
30a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber------------------------------------------------------------------------------
31a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
32a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
33a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
34a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber Filename: dtx_decoder_amr_wb.cpp
35a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
36a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     Date: 05/08/2007
37a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
38a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber------------------------------------------------------------------------------
39a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber REVISION HISTORY
40a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
41a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
42a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber Description:
43a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
44a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber------------------------------------------------------------------------------
45a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber INPUT AND OUTPUT DEFINITIONS
46a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
47a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
48a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber------------------------------------------------------------------------------
49a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber FUNCTION DESCRIPTION
50a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
51a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    DTX functions
52a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
53a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber------------------------------------------------------------------------------
54a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber REQUIREMENTS
55a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
56a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
57a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber------------------------------------------------------------------------------
58a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber REFERENCES
59a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
60a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber------------------------------------------------------------------------------
61a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber PSEUDO-CODE
62a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
63a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber------------------------------------------------------------------------------
64a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber*/
65a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
66a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
67a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber/*----------------------------------------------------------------------------
68a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber; INCLUDES
69a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber----------------------------------------------------------------------------*/
70a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
71a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber#include "pv_amr_wb_type_defs.h"
72a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber#include "pvamrwbdecoder_basic_op.h"
73a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber#include "pvamrwb_math_op.h"
74a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber#include "pvamrwbdecoder_cnst.h"
75a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber#include "pvamrwbdecoder_acelp.h"  /* prototype of functions    */
76a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber#include "get_amr_wb_bits.h"
77a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber#include "dtx.h"
78a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
79a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber/*----------------------------------------------------------------------------
80a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber; MACROS
81a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber; Define module specific macros here
82a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber----------------------------------------------------------------------------*/
83a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
84a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
85a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber/*----------------------------------------------------------------------------
86a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber; DEFINES
87a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber; Include all pre-processor statements here. Include conditional
88a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber; compile variables also.
89a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber----------------------------------------------------------------------------*/
90a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
91a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber/*----------------------------------------------------------------------------
92a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber; LOCAL FUNCTION DEFINITIONS
93a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber; Function Prototype declaration
94a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber----------------------------------------------------------------------------*/
95a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
96a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber/*----------------------------------------------------------------------------
97a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber; LOCAL STORE/BUFFER/POINTER DEFINITIONS
98a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber; Variable declaration - defined here and used outside this module
99a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber----------------------------------------------------------------------------*/
100a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
101a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber/*----------------------------------------------------------------------------
102a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber; EXTERNAL FUNCTION REFERENCES
103a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber; Declare functions defined elsewhere and referenced in this module
104a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber----------------------------------------------------------------------------*/
105a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
106a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber/*----------------------------------------------------------------------------
107a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
108a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber; Declare variables used in this module but defined elsewhere
109a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber----------------------------------------------------------------------------*/
110a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
111a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber/*----------------------------------------------------------------------------
112a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber; FUNCTION CODE
113a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber----------------------------------------------------------------------------*/
114a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber/*
115a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber * Function    : dtx_dec_amr_wb_reset
116a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber */
117a30d40083856cb4edd225faf8b488fab156e5976Andreas Huberint16 dtx_dec_amr_wb_reset(dtx_decState * st, const int16 isf_init[])
118a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber{
119a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int16 i;
120a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
121a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
122a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    if (st == (dtx_decState *) NULL)
123a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
124a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        /* dtx_dec_amr_wb_reset invalid parameter */
125a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        return (-1);
126a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
127a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    st->since_last_sid = 0;
128a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    st->true_sid_period_inv = (1 << 13);      /* 0.25 in Q15 */
129a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
130a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    st->log_en = 3500;
131a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    st->old_log_en = 3500;
132a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* low level noise for better performance in  DTX handover cases */
133a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
134a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    st->cng_seed = RANDOM_INITSEED;
135a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
136a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    st->hist_ptr = 0;
137a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
138a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* Init isf_hist[] and decoder log frame energy */
139a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    pv_memcpy((void *)st->isf, (void *)isf_init, M*sizeof(*isf_init));
140a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
141a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    pv_memcpy((void *)st->isf_old, (void *)isf_init, M*sizeof(*isf_init));
142a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
143a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    for (i = 0; i < DTX_HIST_SIZE; i++)
144a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
145a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        pv_memcpy((void *)&st->isf_hist[i * M], (void *)isf_init, M*sizeof(*isf_init));
146a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        st->log_en_hist[i] = st->log_en;
147a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
148a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
149a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    st->dtxHangoverCount = DTX_HANG_CONST;
150a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    st->decAnaElapsedCount = 32767;
151a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
152a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    st->sid_frame = 0;
153a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    st->valid_data = 0;
154a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    st->dtxHangoverAdded = 0;
155a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
156a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    st->dtxGlobalState = SPEECH;
157a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    st->data_updated = 0;
158a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
159a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    st->dither_seed = RANDOM_INITSEED;
160a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    st->CN_dith = 0;
161a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
162a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    return 0;
163a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber}
164a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
165a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
166a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber/*
167a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     Table of new SPD synthesis states
168a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
169a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber                           |     previous SPD_synthesis_state
170a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     Incoming              |
171a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     frame_type            | SPEECH       | DTX           | DTX_MUTE
172a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     ---------------------------------------------------------------
173a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     RX_SPEECH_GOOD ,      |              |               |
174a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     RX_SPEECH_PR_DEGRADED | SPEECH       | SPEECH        | SPEECH
175a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     ----------------------------------------------------------------
176a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     RX_SPEECH_BAD,        | SPEECH       | DTX           | DTX_MUTE
177a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     ----------------------------------------------------------------
178a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     RX_SID_FIRST,         | DTX          | DTX/(DTX_MUTE)| DTX_MUTE
179a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     ----------------------------------------------------------------
180a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     RX_SID_UPDATE,        | DTX          | DTX           | DTX
181a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     ----------------------------------------------------------------
182a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     RX_SID_BAD,           | DTX          | DTX/(DTX_MUTE)| DTX_MUTE
183a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     ----------------------------------------------------------------
184a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     RX_NO_DATA,           | SPEECH       | DTX/(DTX_MUTE)| DTX_MUTE
185a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     RX_SPARE              |(class2 garb.)|               |
186a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     ----------------------------------------------------------------
187a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber*/
188a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
189a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber/*----------------------------------------------------------------------------
190a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber; FUNCTION CODE
191a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber----------------------------------------------------------------------------*/
192a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
193a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber/*
194a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber * Function    : dtx_dec_amr_wb
195a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber */
196a30d40083856cb4edd225faf8b488fab156e5976Andreas Huberint16 dtx_dec_amr_wb(
197a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    dtx_decState * st,                    /* i/o : State struct         */
198a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int16 * exc2,                        /* o   : CN excitation        */
199a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int16 new_state,                     /* i   : New DTX state        */
200a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int16 isf[],                         /* o   : CN ISF vector        */
201a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int16 ** prms
202a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber)
203a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber{
204a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int16 log_en_index;
205a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int16 ind[7];
206a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int16 i, j;
207a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int16 int_fac;
208a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int16 gain;
209a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
210a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int32 L_isf[M], L_log_en_int, level32, ener32;
211a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int16 ptr;
212a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int16 tmp_int_length;
213a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int16 tmp, exp, exp0, log_en_int_e, log_en_int_m, level;
214a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
215a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* This function is called if synthesis state is not SPEECH the globally passed  inputs to this function
216a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     * are st->sid_frame st->valid_data st->dtxHangoverAdded new_state  (SPEECH, DTX, DTX_MUTE) */
217a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
218a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    if ((st->dtxHangoverAdded != 0) &&
219a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            (st->sid_frame != 0))
220a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
221a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        /* sid_first after dtx hangover period */
222a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        /* or sid_upd after dtxhangover        */
223a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
224a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        /* consider  twice the last frame */
225a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        ptr = st->hist_ptr + 1;
226a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
227a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        if (ptr == DTX_HIST_SIZE)
228a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            ptr = 0;
229a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
230a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        pv_memcpy((void *)&st->isf_hist[ptr * M], (void *)&st->isf_hist[st->hist_ptr * M], M*sizeof(*st->isf_hist));
231a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
232a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        st->log_en_hist[ptr] = st->log_en_hist[st->hist_ptr];
233a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
234a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        /* compute mean log energy and isf from decoded signal (SID_FIRST) */
235a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        st->log_en = 0;
236a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        for (i = 0; i < M; i++)
237a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        {
238a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            L_isf[i] = 0;
239a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        }
240a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
241a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        /* average energy and isf */
242a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        for (i = 0; i < DTX_HIST_SIZE; i++)
243a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        {
244a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            /* Division by DTX_HIST_SIZE = 8 has been done in dtx_buffer log_en is in Q10 */
245a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            st->log_en = add_int16(st->log_en, st->log_en_hist[i]);
246a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
247a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            for (j = 0; j < M; j++)
248a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            {
249a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber                L_isf[j] = add_int32(L_isf[j], (int32)(st->isf_hist[i * M + j]));
250a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            }
251a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        }
252a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
253a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        /* st->log_en in Q9 */
254a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        st->log_en >>=  1;
255a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
256a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        /* Add 2 in Q9, in order to have only positive values for Pow2 */
257a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        /* this value is subtracted back after Pow2 function */
258a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        st->log_en += 1024;
259a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
260a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        if (st->log_en < 0)
261a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            st->log_en = 0;
262a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
263a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        for (j = 0; j < M; j++)
264a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        {
265a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            st->isf[j] = (int16)(L_isf[j] >> 3);  /* divide by 8 */
266a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        }
267a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
268a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
269a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
270a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    if (st->sid_frame != 0)
271a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
272a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        /* Set old SID parameters, always shift */
273a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        /* even if there is no new valid_data   */
274a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
275a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        pv_memcpy((void *)st->isf_old, (void *)st->isf, M*sizeof(*st->isf));
276a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
277a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        st->old_log_en = st->log_en;
278a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
279a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        if (st->valid_data != 0)           /* new data available (no CRC) */
280a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        {
281a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            /* st->true_sid_period_inv = 1.0f/st->since_last_sid; */
282a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            /* Compute interpolation factor, since the division only works * for values of since_last_sid <
283a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber             * 32 we have to limit the      * interpolation to 32 frames                                  */
284a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            tmp_int_length = st->since_last_sid;
285a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
286a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
287a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            if (tmp_int_length > 32)
288a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            {
289a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber                tmp_int_length = 32;
290a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            }
291a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
292a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            if (tmp_int_length >= 2)
293a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            {
294a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber                st->true_sid_period_inv = div_16by16(1 << 10, shl_int16(tmp_int_length, 10));
295a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            }
296a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            else
297a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            {
298a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber                st->true_sid_period_inv = 1 << 14;      /* 0.5 it Q15 */
299a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            }
300a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
301a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            ind[0] = Serial_parm(6, prms);
302a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            ind[1] = Serial_parm(6, prms);
303a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            ind[2] = Serial_parm(6, prms);
304a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            ind[3] = Serial_parm(5, prms);
305a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            ind[4] = Serial_parm(5, prms);
306a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
307a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            Disf_ns(ind, st->isf);
308a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
309a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            log_en_index = Serial_parm(6, prms);
310a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
311a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            /* read background noise stationarity information */
312a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            st->CN_dith = Serial_parm_1bit(prms);
313a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
314a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            /* st->log_en = (float)log_en_index / 2.625 - 2.0;  */
315a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            /* log2(E) in Q9 (log2(E) lies in between -2:22) */
316a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            st->log_en = shl_int16(log_en_index, 15 - 6);
317a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
318a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            /* Divide by 2.625  */
319a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            st->log_en = mult_int16(st->log_en, 12483);
320a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            /* Subtract 2 in Q9 is done later, after Pow2 function  */
321a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
322a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            /* no interpolation at startup after coder reset        */
323a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            /* or when SID_UPD has been received right after SPEECH */
324a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
325a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            if ((st->data_updated == 0) || (st->dtxGlobalState == SPEECH))
326a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            {
327a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber                pv_memcpy((void *)st->isf_old, (void *)st->isf, M*sizeof(*st->isf));
328a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
329a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber                st->old_log_en = st->log_en;
330a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            }
331a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        }                                  /* endif valid_data */
332a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }                                      /* endif sid_frame */
333a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
334a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
335a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    if ((st->sid_frame != 0) && (st->valid_data != 0))
336a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
337a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        st->since_last_sid = 0;
338a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
339a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* Interpolate SID info */
340a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int_fac = shl_int16(st->since_last_sid, 10); /* Q10 */
341a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int_fac = mult_int16(int_fac, st->true_sid_period_inv);   /* Q10 * Q15 -> Q10 */
342a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
343a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* Maximize to 1.0 in Q10 */
344a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
345a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    if (int_fac > 1024)
346a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
347a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        int_fac = 1024;
348a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
349a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int_fac = shl_int16(int_fac, 4);             /* Q10 -> Q14 */
350a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
351a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    L_log_en_int = mul_16by16_to_int32(int_fac, st->log_en); /* Q14 * Q9 -> Q24 */
352a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
353a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    for (i = 0; i < M; i++)
354a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
355a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        isf[i] = mult_int16(int_fac, st->isf[i]);/* Q14 * Q15 -> Q14 */
356a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
357a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
358a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int_fac = 16384 - int_fac;         /* 1-k in Q14 */
359a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
360a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* ( Q14 * Q9 -> Q24 ) + Q24 -> Q24 */
361a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    L_log_en_int = mac_16by16_to_int32(L_log_en_int, int_fac, st->old_log_en);
362a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
363a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    for (i = 0; i < M; i++)
364a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
365a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        /* Q14 + (Q14 * Q15 -> Q14) -> Q14 */
366a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        isf[i] = add_int16(isf[i], mult_int16(int_fac, st->isf_old[i]));
367a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        isf[i] = shl_int16(isf[i], 1);           /* Q14 -> Q15 */
368a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
369a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
370a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* If background noise is non-stationary, insert comfort noise dithering */
371a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    if (st->CN_dith != 0)
372a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
373a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        CN_dithering(isf, &L_log_en_int, &st->dither_seed);
374a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
375a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* L_log_en_int corresponds to log2(E)+2 in Q24, i.e log2(gain)+1 in Q25 */
376a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* Q25 -> Q16 */
377a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    L_log_en_int >>= 9;
378a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
379a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* Find integer part  */
380a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    log_en_int_e = extract_h(L_log_en_int);
381a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
382a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* Find fractional part */
383a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    log_en_int_m = (int16)(sub_int32(L_log_en_int, L_deposit_h(log_en_int_e)) >> 1);
384a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
385a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* Subtract 2 from L_log_en_int in Q9, i.e divide the gain by 2 (energy by 4) */
386a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* Add 16 in order to have the result of pow2 in Q16 */
387a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    log_en_int_e += 15;
388a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
389a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* level = (float)( pow( 2.0f, log_en ) );  */
390a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    level32 = power_of_2(log_en_int_e, log_en_int_m); /* Q16 */
391a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
392a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    exp0 = normalize_amr_wb(level32);
393a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    level32 <<= exp0;        /* level in Q31 */
394a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    exp0 = 15 - exp0;
395a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    level = (int16)(level32 >> 16);          /* level in Q15 */
396a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
397a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* generate white noise vector */
398a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    for (i = 0; i < L_FRAME; i++)
399a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
400a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        exc2[i] = noise_gen_amrwb(&(st->cng_seed)) >> 4;
401a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
402a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
403a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* gain = level / sqrt(ener) * sqrt(L_FRAME) */
404a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
405a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* energy of generated excitation */
406a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    ener32 = Dot_product12(exc2, exc2, L_FRAME, &exp);
407a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
408a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    one_ov_sqrt_norm(&ener32, &exp);
409a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
410a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    gain = extract_h(ener32);
411a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
412a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    gain = mult_int16(level, gain);              /* gain in Q15 */
413a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
414a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    exp += exp0;
415a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
416a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* Multiply by sqrt(L_FRAME)=16, i.e. shift left by 4 */
417a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    exp += 4;
418a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
419a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    for (i = 0; i < L_FRAME; i++)
420a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
421a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        tmp = mult_int16(exc2[i], gain);         /* Q0 * Q15 */
422a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        exc2[i] = shl_int16(tmp, exp);
423a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
424a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
425a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
426a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    if (new_state == DTX_MUTE)
427a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
428a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        /* mute comfort noise as it has been quite a long time since last SID update  was performed                            */
429a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
430a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        tmp_int_length = st->since_last_sid;
431a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
432a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        if (tmp_int_length > 32)
433a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        {
434a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            tmp_int_length = 32;
435a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        }
436a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
437a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        st->true_sid_period_inv = div_16by16(1 << 10, shl_int16(tmp_int_length, 10));
438a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
439a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        st->since_last_sid = 0;
440a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        st->old_log_en = st->log_en;
441a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        /* subtract 1/8 in Q9 (energy), i.e -3/8 dB */
442a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        st->log_en -= 64;
443a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
444a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* reset interpolation length timer if data has been updated.        */
445a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
446a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    if ((st->sid_frame != 0) &&
447a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            ((st->valid_data != 0) ||
448a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber             ((st->valid_data == 0) && (st->dtxHangoverAdded) != 0)))
449a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
450a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        st->since_last_sid = 0;
451a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        st->data_updated = 1;
452a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
453a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    return 0;
454a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber}
455a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
456a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
457a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber/*----------------------------------------------------------------------------
458a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber; FUNCTION CODE
459a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber----------------------------------------------------------------------------*/
460a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
461a30d40083856cb4edd225faf8b488fab156e5976Andreas Hubervoid dtx_dec_amr_wb_activity_update(
462a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    dtx_decState * st,
463a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int16 isf[],
464a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int16 exc[])
465a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber{
466a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int16 i;
467a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
468a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int32 L_frame_en;
469a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int16 log_en_e, log_en_m, log_en;
470a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
471a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
472a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    st->hist_ptr++;
473a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
474a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    if (st->hist_ptr == DTX_HIST_SIZE)
475a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
476a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        st->hist_ptr = 0;
477a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
478a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    pv_memcpy((void *)&st->isf_hist[st->hist_ptr * M], (void *)isf, M*sizeof(*isf));
479a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
480a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
481a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* compute log energy based on excitation frame energy in Q0 */
482a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    L_frame_en = 0;
483a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    for (i = 0; i < L_FRAME; i++)
484a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
485a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        L_frame_en = mac_16by16_to_int32(L_frame_en, exc[i], exc[i]);
486a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
487a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    L_frame_en >>= 1;
488a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
489a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* log_en = (float)log10(L_frame_en/(float)L_FRAME)/(float)log10(2.0f); */
490a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    amrwb_log_2(L_frame_en, &log_en_e, &log_en_m);
491a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
492a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* convert exponent and mantissa to int16 Q7. Q7 is used to simplify averaging in dtx_enc */
493a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    log_en = shl_int16(log_en_e, 7);             /* Q7 */
494a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    log_en += log_en_m >> 8;
495a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
496a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* Divide by L_FRAME = 256, i.e subtract 8 in Q7 = 1024 */
497a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    log_en -= 1024;
498a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
499a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* insert into log energy buffer */
500a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    st->log_en_hist[st->hist_ptr] = log_en;
501a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
502a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    return;
503a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber}
504a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
505a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
506a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber/*
507a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     Table of new SPD synthesis states
508a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
509a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber                           |     previous SPD_synthesis_state
510a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     Incoming              |
511a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     frame_type            | SPEECH       | DTX           | DTX_MUTE
512a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     ---------------------------------------------------------------
513a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     RX_SPEECH_GOOD ,      |              |               |
514a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     RX_SPEECH_PR_DEGRADED | SPEECH       | SPEECH        | SPEECH
515a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     ----------------------------------------------------------------
516a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     RX_SPEECH_BAD,        | SPEECH       | DTX           | DTX_MUTE
517a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     ----------------------------------------------------------------
518a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     RX_SID_FIRST,         | DTX          | DTX/(DTX_MUTE)| DTX_MUTE
519a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     ----------------------------------------------------------------
520a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     RX_SID_UPDATE,        | DTX          | DTX           | DTX
521a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     ----------------------------------------------------------------
522a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     RX_SID_BAD,           | DTX          | DTX/(DTX_MUTE)| DTX_MUTE
523a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     ----------------------------------------------------------------
524a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     RX_NO_DATA,           | SPEECH       | DTX/(DTX_MUTE)| DTX_MUTE
525a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     RX_SPARE              |(class2 garb.)|               |
526a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     ----------------------------------------------------------------
527a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber*/
528a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
529a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
530a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber/*----------------------------------------------------------------------------
531a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber; FUNCTION CODE
532a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber----------------------------------------------------------------------------*/
533a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
534a30d40083856cb4edd225faf8b488fab156e5976Andreas Huberint16 rx_amr_wb_dtx_handler(
535a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    dtx_decState * st,                    /* i/o : State struct     */
536a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int16 frame_type                     /* i   : Frame type       */
537a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber)
538a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber{
539a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int16 newState;
540a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int16 encState;
541a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
542a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* DTX if SID frame or previously in DTX{_MUTE} and (NO_RX OR BAD_SPEECH) */
543a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
544a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
545a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
546a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    if ((frame_type == RX_SID_FIRST)  ||
547a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            (frame_type == RX_SID_UPDATE) ||
548a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            (frame_type == RX_SID_BAD)    ||
549a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            (((st->dtxGlobalState == DTX) ||
550a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber              (st->dtxGlobalState == DTX_MUTE)) &&
551a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber             ((frame_type == RX_NO_DATA)    ||
552a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber              (frame_type == RX_SPEECH_BAD) ||
553a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber              (frame_type == RX_SPEECH_LOST))))
554a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
555a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        newState = DTX;
556a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
557a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        /* stay in mute for these input types */
558a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
559a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        if ((st->dtxGlobalState == DTX_MUTE) &&
560a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber                ((frame_type == RX_SID_BAD) ||
561a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber                 (frame_type == RX_SID_FIRST) ||
562a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber                 (frame_type == RX_SPEECH_LOST) ||
563a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber                 (frame_type == RX_NO_DATA)))
564a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        {
565a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            newState = DTX_MUTE;
566a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        }
567a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        /* evaluate if noise parameters are too old                     */
568a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        /* since_last_sid is reset when CN parameters have been updated */
569a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        st->since_last_sid = add_int16(st->since_last_sid, 1);
570a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
571a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        /* no update of sid parameters in DTX for a long while */
572a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
573a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        if (st->since_last_sid > DTX_MAX_EMPTY_THRESH)
574a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        {
575a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            newState = DTX_MUTE;
576a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        }
577a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
578a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    else
579a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
580a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        newState = SPEECH;
581a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        st->since_last_sid = 0;
582a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
583a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
584a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* reset the decAnaElapsed Counter when receiving CNI data the first time, to robustify counter missmatch
585a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber     * after handover this might delay the bwd CNI analysis in the new decoder slightly. */
586a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
587a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    if ((st->data_updated == 0) &&
588a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            (frame_type == RX_SID_UPDATE))
589a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
590a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        st->decAnaElapsedCount = 0;
591a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
592a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* update the SPE-SPD DTX hangover synchronization */
593a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* to know when SPE has added dtx hangover         */
594a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    st->decAnaElapsedCount = add_int16(st->decAnaElapsedCount, 1);
595a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    st->dtxHangoverAdded = 0;
596a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
597a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
598a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    if ((frame_type == RX_SID_FIRST) ||
599a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            (frame_type == RX_SID_UPDATE) ||
600a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            (frame_type == RX_SID_BAD) ||
601a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            (frame_type == RX_NO_DATA))
602a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
603a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        encState = DTX;
604a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
605a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    else
606a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
607a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        encState = SPEECH;
608a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
609a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
610a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
611a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    if (encState == SPEECH)
612a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
613a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        st->dtxHangoverCount = DTX_HANG_CONST;
614a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
615a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    else
616a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
617a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
618a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        if (st->decAnaElapsedCount > DTX_ELAPSED_FRAMES_THRESH)
619a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        {
620a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            st->dtxHangoverAdded = 1;
621a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            st->decAnaElapsedCount = 0;
622a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            st->dtxHangoverCount = 0;
623a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        }
624a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        else if (st->dtxHangoverCount == 0)
625a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        {
626a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            st->decAnaElapsedCount = 0;
627a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        }
628a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        else
629a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        {
630a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            st->dtxHangoverCount--;
631a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        }
632a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
633a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
634a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    if (newState != SPEECH)
635a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
636a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        /* DTX or DTX_MUTE CN data is not in a first SID, first SIDs are marked as SID_BAD but will do
637a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber         * backwards analysis if a hangover period has been added according to the state machine above */
638a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
639a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        st->sid_frame = 0;
640a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        st->valid_data = 0;
641a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
642a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
643a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        if (frame_type == RX_SID_FIRST)
644a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        {
645a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            st->sid_frame = 1;
646a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        }
647a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        else if (frame_type == RX_SID_UPDATE)
648a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        {
649a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            st->sid_frame = 1;
650a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            st->valid_data = 1;
651a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        }
652a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        else if (frame_type == RX_SID_BAD)
653a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        {
654a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            st->sid_frame = 1;
655a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            st->dtxHangoverAdded = 0;      /* use old data */
656a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        }
657a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
658a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    return newState;
659a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* newState is used by both SPEECH AND DTX synthesis routines */
660a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber}
661a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
662a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
663a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber/*----------------------------------------------------------------------------
664a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber; FUNCTION CODE
665a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber----------------------------------------------------------------------------*/
666a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
667a30d40083856cb4edd225faf8b488fab156e5976Andreas Hubervoid aver_isf_history(
668a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int16 isf_old[],
669a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int16 indices[],
670a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int32 isf_aver[]
671a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber)
672a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber{
673a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int16 i, j, k;
674a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int16 isf_tmp[2 * M];
675a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int32 L_tmp;
676a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
677a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* Memorize in isf_tmp[][] the ISF vectors to be replaced by */
678a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* the median ISF vector prior to the averaging               */
679a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    for (k = 0; k < 2; k++)
680a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
681a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
682a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        if (indices[k] + 1 != 0)
683a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        {
684a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            for (i = 0; i < M; i++)
685a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            {
686a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber                isf_tmp[k * M + i] = isf_old[indices[k] * M + i];
687a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber                isf_old[indices[k] * M + i] = isf_old[indices[2] * M + i];
688a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            }
689a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        }
690a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
691a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
692a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* Perform the ISF averaging */
693a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    for (j = 0; j < M; j++)
694a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
695a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        L_tmp = 0;
696a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
697a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        for (i = 0; i < DTX_HIST_SIZE; i++)
698a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        {
699a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            L_tmp = add_int32(L_tmp, (int32)(isf_old[i * M + j]));
700a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        }
701a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        isf_aver[j] = L_tmp;
702a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
703a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
704a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* Retrieve from isf_tmp[][] the ISF vectors saved prior to averaging */
705a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    for (k = 0; k < 2; k++)
706a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
707a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
708a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        if (indices[k] + 1 != 0)
709a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        {
710a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            for (i = 0; i < M; i++)
711a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            {
712a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber                isf_old[indices[k] * M + i] = isf_tmp[k * M + i];
713a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            }
714a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        }
715a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
716a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
717a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    return;
718a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber}
719a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
720a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
721a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber/*----------------------------------------------------------------------------
722a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber; FUNCTION CODE
723a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber----------------------------------------------------------------------------*/
724a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
725a30d40083856cb4edd225faf8b488fab156e5976Andreas Hubervoid find_frame_indices(
726a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int16 isf_old_tx[],
727a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int16 indices[],
728a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    dtx_encState * st
729a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber)
730a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber{
731a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int32 L_tmp, summin, summax, summax2nd;
732a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int16 i, j, tmp;
733a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int16 ptr;
734a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
735a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* Remove the effect of the oldest frame from the column */
736a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* sum sumD[0..DTX_HIST_SIZE-1]. sumD[DTX_HIST_SIZE] is    */
737a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* not updated since it will be removed later.           */
738a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
739a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    tmp = DTX_HIST_SIZE_MIN_ONE;
740a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    j = -1;
741a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    for (i = 0; i < DTX_HIST_SIZE_MIN_ONE; i++)
742a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
743a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        j += tmp;
744a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        st->sumD[i] = sub_int32(st->sumD[i], st->D[j]);
745a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        tmp--;
746a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
747a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
748a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* Shift the column sum sumD. The element sumD[DTX_HIST_SIZE-1]    */
749a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* corresponding to the oldest frame is removed. The sum of     */
750a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* the distances between the latest isf and other isfs, */
751a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* i.e. the element sumD[0], will be computed during this call. */
752a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* Hence this element is initialized to zero.                   */
753a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
754a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    for (i = DTX_HIST_SIZE_MIN_ONE; i > 0; i--)
755a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
756a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        st->sumD[i] = st->sumD[i - 1];
757a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
758a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    st->sumD[0] = 0;
759a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
760a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* Remove the oldest frame from the distance matrix.           */
761a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* Note that the distance matrix is replaced by a one-         */
762a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* dimensional array to save static memory.                    */
763a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
764a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    tmp = 0;
765a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    for (i = 27; i >= 12; i -= tmp)
766a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
767a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        tmp++;
768a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        for (j = tmp; j > 0; j--)
769a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        {
770a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            st->D[i - j + 1] = st->D[i - j - tmp];
771a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        }
772a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
773a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
774a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* Compute the first column of the distance matrix D            */
775a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* (squared Euclidean distances from isf1[] to isf_old_tx[][]). */
776a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
777a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    ptr = st->hist_ptr;
778a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    for (i = 1; i < DTX_HIST_SIZE; i++)
779a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
780a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        /* Compute the distance between the latest isf and the other isfs. */
781a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        ptr--;
782a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
783a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        if (ptr < 0)
784a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        {
785a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            ptr = DTX_HIST_SIZE_MIN_ONE;
786a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        }
787a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        L_tmp = 0;
788a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        for (j = 0; j < M; j++)
789a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        {
790a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            tmp = sub_int16(isf_old_tx[st->hist_ptr * M + j], isf_old_tx[ptr * M + j]);
791a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            L_tmp = mac_16by16_to_int32(L_tmp, tmp, tmp);
792a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        }
793a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        st->D[i - 1] = L_tmp;
794a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
795a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        /* Update also the column sums. */
796a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        st->sumD[0] = add_int32(st->sumD[0], st->D[i - 1]);
797a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        st->sumD[i] = add_int32(st->sumD[i], st->D[i - 1]);
798a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
799a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
800a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* Find the minimum and maximum distances */
801a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    summax = st->sumD[0];
802a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    summin = st->sumD[0];
803a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    indices[0] = 0;
804a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    indices[2] = 0;
805a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    for (i = 1; i < DTX_HIST_SIZE; i++)
806a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
807a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
808a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        if (st->sumD[i] > summax)
809a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        {
810a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            indices[0] = i;
811a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            summax = st->sumD[i];
812a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        }
813a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
814a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        if (st->sumD[i] < summin)
815a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        {
816a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            indices[2] = i;
817a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            summin = st->sumD[i];
818a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        }
819a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
820a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
821a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* Find the second largest distance */
822a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    summax2nd = -2147483647L;
823a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    indices[1] = -1;
824a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    for (i = 0; i < DTX_HIST_SIZE; i++)
825a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
826a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
827a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        if ((st->sumD[i] > summax2nd) && (i != indices[0]))
828a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        {
829a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            indices[1] = i;
830a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            summax2nd = st->sumD[i];
831a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        }
832a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
833a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
834a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    for (i = 0; i < 3; i++)
835a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
836a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        indices[i] = sub_int16(st->hist_ptr, indices[i]);
837a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
838a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        if (indices[i] < 0)
839a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        {
840a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            indices[i] = add_int16(indices[i], DTX_HIST_SIZE);
841a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        }
842a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
843a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
844a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* If maximum distance/MED_THRESH is smaller than minimum distance */
845a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* then the median ISF vector replacement is not performed         */
846a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    tmp = normalize_amr_wb(summax);
847a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    summax <<= tmp;
848a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    summin <<= tmp;
849a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    L_tmp = mul_16by16_to_int32(amr_wb_round(summax), INV_MED_THRESH);
850a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
851a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    if (L_tmp <= summin)
852a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
853a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        indices[0] = -1;
854a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
855a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* If second largest distance/MED_THRESH is smaller than     */
856a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* minimum distance then the median ISF vector replacement is    */
857a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* not performed                                                 */
858a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    summax2nd = shl_int32(summax2nd, tmp);
859a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    L_tmp = mul_16by16_to_int32(amr_wb_round(summax2nd), INV_MED_THRESH);
860a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
861a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    if (L_tmp <= summin)
862a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
863a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        indices[1] = -1;
864a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
865a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    return;
866a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber}
867a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
868a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
869a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber/*----------------------------------------------------------------------------
870a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber; FUNCTION CODE
871a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber----------------------------------------------------------------------------*/
872a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
873a30d40083856cb4edd225faf8b488fab156e5976Andreas Huberint16 dithering_control(dtx_encState * st)
874a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber{
875a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int16 i, tmp, mean, CN_dith, gain_diff;
876a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int32 ISF_diff;
877a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
878a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* determine how stationary the spectrum of background noise is */
879a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    ISF_diff = 0;
880a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    for (i = 0; i < 8; i++)
881a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
882a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        ISF_diff = add_int32(ISF_diff, st->sumD[i]);
883a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
884a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    if ((ISF_diff >> 26) > 0)
885a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
886a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        CN_dith = 1;
887a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
888a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    else
889a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
890a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        CN_dith = 0;
891a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
892a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
893a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* determine how stationary the energy of background noise is */
894a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    mean = 0;
895a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    for (i = 0; i < DTX_HIST_SIZE; i++)
896a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
897a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        mean = add_int16(mean, st->log_en_hist[i]);
898a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
899a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    mean >>= 3;
900a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    gain_diff = 0;
901a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    for (i = 0; i < DTX_HIST_SIZE; i++)
902a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
903a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        tmp = sub_int16(st->log_en_hist[i], mean);
904a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        tmp = tmp - (tmp < 0);
905a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
906a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        gain_diff += tmp ^(tmp >> 15);    /*  tmp ^sign(tmp)  */;
907a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
908a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    if (gain_diff > GAIN_THR)
909a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
910a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        CN_dith = 1;
911a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
912a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    return CN_dith;
913a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber}
914a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
915a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
916a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber/*----------------------------------------------------------------------------
917a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber; FUNCTION CODE
918a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber----------------------------------------------------------------------------*/
919a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
920a30d40083856cb4edd225faf8b488fab156e5976Andreas Hubervoid CN_dithering(
921a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int16 isf[M],
922a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int32 * L_log_en_int,
923a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int16 * dither_seed
924a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber)
925a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber{
926a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int16 temp, temp1, i, dither_fac, rand_dith;
927a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    int16 rand_dith2;
928a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
929a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* Insert comfort noise dithering for energy parameter */
930a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    rand_dith = noise_gen_amrwb(dither_seed) >> 1;
931a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    rand_dith2 = noise_gen_amrwb(dither_seed) >> 1;
932a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    rand_dith += rand_dith2;
933a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    *L_log_en_int = add_int32(*L_log_en_int, mul_16by16_to_int32(rand_dith, GAIN_FACTOR));
934a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
935a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    if (*L_log_en_int < 0)
936a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
937a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        *L_log_en_int = 0;
938a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
939a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* Insert comfort noise dithering for spectral parameters (ISF-vector) */
940a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    dither_fac = ISF_FACTOR_LOW;
941a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
942a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    rand_dith = noise_gen_amrwb(dither_seed) >> 1;
943a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    rand_dith2 = noise_gen_amrwb(dither_seed) >> 1;
944a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    rand_dith +=  rand_dith2;
945a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    temp = add_int16(isf[0], mult_int16_r(rand_dith, dither_fac));
946a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
947a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* Make sure that isf[0] will not get negative values */
948a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    if (temp < ISF_GAP)
949a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
950a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        isf[0] = ISF_GAP;
951a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
952a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    else
953a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
954a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        isf[0] = temp;
955a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
956a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
957a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    for (i = 1; i < M - 1; i++)
958a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
959a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        dither_fac = add_int16(dither_fac, ISF_FACTOR_STEP);
960a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
961a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        rand_dith = noise_gen_amrwb(dither_seed) >> 1;
962a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        rand_dith2 = noise_gen_amrwb(dither_seed) >> 1;
963a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        rand_dith +=  rand_dith2;
964a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        temp = add_int16(isf[i], mult_int16_r(rand_dith, dither_fac));
965a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        temp1 = sub_int16(temp, isf[i - 1]);
966a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
967a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        /* Make sure that isf spacing remains at least ISF_DITH_GAP Hz */
968a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        if (temp1 < ISF_DITH_GAP)
969a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        {
970a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            isf[i] = isf[i - 1] + ISF_DITH_GAP;
971a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        }
972a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        else
973a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        {
974a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber            isf[i] = temp;
975a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        }
976a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
977a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber
978a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    /* Make sure that isf[M-2] will not get values above 16384 */
979a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    if (isf[M - 2] > 16384)
980a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    {
981a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber        isf[M - 2] = 16384;
982a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    }
983a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber    return;
984a30d40083856cb4edd225faf8b488fab156e5976Andreas Huber}
985