Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2026 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
4 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
5 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
6 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
7 : contributors to this repository. All Rights Reserved.
8 :
9 : This software is protected by copyright law and by international treaties.
10 : The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
11 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
12 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
13 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
14 : contributors to this repository retain full ownership rights in their respective contributions in
15 : the software. This notice grants no license of any kind, including but not limited to patent
16 : license, nor is any license granted by implication, estoppel or otherwise.
17 :
18 : Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
19 : contributions.
20 :
21 : This software is provided "AS IS", without any express or implied warranties. The software is in the
22 : development stage. It is intended exclusively for experts who have experience with such software and
23 : solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
24 : and fitness for a particular purpose are hereby disclaimed and excluded.
25 :
26 : Any dispute, controversy or claim arising under or in relation to providing this software shall be
27 : submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
28 : accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
29 : the United Nations Convention on Contracts on the International Sales of Goods.
30 :
31 : *******************************************************************************************************/
32 :
33 : /*====================================================================================
34 : EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
35 : ====================================================================================*/
36 :
37 : #include <stdint.h>
38 : #include "options.h"
39 : #ifdef DEBUGGING
40 : #include "debug.h"
41 : #endif
42 : #include <math.h>
43 : #include "cnst.h"
44 : #include "rom_enc.h"
45 : #include "rom_com.h"
46 : #include "prot.h"
47 : #include "wmc_auto.h"
48 :
49 : /*---------------------------------------------------------------------*
50 : * Local constants
51 : *---------------------------------------------------------------------*/
52 :
53 : #define MAX_DELTA_CNG 1
54 : #define ENER_MID_DEAD_ZONE 0.01 /* dead-zone width around mid points between quantization levels */
55 :
56 : /*---------------------------------------------------------------------*
57 : * Local function prototypes
58 : *---------------------------------------------------------------------*/
59 :
60 : static int16_t shb_DTX( Encoder_State *st, const float *shb_speech, const float *syn_12k8_16k );
61 :
62 : static void shb_CNG_encod( Encoder_State *st, const int16_t update );
63 :
64 :
65 : /*---------------------------------------------------------------------*
66 : * CNG_enc()
67 : *
68 : * Confort noise generation for the coder
69 : *---------------------------------------------------------------------*/
70 :
71 2548 : void CNG_enc(
72 : Encoder_State *st, /* i/o: State structure */
73 : float Aq[], /* o : LP coefficients */
74 : const float *speech, /* i : pointer to current frame input speech buffer */
75 : #ifndef ALIGN_ACELP_CORE
76 : float enr, /* i : residual energy from Levinson-Durbin */
77 : #endif
78 : const float *lsp_mid, /* i : mid frame LSPs */
79 : float *lsp_new, /* i/o: current frame ISPs */
80 : float *lsf_new, /* i/o: current frame ISFs */
81 : int16_t *allow_cn_step, /* o : allow CN step */
82 : float *q_env,
83 : int16_t *sid_bw )
84 : {
85 : int16_t enr_index, i;
86 : float step, res[L_FRAME16k];
87 : int16_t maxl, num_bits;
88 : int16_t j, k, ptr;
89 : int16_t m1;
90 : float weights;
91 : float sp_enr;
92 2548 : int16_t m = 0;
93 : float tmp[HO_HIST_SIZE * M];
94 : int16_t ll, s_ptr;
95 2548 : float att = 1.0f;
96 : float lsf_tmp[M];
97 : float C[M];
98 : float max_val[2];
99 : int16_t max_idx[2];
100 : float ftmp;
101 : float lsp_tmp[M];
102 : float dev;
103 : float max_dev;
104 : float dist;
105 2548 : int16_t max_idx1[2] = { 0, 0 };
106 : float fft_io[L_FRAME16k];
107 : float *ptR, *ptI;
108 2548 : float enr1 = 0;
109 : float env[NUM_ENV_CNG];
110 : float min1;
111 : int16_t min1_idx;
112 : float d;
113 : float res1[L_FRAME16k];
114 : float tmp_env[HO_HIST_SIZE * NUM_ENV_CNG];
115 2548 : int16_t force_cn_step = 0;
116 : float st_lp_sp_enr;
117 : float lp_ener_thr_scale;
118 : #ifdef ALIGN_ACELP_CORE
119 : float enr;
120 : #endif
121 :
122 2548 : BSTR_ENC_HANDLE hBstr = st->hBstr;
123 2548 : TD_CNG_ENC_HANDLE hTdCngEnc = st->hTdCngEnc;
124 2548 : DTX_ENC_HANDLE hDtxEnc = st->hDtxEnc;
125 :
126 2548 : st_lp_sp_enr = hTdCngEnc->lp_sp_enr;
127 :
128 2548 : lp_ener_thr_scale = 4.0f;
129 2548 : if ( st->element_mode != EVS_MONO )
130 : {
131 2548 : lp_ener_thr_scale = 3.5f;
132 : }
133 :
134 : /* calculate input energy */
135 2548 : sp_enr = (float) log10( sum2_f( speech, st->L_frame ) / st->L_frame + 0.1f ) / (float) log10( 2.0f );
136 :
137 2548 : if ( sp_enr < 0.0f )
138 : {
139 166 : sp_enr = 0.0f;
140 : }
141 :
142 2548 : if ( hDtxEnc->first_CNG == 0 || hTdCngEnc->old_enr_index < 0 )
143 : {
144 30 : hTdCngEnc->lp_sp_enr = sp_enr;
145 : }
146 : else
147 : {
148 2518 : if ( st->last_core_brate > SID_2k40 && ( st->last_core == HQ_CORE || st->hTdCngEnc->burst_ho_cnt > 0 ) && hTdCngEnc->lp_sp_enr < 6.0f && ( sp_enr - hTdCngEnc->lp_sp_enr ) > 4.0f && sp_enr > 6.0f )
149 : {
150 0 : hTdCngEnc->lp_sp_enr = sp_enr;
151 0 : force_cn_step = 1;
152 : }
153 : else
154 : {
155 2518 : hTdCngEnc->lp_sp_enr = 0.1f * sp_enr + 0.9f * hTdCngEnc->lp_sp_enr;
156 : }
157 : }
158 :
159 : /* update the pointer to circular buffer of old LSP vectors */
160 2548 : if ( ++( hTdCngEnc->cng_hist_ptr ) == DTX_HIST_SIZE )
161 : {
162 0 : hTdCngEnc->cng_hist_ptr = 0;
163 : }
164 :
165 : /* update the circular buffer of old LSP vectors with the new LSP vector */
166 2548 : mvr2r( lsp_new, &( hTdCngEnc->cng_lsp_hist[( hTdCngEnc->cng_hist_ptr ) * M] ), M );
167 :
168 : /*-----------------------------------------------------------------*
169 : * Find CNG spectral envelope
170 : * Find LSP median
171 : *-----------------------------------------------------------------*/
172 :
173 2548 : if ( ( st->core_brate == SID_2k40 || st->core_brate == SID_1k75 ) && hDtxEnc->cng_cnt >= ( hDtxEnc->cng_hist_size - 1 ) )
174 : {
175 246 : set_f( max_val, 0.0f, 2 );
176 246 : set_s( max_idx, 0, 2 );
177 :
178 2214 : for ( i = 0; i < hDtxEnc->cng_hist_size; i++ )
179 : {
180 1968 : if ( st->L_frame == L_FRAME )
181 : {
182 728 : lsp2lsf( &hTdCngEnc->cng_lsp_hist[i * M], lsf_tmp, M, INT_FS_12k8 );
183 728 : ftmp = 6400.0f / ( M + 1 );
184 728 : C[i] = ( 6400.0f - lsf_tmp[M - 1] - ftmp ) * ( 6400.0f - lsf_tmp[M - 1] - ftmp );
185 : }
186 : else
187 : {
188 1240 : lsp2lsf( &hTdCngEnc->cng_lsp_hist[i * M], lsf_tmp, M, INT_FS_16k );
189 1240 : ftmp = 8000.0f / ( M + 1 );
190 1240 : C[i] = ( 8000.0f - lsf_tmp[M - 1] - ftmp ) * ( 8000.0f - lsf_tmp[M - 1] - ftmp );
191 : }
192 :
193 1968 : C[i] += ( lsf_tmp[0] - ftmp ) * ( lsf_tmp[0] - ftmp );
194 :
195 31488 : for ( j = 0; j < M - 1; j++ )
196 : {
197 29520 : C[i] += ( lsf_tmp[j + 1] - lsf_tmp[j] - ftmp ) * ( lsf_tmp[j + 1] - lsf_tmp[j] - ftmp );
198 : }
199 :
200 1968 : C[i] *= 0.0588235f; /* 1/M+1 */
201 :
202 1968 : if ( C[i] > max_val[0] )
203 : {
204 656 : max_val[1] = max_val[0];
205 656 : max_idx[1] = max_idx[0];
206 656 : max_val[0] = C[i];
207 656 : max_idx[0] = i;
208 : }
209 1312 : else if ( C[i] > max_val[1] )
210 : {
211 405 : max_val[1] = C[i];
212 405 : max_idx[1] = i;
213 : }
214 : }
215 :
216 4182 : for ( i = 0; i < M; i++ )
217 : {
218 3936 : lsp_new[i] = 0.0f;
219 35424 : for ( j = 0; j < hDtxEnc->cng_hist_size; j++ )
220 : {
221 31488 : lsp_new[i] += hTdCngEnc->cng_lsp_hist[j * M + i];
222 : }
223 :
224 3936 : lsp_new[i] -= ( hTdCngEnc->cng_lsp_hist[max_idx[0] * M + i] + hTdCngEnc->cng_lsp_hist[max_idx[1] * M + i] );
225 3936 : lsp_new[i] /= (float) ( hDtxEnc->cng_hist_size - 2 );
226 : }
227 246 : max_idx1[0] = max_idx[0];
228 246 : max_idx1[1] = max_idx[1];
229 : }
230 :
231 : /*-----------------------------------------------------------------*
232 : * Quantize CNG spectral envelope (only in SID frame)
233 : * Quantize the LSF vector
234 : *-----------------------------------------------------------------*/
235 :
236 :
237 5681 : *allow_cn_step = ( ( hDtxEnc->cng_cnt == 0 ) &&
238 585 : ( hTdCngEnc->lp_sp_enr > 6.0f ) &&
239 585 : ( ( st_lp_sp_enr + 4.0f ) < sp_enr ) &&
240 30 : ( hDtxEnc->first_CNG != 0 ) &&
241 0 : ( hTdCngEnc->old_enr_index >= 0 ) &&
242 3133 : ( st->last_core_brate > SID_2k40 ) ) ||
243 : force_cn_step;
244 :
245 : /* Initialize the CNG spectral envelope in case of the very first CNG frame */
246 2548 : if ( hDtxEnc->first_CNG == 0 )
247 : {
248 30 : mvr2r( st->lsp_old, hDtxEnc->lspCNG, M );
249 :
250 : /* Average the CNG spectral envelope in case of the very first CNG frame */
251 30 : if ( st->element_mode != EVS_MONO )
252 : {
253 510 : for ( i = 0; i < M; i++ )
254 : {
255 480 : lsp_new[i] = 0.5f * ( lsp_mid[i] + lsp_new[i] );
256 : }
257 : }
258 : }
259 :
260 2548 : if ( st->core_brate == SID_2k40 || st->core_brate == SID_1k75 )
261 : {
262 : /* LSF quantization */
263 466 : if ( st->Opt_AMR_WB )
264 : {
265 0 : isf_enc_amr_wb( st, lsf_new, lsp_new, 0 );
266 : }
267 : else
268 : {
269 466 : lsf_enc( st, lsf_new, lsp_new, 0, 0, 0, 0, NULL );
270 : }
271 :
272 : /* Reset CNG history if CNG frame length is changed */
273 466 : if ( st->bwidth == WB && hDtxEnc->first_CNG && st->L_frame != hDtxEnc->last_CNG_L_frame )
274 : {
275 4 : hTdCngEnc->ho_hist_size = 0;
276 : }
277 : }
278 : else
279 : {
280 : /* Use old LSP vector */
281 2082 : mvr2r( st->lsp_old, lsp_new, M );
282 2082 : mvr2r( st->lsf_old, lsf_new, M );
283 : }
284 :
285 :
286 : /*---------------------------------------------------------------------*
287 : * CNG spectral envelope update
288 : * Find A(z) coefficients
289 : *---------------------------------------------------------------------*/
290 :
291 2548 : if ( st->last_core_brate == FRAME_NO_DATA || st->last_core_brate == SID_1k75 || st->last_core_brate == SID_2k40 )
292 : {
293 : /* Reset hangover counter if not first SID period */
294 2328 : if ( st->core_brate > FRAME_NO_DATA )
295 : {
296 246 : hTdCngEnc->num_ho = 0;
297 : }
298 : /* Update LSPs if last SID energy not outlier or insufficient number of hangover frames */
299 2328 : if ( hTdCngEnc->num_ho < 3 || hTdCngEnc->Enew < 1.5f * hTdCngEnc->lp_ener )
300 : {
301 39134 : for ( i = 0; i < M; i++ )
302 : {
303 : /* AR low-pass filter */
304 36832 : hDtxEnc->lspCNG[i] = CNG_ISF_FACT * hDtxEnc->lspCNG[i] + ( 1 - CNG_ISF_FACT ) * lsp_new[i];
305 : }
306 : }
307 : }
308 : else
309 : {
310 : /* Update CNG_mode if allowed */
311 220 : if ( st->element_mode == EVS_MONO && ( st->Opt_AMR_WB || st->bwidth == WB ) && ( !hDtxEnc->first_CNG || hTdCngEnc->act_cnt2 >= MIN_ACT_CNG_UPD ) )
312 : {
313 0 : if ( hDtxEnc->last_active_brate > ACELP_16k40 )
314 : {
315 0 : hDtxEnc->CNG_mode = -1;
316 : }
317 : else
318 : {
319 0 : hDtxEnc->CNG_mode = get_cng_mode( hDtxEnc->last_active_brate );
320 : }
321 : }
322 :
323 : /* If first SID after active burst update LSF history from circ buffer */
324 220 : hTdCngEnc->burst_ho_cnt = min( hTdCngEnc->burst_ho_cnt, hTdCngEnc->ho_circ_size );
325 220 : hTdCngEnc->act_cnt = 0;
326 220 : s_ptr = hTdCngEnc->ho_circ_ptr - hTdCngEnc->burst_ho_cnt + 1;
327 220 : if ( s_ptr < 0 )
328 : {
329 33 : s_ptr += hTdCngEnc->ho_circ_size;
330 : }
331 :
332 522 : for ( ll = hTdCngEnc->burst_ho_cnt; ll > 0; ll-- )
333 : {
334 302 : if ( ++( hTdCngEnc->ho_hist_ptr ) == HO_HIST_SIZE )
335 : {
336 26 : hTdCngEnc->ho_hist_ptr = 0;
337 : }
338 : /* Conversion between 12.8k and 16k LSPs */
339 302 : if ( st->L_frame == L_FRAME && hTdCngEnc->ho_16k_lsp[s_ptr] == 1 )
340 : {
341 : /* Conversion from 16k LPSs to 12k8 */
342 0 : lsp_convert_poly( &( hTdCngEnc->ho_lsp_circ[s_ptr * M] ), st->L_frame, 0 );
343 : }
344 302 : else if ( st->L_frame == L_FRAME16k && hTdCngEnc->ho_16k_lsp[s_ptr] == 0 )
345 : {
346 : /* 16k LSPs already converted and stored, just copy to the other buffer */
347 61 : mvr2r( &( hTdCngEnc->ho_lsp_circ2[s_ptr * M] ), &( hTdCngEnc->ho_lsp_circ[s_ptr * M] ), M );
348 : }
349 :
350 : /* update circular buffers */
351 302 : mvr2r( &( hTdCngEnc->ho_lsp_circ[s_ptr * M] ), &( hTdCngEnc->ho_lsp_hist[hTdCngEnc->ho_hist_ptr * M] ), M );
352 302 : mvr2r( &( hTdCngEnc->ho_ener_circ[s_ptr] ), &( hTdCngEnc->ho_ener_hist[hTdCngEnc->ho_hist_ptr] ), 1 );
353 302 : hTdCngEnc->ho_sid_bw = ( hTdCngEnc->ho_sid_bw & 0x3fffffffL ) << 1;
354 302 : mvr2r( &( hTdCngEnc->ho_env_circ[s_ptr * NUM_ENV_CNG] ), &( hTdCngEnc->ho_env_hist[hTdCngEnc->ho_hist_ptr * NUM_ENV_CNG] ), NUM_ENV_CNG );
355 :
356 302 : hTdCngEnc->ho_hist_size++;
357 302 : if ( hTdCngEnc->ho_hist_size > HO_HIST_SIZE )
358 : {
359 32 : hTdCngEnc->ho_hist_size = HO_HIST_SIZE;
360 : }
361 :
362 302 : s_ptr++;
363 :
364 302 : if ( s_ptr == hTdCngEnc->ho_circ_size )
365 : {
366 36 : s_ptr = 0;
367 : }
368 : }
369 220 : if ( st->hTdCngEnc->burst_ho_cnt > 0 )
370 : {
371 70 : *allow_cn_step |= ( hDtxEnc->first_CNG || st->element_mode == EVS_MONO ) && ( hTdCngEnc->ho_ener_hist[hTdCngEnc->ho_hist_ptr] > lp_ener_thr_scale * hTdCngEnc->lp_ener );
372 : }
373 :
374 220 : if ( !*allow_cn_step && hTdCngEnc->ho_hist_size > 0 )
375 : {
376 194 : ptr = hTdCngEnc->ho_hist_ptr;
377 194 : mvr2r( &( hTdCngEnc->ho_lsp_hist[ptr * M] ), tmp, M );
378 194 : m1 = 0;
379 194 : if ( ( hTdCngEnc->ho_sid_bw & 0x1L ) == 0 )
380 : {
381 70 : mvr2r( &hTdCngEnc->ho_env_hist[ptr * NUM_ENV_CNG], tmp_env, NUM_ENV_CNG );
382 70 : m1 = 1;
383 : }
384 194 : enr = W_DTX_HO[0] * hTdCngEnc->ho_ener_hist[ptr];
385 194 : weights = W_DTX_HO[0];
386 194 : m = 1;
387 910 : for ( k = 1; k < hTdCngEnc->ho_hist_size; k++ )
388 : {
389 716 : ptr--;
390 716 : if ( ptr < 0 )
391 : {
392 35 : ptr = HO_HIST_SIZE - 1;
393 : }
394 :
395 716 : if ( hTdCngEnc->ho_ener_hist[ptr] < hTdCngEnc->ho_ener_hist[hTdCngEnc->ho_hist_ptr] * BUF_H_NRG &&
396 394 : hTdCngEnc->ho_ener_hist[ptr] > hTdCngEnc->ho_ener_hist[hTdCngEnc->ho_hist_ptr] * BUF_L_NRG )
397 : {
398 345 : enr += W_DTX_HO[k] * hTdCngEnc->ho_ener_hist[ptr];
399 345 : weights += W_DTX_HO[k];
400 345 : mvr2r( &hTdCngEnc->ho_lsp_hist[ptr * M], &tmp[m * M], M );
401 345 : if ( ( hTdCngEnc->ho_sid_bw & ( 0x1L << k ) ) == 0 )
402 : {
403 101 : mvr2r( &hTdCngEnc->ho_env_hist[ptr * NUM_ENV_CNG], &tmp_env[m1 * NUM_ENV_CNG], NUM_ENV_CNG );
404 101 : m1++;
405 : }
406 345 : m++;
407 : }
408 : }
409 :
410 194 : enr /= weights;
411 194 : hTdCngEnc->lp_ener = enr;
412 :
413 194 : set_f( max_val, 0.0f, 2 );
414 194 : set_s( max_idx, 0, 2 );
415 :
416 733 : for ( i = 0; i < m; i++ )
417 : {
418 539 : if ( st->L_frame == L_FRAME )
419 : {
420 238 : lsp2lsf( &tmp[i * M], lsf_tmp, M, INT_FS_12k8 );
421 238 : ftmp = 6400.0f / ( M + 1 );
422 238 : C[i] = ( 6400.0f - lsf_tmp[M - 1] - ftmp ) * ( 6400.0f - lsf_tmp[M - 1] - ftmp );
423 : }
424 : else
425 : {
426 301 : lsp2lsf( &tmp[i * M], lsf_tmp, M, INT_FS_16k );
427 301 : ftmp = 8000.0f / ( M + 1 );
428 301 : C[i] = ( 8000.0f - lsf_tmp[M - 1] - ftmp ) * ( 8000.0f - lsf_tmp[M - 1] - ftmp );
429 : }
430 :
431 539 : C[i] += ( lsf_tmp[0] - ftmp ) * ( lsf_tmp[0] - ftmp );
432 :
433 8624 : for ( j = 0; j < M - 1; j++ )
434 : {
435 8085 : C[i] += ( lsf_tmp[j + 1] - lsf_tmp[j] - ftmp ) * ( lsf_tmp[j + 1] - lsf_tmp[j] - ftmp );
436 : }
437 :
438 539 : C[i] *= 0.0588235f; /* 1/M+1 */
439 :
440 539 : if ( C[i] > max_val[0] )
441 : {
442 352 : max_val[1] = max_val[0];
443 352 : max_idx[1] = max_idx[0];
444 352 : max_val[0] = C[i];
445 352 : max_idx[0] = i;
446 : }
447 187 : else if ( C[i] > max_val[1] )
448 : {
449 92 : max_val[1] = C[i];
450 92 : max_idx[1] = i;
451 : }
452 : }
453 :
454 194 : if ( m == 1 )
455 : {
456 59 : mvr2r( tmp, lsp_tmp, M );
457 : }
458 135 : else if ( m < 4 )
459 : {
460 1462 : for ( i = 0; i < M; i++ )
461 : {
462 1376 : lsp_tmp[i] = 0.0f;
463 4848 : for ( j = 0; j < m; j++ )
464 : {
465 3472 : lsp_tmp[i] += tmp[j * M + i];
466 : }
467 :
468 1376 : lsp_tmp[i] -= tmp[max_idx[0] * M + i];
469 1376 : lsp_tmp[i] /= (float) ( m - 1 );
470 : }
471 : }
472 : else
473 : {
474 833 : for ( i = 0; i < M; i++ )
475 : {
476 784 : lsp_tmp[i] = 0.0f;
477 4992 : for ( j = 0; j < m; j++ )
478 : {
479 4208 : lsp_tmp[i] += tmp[j * M + i];
480 : }
481 :
482 784 : lsp_tmp[i] -= ( tmp[max_idx[0] * M + i] + tmp[max_idx[1] * M + i] );
483 784 : lsp_tmp[i] /= (float) ( m - 2 );
484 : }
485 : }
486 :
487 194 : dist = 0.0f;
488 194 : max_dev = 0.0f;
489 3298 : for ( i = 0; i < M; i++ )
490 : {
491 3104 : dev = (float) fabs( lsp_tmp[i] - lsp_new[i] );
492 3104 : dist += dev;
493 3104 : if ( dev > max_dev )
494 : {
495 956 : max_dev = dev;
496 : }
497 : }
498 :
499 194 : if ( dist > 0.4f || max_dev > 0.1f )
500 : {
501 153 : for ( i = 0; i < M; i++ )
502 : {
503 144 : hDtxEnc->lspCNG[i] = lsp_tmp[i];
504 : }
505 : }
506 : else
507 : {
508 3145 : for ( i = 0; i < M; i++ )
509 : {
510 : /* AR low-pass filter */
511 2960 : hDtxEnc->lspCNG[i] = 0.8f * lsp_tmp[i] + ( 1 - 0.8f ) * lsp_new[i];
512 : }
513 : }
514 194 : if ( m1 > 0 )
515 : {
516 2184 : for ( i = 0; i < NUM_ENV_CNG; i++ )
517 : {
518 2080 : env[i] = 0;
519 5500 : for ( j = 0; j < m1; j++ )
520 : {
521 3420 : env[i] += tmp_env[j * NUM_ENV_CNG + i];
522 : }
523 :
524 2080 : env[i] /= (float) m1;
525 2080 : env[i] = env[i] - 2 * hTdCngEnc->lp_ener;
526 : }
527 104 : mvr2r( env, hTdCngEnc->lp_env, NUM_ENV_CNG );
528 : }
529 : }
530 : else
531 : {
532 26 : mvr2r( lsp_new, hDtxEnc->lspCNG, M ); /* use newly analyzed parameters */
533 : }
534 : }
535 :
536 2548 : if ( st->Opt_AMR_WB )
537 : {
538 0 : isp2a( hDtxEnc->lspCNG, Aq, M );
539 : }
540 : else
541 : {
542 2548 : lsp2a_stab( hDtxEnc->lspCNG, Aq, M );
543 : }
544 :
545 11806 : for ( i = 1; i < st->L_frame / L_SUBFR; i++ )
546 : {
547 9258 : mvr2r( Aq, &Aq[i * ( M + 1 )], M + 1 );
548 : }
549 :
550 : /*-----------------------------------------------------------------*
551 : * Find residual signal
552 : * Calculate residual signal energy per sample
553 : *-----------------------------------------------------------------*/
554 :
555 : /* calculate the residual signal */
556 2548 : residu( Aq, M, speech, res, st->L_frame );
557 :
558 2548 : mvr2r( res, res1, st->L_frame );
559 :
560 2548 : if ( st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD )
561 : {
562 2548 : att = powf( 10.0f, hTdCngEnc->CNG_att / 20.0f );
563 2548 : v_multc( res1, att, res1, st->L_frame );
564 : }
565 0 : else if ( st->bwidth != NB )
566 : {
567 0 : if ( st->bwidth == WB && hDtxEnc->CNG_mode >= 0 )
568 : {
569 0 : ftmp = HO_ATT[hDtxEnc->CNG_mode];
570 : }
571 : else
572 : {
573 0 : ftmp = 0.6f;
574 : }
575 :
576 0 : att = ftmp / 6.0f;
577 0 : att = 1.0f / ( 1 + att * 8 );
578 :
579 0 : if ( att < ftmp )
580 : {
581 0 : att = ftmp;
582 : }
583 :
584 0 : v_multc( res1, att, res1, st->L_frame );
585 : }
586 :
587 : /* calculate the spectrum of residual signal */
588 2548 : mvr2r( res1, fft_io, st->L_frame );
589 :
590 2548 : if ( st->L_frame == L_FRAME16k )
591 : {
592 1614 : modify_Fs( fft_io, L_FRAME16k, 16000, fft_io, 12800, hTdCngEnc->exc_mem2, 0 );
593 : }
594 :
595 2548 : fft_rel( fft_io, L_FFT, LOG2_L_FFT );
596 2548 : ptR = &fft_io[1];
597 2548 : ptI = &fft_io[L_FFT - 1];
598 53508 : for ( i = 0; i < NUM_ENV_CNG; i++ )
599 : {
600 50960 : env[i] = 2.0f * ( *ptR * *ptR + *ptI * *ptI ) / L_FFT;
601 50960 : ptR++;
602 50960 : ptI--;
603 : }
604 :
605 2548 : mvr2r( env, &( hTdCngEnc->cng_res_env[( hTdCngEnc->cng_hist_ptr ) * NUM_ENV_CNG] ), NUM_ENV_CNG );
606 : /* calculate the residual signal energy */
607 2548 : enr = dotp( res, res, st->L_frame ) / st->L_frame;
608 :
609 : /* convert log2 of residual signal energy */
610 2548 : enr = (float) log10( enr + 0.1f ) / (float) log10( 2.0f );
611 :
612 : /* update the circular buffer of old energies */
613 2548 : hTdCngEnc->cng_ener_hist[hTdCngEnc->cng_hist_ptr] = enr;
614 :
615 : /*-----------------------------------------------------------------*
616 : * Quantize residual signal energy (only in SID frame)
617 : *-----------------------------------------------------------------*/
618 :
619 2548 : if ( st->core_brate == SID_2k40 || st->core_brate == SID_1k75 )
620 : {
621 466 : if ( hDtxEnc->cng_cnt >= hDtxEnc->cng_hist_size - 1 )
622 : {
623 : /* average the envelope except outliers */
624 5166 : for ( i = 0; i < NUM_ENV_CNG; i++ )
625 : {
626 44280 : for ( j = 0; j < hDtxEnc->cng_hist_size; j++ )
627 : {
628 39360 : env[i] += hTdCngEnc->cng_res_env[j * NUM_ENV_CNG + i];
629 : }
630 :
631 4920 : env[i] -= ( hTdCngEnc->cng_res_env[max_idx1[0] * NUM_ENV_CNG + i] + hTdCngEnc->cng_res_env[max_idx1[1] * NUM_ENV_CNG + i] );
632 4920 : env[i] /= (float) ( hDtxEnc->cng_hist_size - 2 );
633 : }
634 : /* compute average excitation energy */
635 246 : enr = 0;
636 246 : weights = 0;
637 246 : ptr = hTdCngEnc->cng_hist_ptr;
638 :
639 2214 : for ( k = 0; k < hDtxEnc->cng_hist_size; k++ )
640 : {
641 1968 : enr += W_HIST[k] * hTdCngEnc->cng_ener_hist[ptr--];
642 1968 : if ( ptr < 0 )
643 : {
644 246 : ptr = DTX_HIST_SIZE - 1;
645 : }
646 :
647 1968 : weights += W_HIST[k];
648 : }
649 :
650 : /* normalize the average value */
651 246 : enr /= weights;
652 : }
653 :
654 466 : if ( st->element_mode == IVAS_SCE || st->element_mode == IVAS_CPE_DFT )
655 : {
656 466 : enr += hTdCngEnc->CNG_att * FAC_LOG2 / 10.0f;
657 : }
658 0 : else if ( st->bwidth != NB )
659 : {
660 0 : if ( st->bwidth == WB )
661 : {
662 0 : if ( hDtxEnc->CNG_mode >= 0 )
663 : {
664 : /* Bitrate adapted attenuation */
665 0 : att = ENR_ATT[hDtxEnc->CNG_mode];
666 : }
667 : else
668 : {
669 : /* Use least attenuation for higher bitrates */
670 0 : att = ENR_ATT[4];
671 : }
672 : }
673 : else
674 : {
675 0 : att = 1.5f;
676 : }
677 0 : enr -= att;
678 : }
679 :
680 : /* intialize the energy quantization parameters */
681 466 : if ( !st->Opt_AMR_WB )
682 : {
683 466 : step = STEP_SID;
684 466 : maxl = 127;
685 466 : num_bits = 7;
686 : }
687 : else
688 : {
689 0 : step = STEP_AMR_WB_SID;
690 0 : maxl = 63;
691 0 : num_bits = 6;
692 : }
693 :
694 : /* calculate the energy quantization index */
695 466 : enr_index = (int16_t) ( ( enr + 2.0f ) * step );
696 :
697 : /* limit the energy quantization index */
698 466 : if ( enr_index > maxl )
699 : {
700 0 : enr_index = maxl;
701 : }
702 :
703 466 : if ( enr_index < 0 )
704 : {
705 12 : enr_index = 0;
706 : }
707 :
708 : /* allow only slow energy increase */
709 466 : if ( hDtxEnc->first_CNG && enr_index > hTdCngEnc->old_enr_index + MAX_DELTA_CNG )
710 : {
711 69 : if ( *allow_cn_step == 1 )
712 : {
713 0 : enr_index = hTdCngEnc->old_enr_index + (int16_t) ( 0.85f * ( enr_index - hTdCngEnc->old_enr_index ) );
714 : }
715 : else
716 : {
717 69 : enr_index = hTdCngEnc->old_enr_index + MAX_DELTA_CNG;
718 : }
719 : }
720 466 : hTdCngEnc->old_enr_index = enr_index;
721 :
722 466 : push_indice( hBstr, IND_ENERGY, enr_index, num_bits );
723 466 : if ( enr_index == 0 )
724 : {
725 19 : enr_index = -5;
726 : }
727 : /* find the quatized energy */
728 466 : hTdCngEnc->Enew = (float) enr_index / step - 2.0f;
729 466 : hTdCngEnc->Enew = (float) ( pow( 2.0f, hTdCngEnc->Enew ) );
730 466 : if ( st->core_brate == SID_2k40 )
731 : {
732 466 : enr1 = (float) log10( hTdCngEnc->Enew * st->L_frame + 0.1f ) / (float) log10( 2.0f );
733 9786 : for ( i = 0; i < NUM_ENV_CNG; i++ )
734 : {
735 9320 : env[i] -= 2 * hTdCngEnc->Enew;
736 :
737 9320 : if ( env[i] < 0.0f )
738 : {
739 5367 : env[i] = 0.1f;
740 : }
741 :
742 9320 : env[i] = (float) log10( env[i] + 0.1f ) / (float) log10( 2.0f );
743 9320 : env[i] -= att;
744 :
745 9320 : if ( env[i] < 0 )
746 : {
747 5395 : env[i] = 0;
748 : }
749 :
750 9320 : env[i] = enr1 - env[i];
751 : }
752 :
753 : /* codebook search */
754 466 : min1 = 9999.0f;
755 466 : min1_idx = 0;
756 :
757 30290 : for ( i = 0; i < 64; i++ )
758 : {
759 29824 : d = 0.0f;
760 626304 : for ( j = 0; j < NUM_ENV_CNG; j++ )
761 : {
762 596480 : d += ( env[j] - CNG_details_codebook[i][j] ) * ( env[j] - CNG_details_codebook[i][j] );
763 : }
764 :
765 29824 : if ( d < min1 )
766 : {
767 3502 : min1 = d;
768 3502 : min1_idx = i;
769 : }
770 : }
771 466 : push_indice( hBstr, IND_CNG_ENV1, min1_idx, 6 );
772 : /* get quantized res_env_details */
773 9786 : for ( i = 0; i < NUM_ENV_CNG; i++ )
774 : {
775 9320 : q_env[i] = CNG_details_codebook[min1_idx][i];
776 : }
777 : }
778 : /* Update hangover memory during CNG */
779 466 : if ( !*allow_cn_step && ( hTdCngEnc->Enew < 1.5f * hTdCngEnc->lp_ener ) )
780 : {
781 : /* update the pointer to circular buffer of old LSP vectors */
782 370 : if ( ++( hTdCngEnc->ho_hist_ptr ) == HO_HIST_SIZE )
783 : {
784 42 : hTdCngEnc->ho_hist_ptr = 0;
785 : }
786 :
787 : /* update the circular buffer of old LSP vectors with the new LSP vector */
788 370 : mvr2r( lsp_new, &( hTdCngEnc->ho_lsp_hist[( hTdCngEnc->ho_hist_ptr ) * M] ), M );
789 :
790 : /* update the hangover energy buffer */
791 370 : hTdCngEnc->ho_ener_hist[hTdCngEnc->ho_hist_ptr] = hTdCngEnc->Enew;
792 370 : if ( st->core_brate == SID_2k40 )
793 : {
794 7770 : for ( i = 0; i < NUM_ENV_CNG; i++ )
795 : {
796 : /* get quantized envelope */
797 7400 : env[i] = (float) ( pow( 2.0f, ( enr1 - q_env[i] ) ) + 2 * hTdCngEnc->Enew );
798 : }
799 370 : mvr2r( env, &( hTdCngEnc->ho_env_hist[( hTdCngEnc->ho_hist_ptr ) * NUM_ENV_CNG] ), NUM_ENV_CNG );
800 : }
801 370 : if ( ++( hTdCngEnc->ho_hist_size ) > HO_HIST_SIZE )
802 : {
803 233 : hTdCngEnc->ho_hist_size = HO_HIST_SIZE;
804 : }
805 : }
806 : }
807 :
808 : /* dithering bit for AMR-WB IO mode is always set to 0 */
809 2548 : if ( st->core_brate == SID_1k75 )
810 : {
811 0 : push_indice( hBstr, IND_DITHERING, 0, 1 );
812 : }
813 :
814 2548 : if ( st->core_brate == SID_2k40 )
815 : {
816 466 : push_indice( hBstr, IND_ACELP_16KHZ, st->L_frame == L_FRAME16k ? 1 : 0, 1 );
817 :
818 : /* transmit ho_cnt for use at decoder side as CNG synthesis assistance */
819 466 : if ( hTdCngEnc->burst_ho_cnt > ( HO_HIST_SIZE - 1 ) )
820 : {
821 2 : push_indice( hBstr, IND_CNG_HO, ( HO_HIST_SIZE - 1 ), 3 ); /* send max allowed value, limited to 7 */
822 : }
823 : else
824 : {
825 464 : push_indice( hBstr, IND_CNG_HO, hTdCngEnc->burst_ho_cnt, 3 ); /* send actual value */
826 : }
827 466 : hTdCngEnc->num_ho = m;
828 466 : push_indice( hBstr, IND_SID_TYPE, 0, 1 );
829 :
830 466 : if ( st->input_Fs < 32000 && st->element_mode != IVAS_CPE_DFT )
831 : {
832 0 : push_indice( hBstr, IND_SID_BW, 0, 1 );
833 0 : *sid_bw = 0;
834 : }
835 : }
836 :
837 : /*-----------------------------------------------------------------*
838 : * Updates
839 : *-----------------------------------------------------------------*/
840 :
841 : /* update the SID frames counter */
842 2548 : if ( st->core_brate == SID_2k40 || st->core_brate == SID_1k75 )
843 : {
844 466 : hDtxEnc->cng_cnt = 0;
845 : /* update frame length memory */
846 466 : hDtxEnc->last_CNG_L_frame = st->L_frame;
847 466 : hTdCngEnc->cng_hist_ptr = -1;
848 : }
849 : else
850 : {
851 2082 : hDtxEnc->cng_cnt++;
852 : }
853 :
854 2548 : return;
855 : }
856 :
857 :
858 : /*---------------------------------------------------------------------*
859 : * swb_CNG_enc()
860 : *
861 : * SWB DTX/CNG encoding
862 : *---------------------------------------------------------------------*/
863 :
864 54797 : void swb_CNG_enc(
865 : Encoder_State *st, /* i/o: State structure */
866 : const float *shb_speech, /* i : SHB target signal (6-14kHz) at 16kHz */
867 : const float *syn_12k8_16k /* i : ACELP core synthesis at 12.8kHz or 16kHz */
868 : )
869 : {
870 : int16_t shb_SID_updt;
871 :
872 54797 : if ( st->core_brate == SID_2k40 || st->core_brate == FRAME_NO_DATA )
873 : {
874 13765 : if ( st->cng_type == LP_CNG )
875 : {
876 2548 : if ( st->input_Fs >= L_FRAME32k * FRAMES_PER_SEC )
877 : {
878 : /* decide if SHB SID encoding or not */
879 2194 : shb_SID_updt = shb_DTX( st, shb_speech, syn_12k8_16k );
880 :
881 : /* SHB CNG encoding */
882 2194 : shb_CNG_encod( st, shb_SID_updt );
883 : }
884 354 : else if ( st->element_mode == IVAS_CPE_DFT && st->core_brate == SID_2k40 )
885 : {
886 : /* LF-boost not used in DFT-stereo, instead the bandwidth is transmitted */
887 48 : delete_indice( st->hBstr, IND_CNG_ENV1 );
888 48 : push_indice( st->hBstr, IND_BWIDTH, st->bwidth, 2 );
889 48 : push_indice( st->hBstr, IND_UNUSED, 0, 4 );
890 48 : push_indice( st->hBstr, IND_SID_BW, 1, 1 );
891 : }
892 : }
893 13765 : st->hTdCngEnc->last_vad = 0;
894 : }
895 : else
896 : {
897 41032 : st->hTdCngEnc->last_vad = 1;
898 : }
899 :
900 54797 : return;
901 : }
902 :
903 : /*---------------------------------------------------------------------*
904 : * shb_CNG_encod()
905 : *
906 : * SID parameters encoding for SHB signal
907 : *---------------------------------------------------------------------*/
908 :
909 2194 : static void shb_CNG_encod(
910 : Encoder_State *st, /* i/o: State structure */
911 : const int16_t update /* i : SID update flag */
912 : )
913 : {
914 2194 : int16_t idx_ener = 0;
915 2194 : BSTR_ENC_HANDLE hBstr = st->hBstr;
916 : float ener_mid_dec_thr;
917 :
918 2194 : if ( update == 1 )
919 : {
920 : /* SHB energy quantization */
921 418 : if ( st->element_mode == EVS_MONO )
922 : {
923 0 : idx_ener = (int16_t) ( 0.9f * ( 0.1f * st->hTdCngEnc->mov_shb_cng_ener / (float) log10( 2.0f ) + 6.0f ) + 0.5f );
924 : }
925 : else
926 : {
927 418 : idx_ener = (int16_t) ( 0.7f * ( 0.1f * st->hTdCngEnc->mov_shb_cng_ener / (float) log10( 2.0f ) + 6.0f ) + 0.5f );
928 : }
929 :
930 418 : if ( st->bwidth < SWB )
931 : {
932 2 : idx_ener = 0;
933 : }
934 :
935 418 : if ( idx_ener > 15 )
936 : {
937 0 : idx_ener = 15;
938 : }
939 418 : else if ( idx_ener < 0 )
940 : {
941 5 : idx_ener = 0;
942 : }
943 :
944 : /* prevent toggling of idx_ener by adding small dead-zone interval around decision thresholds */
945 418 : if ( st->element_mode != EVS_MONO )
946 : {
947 418 : if ( abs( idx_ener - st->hTdCngEnc->last_idx_ener ) == 1 )
948 : {
949 29 : ener_mid_dec_thr = 0.5f * ( ( st->hTdCngEnc->last_idx_ener / 0.7f - 6.0f ) / 0.1f ) * (float) log10( 2.0f );
950 29 : ener_mid_dec_thr += 0.5f * ( ( idx_ener / 0.7f - 6.0f ) / 0.1f ) * (float) log10( 2.0f );
951 :
952 29 : if ( fabs( st->hTdCngEnc->mov_shb_cng_ener - ener_mid_dec_thr ) / ener_mid_dec_thr < ENER_MID_DEAD_ZONE )
953 : {
954 6 : idx_ener = st->hTdCngEnc->last_idx_ener;
955 : }
956 : }
957 : }
958 :
959 418 : st->hTdCngEnc->last_idx_ener = idx_ener;
960 :
961 418 : push_indice( hBstr, IND_SHB_CNG_GAIN, idx_ener, 4 );
962 418 : push_indice( hBstr, IND_SID_BW, 1, 1 );
963 418 : delete_indice( hBstr, IND_CNG_ENV1 );
964 418 : if ( st->element_mode == IVAS_CPE_DFT )
965 : {
966 418 : push_indice( st->hBstr, IND_BWIDTH, st->bwidth, 2 );
967 : }
968 : else
969 : {
970 0 : push_indice( hBstr, IND_UNUSED, 0, 2 );
971 : }
972 418 : st->hTdCngEnc->ho_sid_bw = ( st->hTdCngEnc->ho_sid_bw & 0x3fffffffL ) << 1;
973 418 : st->hTdCngEnc->ho_sid_bw |= 0x1L;
974 : }
975 1776 : else if ( st->core_brate == SID_2k40 )
976 : {
977 0 : st->hTdCngEnc->ho_sid_bw = ( st->hTdCngEnc->ho_sid_bw & 0x3fffffffL ) << 1;
978 0 : push_indice( hBstr, IND_SID_BW, 0, 1 );
979 : }
980 :
981 2194 : return;
982 : }
983 :
984 :
985 : /*---------------------------------------------------------------------*
986 : * shb_DTX()
987 : *
988 : * Decide if encoding SHB SID or not
989 : *---------------------------------------------------------------------*/
990 :
991 2194 : static int16_t shb_DTX(
992 : Encoder_State *st, /* i/o: State structure */
993 : const float *shb_speech, /* i : SHB target signal (6-14kHz) at 16kHz */
994 : const float *syn_12k8_16k /* i : ACELP core synthesis at 12.8kHz or 16kHz */
995 : )
996 : {
997 : int16_t i;
998 : int16_t update;
999 : float shb_old_speech[( L_LOOK_12k8 + L_SUBFR + L_FRAME ) * 5 / 4];
1000 : float *shb_new_speech;
1001 : float wb_ener;
1002 : float shb_ener;
1003 : float log_wb_ener;
1004 : float log_shb_ener;
1005 : float ftmp;
1006 2194 : int16_t allow_cn_step = 0;
1007 : float att;
1008 :
1009 2194 : TD_CNG_ENC_HANDLE hTdCngEnc = st->hTdCngEnc;
1010 :
1011 2194 : shb_new_speech = shb_old_speech + ( L_LOOK_12k8 + L_SUBFR ) * 5 / 4;
1012 2194 : mvr2r( st->hBWE_TD->old_speech_shb, shb_old_speech, ( L_LOOK_12k8 + L_SUBFR ) * 5 / 4 );
1013 2194 : mvr2r( shb_speech, shb_new_speech, L_FRAME16k );
1014 2194 : mvr2r( shb_old_speech + L_FRAME16k, st->hBWE_TD->old_speech_shb, ( L_LOOK_12k8 + L_SUBFR ) * 5 / 4 );
1015 :
1016 2194 : shb_ener = FLT_MIN * L_FRAME16k;
1017 704274 : for ( i = 0; i < L_FRAME16k; i++ )
1018 : {
1019 702080 : shb_ener += shb_old_speech[i] * shb_old_speech[i];
1020 : }
1021 2194 : shb_ener /= L_FRAME16k;
1022 :
1023 2194 : wb_ener = sum2_f( syn_12k8_16k, st->L_frame ) + 0.001f;
1024 2194 : wb_ener = wb_ener / st->L_frame;
1025 :
1026 2194 : log_wb_ener = 10 * (float) log10( wb_ener );
1027 2194 : if ( st->element_mode == IVAS_SCE || st->element_mode == IVAS_CPE_DFT )
1028 : {
1029 2194 : att = 0.0f;
1030 :
1031 2194 : apply_scale( &att, st->hFdCngEnc->hFdCngCom->CngBandwidth, st->hFdCngEnc->hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO );
1032 : }
1033 : else
1034 : {
1035 0 : att = -6.5f;
1036 : }
1037 2194 : log_shb_ener = 10 * (float) log10( shb_ener ) + att;
1038 :
1039 2194 : if ( st->hDtxEnc->first_CNG == 0 )
1040 : {
1041 24 : hTdCngEnc->mov_wb_cng_ener = log_wb_ener;
1042 24 : hTdCngEnc->mov_shb_cng_ener = log_shb_ener;
1043 24 : hTdCngEnc->last_wb_cng_ener = log_wb_ener;
1044 24 : hTdCngEnc->last_shb_cng_ener = log_shb_ener;
1045 : }
1046 2194 : if ( fabs( log_wb_ener - hTdCngEnc->mov_wb_cng_ener ) > 12.0f )
1047 : {
1048 22 : allow_cn_step = 1;
1049 : }
1050 :
1051 : /* Also allow step if shb energy has dropped 12 dB */
1052 2194 : if ( ( st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD ) && ( ( hTdCngEnc->mov_shb_cng_ener - log_shb_ener ) > 12.0f ) )
1053 : {
1054 26 : allow_cn_step = 1;
1055 : }
1056 :
1057 2194 : if ( allow_cn_step == 1 )
1058 : {
1059 27 : hTdCngEnc->mov_wb_cng_ener = log_wb_ener;
1060 27 : hTdCngEnc->mov_shb_cng_ener = log_shb_ener;
1061 : }
1062 : else
1063 : {
1064 2167 : ftmp = log_wb_ener - hTdCngEnc->mov_wb_cng_ener;
1065 :
1066 2167 : hTdCngEnc->mov_wb_cng_ener += 0.9f * ftmp;
1067 :
1068 2167 : ftmp = log_shb_ener - hTdCngEnc->mov_shb_cng_ener;
1069 :
1070 2167 : hTdCngEnc->mov_shb_cng_ener += 0.25f * ftmp;
1071 : }
1072 2194 : hTdCngEnc->shb_NO_DATA_cnt++;
1073 :
1074 2194 : update = 0;
1075 2194 : if ( st->core_brate == SID_2k40 )
1076 : {
1077 418 : if ( st->hDtxEnc->first_CNG == 0 )
1078 : {
1079 24 : update = 1;
1080 : }
1081 394 : else if ( hTdCngEnc->shb_cng_ini_cnt > 0 )
1082 : {
1083 24 : hTdCngEnc->shb_cng_ini_cnt--;
1084 24 : update = 1;
1085 : }
1086 370 : else if ( hTdCngEnc->last_vad == 1 )
1087 : {
1088 164 : update = 1;
1089 : }
1090 206 : else if ( hTdCngEnc->shb_NO_DATA_cnt >= 100 )
1091 : {
1092 0 : update = 1;
1093 : }
1094 206 : else if ( fabs( ( hTdCngEnc->mov_wb_cng_ener - hTdCngEnc->mov_shb_cng_ener ) - ( hTdCngEnc->last_wb_cng_ener - hTdCngEnc->last_shb_cng_ener ) ) > 3.0f )
1095 : {
1096 78 : update = 1;
1097 : }
1098 128 : else if ( ( st->bwidth >= SWB && hTdCngEnc->last_SID_bwidth < SWB ) || ( st->bwidth < SWB && hTdCngEnc->last_SID_bwidth >= SWB ) )
1099 : {
1100 0 : update = 1;
1101 : }
1102 :
1103 418 : hTdCngEnc->last_SID_bwidth = st->bwidth;
1104 : }
1105 :
1106 : /* LF-boost not yet implemented in decoder which means that the specific wb_sid information is not used */
1107 2194 : if ( ( st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD ) && st->core_brate == SID_2k40 )
1108 : {
1109 418 : update = 1;
1110 : }
1111 :
1112 2194 : if ( update == 1 )
1113 : {
1114 418 : hTdCngEnc->last_wb_cng_ener = hTdCngEnc->mov_wb_cng_ener;
1115 418 : hTdCngEnc->last_shb_cng_ener = hTdCngEnc->mov_shb_cng_ener;
1116 418 : hTdCngEnc->shb_NO_DATA_cnt = 0;
1117 : }
1118 :
1119 2194 : return ( update );
1120 : }
1121 :
1122 :
1123 : /*---------------------------------------------------------------------*
1124 : * calculate_hangover_attenuation_gain()
1125 : *
1126 : *
1127 : *---------------------------------------------------------------------*/
1128 :
1129 413589 : void calculate_hangover_attenuation_gain(
1130 : Encoder_State *st, /* i : encoder state structure */
1131 : float *att, /* o : attenuation factor */
1132 : const int16_t vad_hover_flag /* i : VAD hangover flag */
1133 : )
1134 : {
1135 : float lim;
1136 :
1137 413589 : *att = 1.0f;
1138 413589 : if ( st->hTdCngEnc != NULL && vad_hover_flag && st->hTdCngEnc->burst_ho_cnt > 0 && ( st->bwidth != NB || st->element_mode > EVS_MONO ) )
1139 : {
1140 2910 : if ( st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD )
1141 : {
1142 2434 : *att = powf( 10.0f, ( st->hTdCngEnc->CNG_att / 160.0f ) * st->hTdCngEnc->burst_ho_cnt );
1143 : }
1144 : else
1145 : {
1146 476 : if ( st->bwidth == WB && st->hDtxEnc->CNG_mode >= 0 )
1147 : {
1148 0 : lim = HO_ATT[st->hDtxEnc->CNG_mode];
1149 : }
1150 : else
1151 : {
1152 476 : lim = 0.6f;
1153 : }
1154 :
1155 476 : *att = lim / 6.0f;
1156 476 : *att = 1.0f / ( 1 + *att * st->hTdCngEnc->burst_ho_cnt );
1157 :
1158 476 : if ( *att < lim )
1159 : {
1160 16 : *att = lim;
1161 : }
1162 : }
1163 : }
1164 :
1165 413589 : return;
1166 : }
|