Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 : #include <stdint.h>
5 : #include "options.h" /* Compilation switches */
6 : #include "cnst.h" /* Common constants */
7 : #include "rom_enc.h" /* Encoder static table prototypes */
8 : #include "rom_com.h" /* Static table prototypes */
9 : #include "prot_fx.h" /* Function prototypes */
10 : #include "prot_fx_enc.h" /* Function prototypes */
11 : //#include "basop_mpy.h"
12 :
13 : #include <assert.h>
14 : /*---------------------------------------------------------------------*
15 : * Local constants
16 : *---------------------------------------------------------------------*/
17 :
18 : #define MAX_DELTA 1
19 : #define MIN_CNT 50 /* Minimum frame number before SID interval adaptation */
20 : #define INT_H 50
21 : #define INT_L 8
22 :
23 : /*---------------------------------------------------------------------*
24 : * Local function prototypes
25 : *---------------------------------------------------------------------*/
26 : static void shb_CNG_encod_fx( Encoder_State *st_fx, const Word16 update_fx );
27 : static Word16 shb_DTX_fx( Encoder_State *st_fx, const Word16 *shb_speech_fx, const Word16 *syn_12k8_16k );
28 : static Word16 shb_DTX_ivas_fx( Encoder_State *st, const Word16 *shb_speech_fx, const Word16 *syn_12k8_16k_fx );
29 : static void shb_CNG_encod_ivas_fx( Encoder_State *st, const Word16 update );
30 : /*---------------------------------------------------------------------*
31 : * CNG_enc()
32 : *
33 : * Confort noise generation for the coder
34 : *---------------------------------------------------------------------*/
35 0 : void CNG_enc_fx(
36 : Encoder_State *st_fx, /* i/o: State structure */
37 : Word16 Aq[], /* o : LP coefficients Q12 */
38 : const Word16 *speech, /* i : pointer to current frame input speech buffer Q_new */
39 : Word32 L_enr, /* i : residual energy from Levinson-Durbin Q6 */
40 : const Word16 *lsp_mid, /* i : mid frame LSPs Q15 */
41 : Word16 *lsp_new, /* i/o: current frame ISPs Q15 */
42 : Word16 *lsf_new, /* i/o: current frame ISFs Qlog2(2.56) */
43 : Word16 *allow_cn_step, /* o : allow CN step Q0 */
44 : Word16 Q_new, /* i : Q value of speech */
45 : Word32 *q_env,
46 : Word16 *sid_bw )
47 : {
48 : Word16 enr_index;
49 : Word16 i, j, ptr;
50 : Word16 m1;
51 : Word16 res[L_FRAME16k];
52 0 : Word16 step_inv = 0;
53 0 : move16();
54 : Word16 hi, lo;
55 0 : Word16 maxl = 0;
56 0 : move16();
57 0 : Word16 num_bits = 0;
58 0 : move16();
59 0 : Word16 step = 0;
60 0 : move16();
61 : Word16 *pt_res;
62 : const Word16 *pt_sp;
63 : Word16 enr;
64 : Word32 L_tmp, L_ener;
65 : Word16 k, tmp1;
66 : Word16 weights;
67 : Word16 sp_enr;
68 : Word32 L_tmp1;
69 : Word16 exp;
70 0 : Word16 m = 0;
71 0 : move16();
72 : Word16 tmp[HO_HIST_SIZE * M];
73 : Word16 ll, s_ptr;
74 0 : Word16 tmpv, maxv, scale, att = 1;
75 0 : move16();
76 : Word16 lsf_tmp[M];
77 : Word32 C[M];
78 : Word32 max_val[2];
79 : Word16 max_idx[2];
80 : Word16 ftmp_fx;
81 : Word16 lsp_tmp[M];
82 : Word16 dev;
83 : Word16 max_dev;
84 : Word16 dist;
85 0 : Word16 max_idx1[2] = { 0, 0 };
86 0 : move16();
87 0 : move16();
88 : Word16 fft_io[L_FRAME16k];
89 : Word16 *ptR, *ptI;
90 0 : Word32 enr1 = 0;
91 0 : move32();
92 : Word32 env[NUM_ENV_CNG];
93 : Word32 min1;
94 : Word16 min1_idx;
95 : Word32 d;
96 : Word16 res1[L_FRAME16k];
97 : Word32 tmp_env[HO_HIST_SIZE * NUM_ENV_CNG];
98 : Word16 fra;
99 : Word16 temp_lo_fx, temp_hi_fx;
100 : Word16 exp_pow;
101 0 : Word16 force_cn_step = 0;
102 0 : move16();
103 : Word16 tmp_loop;
104 : Word16 st_lp_sp_enr;
105 0 : DTX_ENC_HANDLE hDtxEnc = st_fx->hDtxEnc;
106 0 : TD_CNG_ENC_HANDLE hTdCngEnc = st_fx->hTdCngEnc;
107 0 : BSTR_ENC_HANDLE hBstr = st_fx->hBstr;
108 0 : st_lp_sp_enr = hTdCngEnc->lp_sp_enr_fx;
109 0 : move16();
110 : Word16 lp_ener_thr_scale;
111 : #ifndef ISSUE_1867_replace_overflow_libenc
112 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
113 : Flag Overflow = 0;
114 : move32();
115 : #endif
116 : #endif
117 : /* Temp variables for floating point functions */
118 :
119 0 : lp_ener_thr_scale = 8; /* 4.0f*/ /*IVAS_CODE Q2 */
120 0 : move16();
121 0 : if ( st_fx->element_mode != EVS_MONO )
122 : {
123 0 : lp_ener_thr_scale = 7; /* 3.5f;*/
124 0 : move16();
125 : }
126 : /*sp_enr = (float) log10( sum2_f( speech, L_frame )/L_frame + 0.1f )/ (float)log10(2.0f);*/ /*9.1 */
127 0 : pt_sp = speech;
128 0 : L_ener = L_deposit_l( 1 );
129 : /* L_ener = L_add(L_shr(sum2_f_fx( speech, L_frame ), 8) , L_ener);*/
130 0 : IF( EQ_16( st_fx->L_frame, L_FRAME ) )
131 : {
132 0 : FOR( j = 0; j < 128; j++ )
133 : {
134 0 : L_tmp = L_mult0( *pt_sp, *pt_sp );
135 0 : pt_sp++;
136 0 : L_tmp = L_mac0( L_tmp, *pt_sp, *pt_sp );
137 0 : pt_sp++;
138 0 : L_ener = L_add( L_ener, L_shr( L_tmp, 7 ) ); /* 2*Q_new + 1, divide by L_frame done here */
139 : }
140 : }
141 : ELSE /* L_FRAME16k */
142 : {
143 0 : FOR( i = 0; i < 2; i++ )
144 : {
145 0 : FOR( j = 0; j < 80; j++ )
146 : {
147 0 : L_tmp = L_mult0( *pt_sp, *pt_sp );
148 0 : pt_sp++;
149 0 : L_tmp = L_mac0( L_tmp, *pt_sp, *pt_sp );
150 0 : pt_sp++;
151 0 : L_ener = L_add( L_ener, L_shr( Mult_32_16( L_tmp, 26214 /* 256/320, Q15 */ ), 7 ) ); /* 2*Q_new + 1, divide by L_frame done here */
152 : }
153 : }
154 : }
155 :
156 0 : hi = norm_l( L_ener );
157 0 : lo = Log2_norm_lc( L_shl( L_ener, hi ) );
158 0 : hi = sub( 29, hi ); /* log2 exp in Q2*Q_new */
159 0 : hi = sub( hi, shl( Q_new, 1 ) ); /* Q0 */
160 0 : L_tmp = L_Comp( hi, lo ); /* Q16 */
161 0 : sp_enr = round_fx( L_shl( L_tmp, 8 ) ); /* Q8 (16+8-16) */
162 :
163 0 : if ( sp_enr < 0 )
164 : {
165 0 : sp_enr = 0;
166 0 : move16();
167 : }
168 0 : test();
169 0 : IF( hDtxEnc->first_CNG == 0 || hTdCngEnc->old_enr_index < 0 )
170 : {
171 0 : hTdCngEnc->lp_sp_enr_fx = sp_enr;
172 0 : move16(); /* Q8 */
173 : }
174 : ELSE
175 : {
176 0 : test();
177 0 : test();
178 0 : test();
179 0 : test();
180 0 : test();
181 0 : IF( GT_32( st_fx->last_core_brate, SID_2k40 ) && ( EQ_16( st_fx->last_core, HQ_CORE ) || st_fx->hTdCngEnc->burst_ho_cnt > 0 ) && LT_16( hTdCngEnc->lp_sp_enr_fx, 1536 /*6.0f in Q8*/ ) &&
182 : GT_16( sub( sp_enr, hTdCngEnc->lp_sp_enr_fx ), 1024 /*4.0f in Q8*/ ) && GT_16( sp_enr, 1536 /*6.0f in Q8*/ ) )
183 : {
184 0 : hTdCngEnc->lp_sp_enr_fx = sp_enr;
185 0 : move16();
186 0 : force_cn_step = 1;
187 0 : move16();
188 : }
189 : ELSE
190 : {
191 0 : hTdCngEnc->lp_sp_enr_fx = round_fx( L_mac( L_mult( 29491 /* 0.9, Q15 */, hTdCngEnc->lp_sp_enr_fx ), 3277 /* 0.1, Q15 */, sp_enr ) ); /* Q8 (8+15+1-16) */
192 0 : move16();
193 : }
194 : }
195 : /* update the pointer to circular buffer of old LSP vectors */
196 0 : hTdCngEnc->cng_hist_ptr = add( hTdCngEnc->cng_hist_ptr, 1 );
197 0 : move16();
198 0 : if ( EQ_16( hTdCngEnc->cng_hist_ptr, DTX_HIST_SIZE ) )
199 : {
200 0 : hTdCngEnc->cng_hist_ptr = 0;
201 0 : move16();
202 : }
203 :
204 : /* update the circular buffer of old LSP vectors with the new LSP vector */
205 0 : Copy( lsp_new, &( hTdCngEnc->cng_lsp_hist_fx[( hTdCngEnc->cng_hist_ptr ) * M] ), M );
206 :
207 : /*-----------------------------------------------------------------*
208 : * Find CNG spectral envelope
209 : * Find LSP median
210 : *-----------------------------------------------------------------*/
211 0 : test();
212 0 : test();
213 0 : IF( ( EQ_32( st_fx->core_brate, SID_2k40 ) || EQ_32( st_fx->core_brate, SID_1k75 ) ) && GE_16( hDtxEnc->cng_cnt, sub( hDtxEnc->cng_hist_size, 1 ) ) )
214 : {
215 0 : set32_fx( max_val, 0, 2 );
216 0 : set16_fx( max_idx, 0, 2 );
217 :
218 0 : FOR( i = 0; i < hDtxEnc->cng_hist_size; i++ )
219 : {
220 0 : IF( EQ_16( st_fx->L_frame, L_FRAME ) )
221 : {
222 0 : lsp2lsf_fx( &hTdCngEnc->cng_lsp_hist_fx[i * M], lsf_tmp, M, INT_FS_FX );
223 0 : ftmp_fx = 964; /*(6400/(M+1))X2.56 */
224 0 : move16(); /*QX2.56 */
225 0 : tmpv = sub( 16384, add( lsf_tmp[M - 1], ftmp_fx ) ); /*QX2.56 */
226 0 : L_tmp = L_mult0( tmpv, tmpv ); /*QX6.5536 */
227 : }
228 : ELSE
229 : {
230 0 : lsp2lsf_fx( &hTdCngEnc->cng_lsp_hist_fx[i * M], lsf_tmp, M, INT_FS_16k );
231 0 : ftmp_fx = 1205; /*(8000/(M+1))X2.56*/
232 0 : move16(); /*QX2.56 */
233 0 : tmpv = sub( 20480, add( lsf_tmp[M - 1], ftmp_fx ) ); /*QX2.56 */
234 0 : L_tmp = L_mult0( tmpv, tmpv ); /*QX6.5536 */
235 : }
236 :
237 0 : tmpv = sub( lsf_tmp[0], ftmp_fx ); /*QX2.56 */
238 0 : L_tmp = L_mac0( L_tmp, tmpv, tmpv ); /*QX6.5536 */
239 0 : FOR( j = 0; j < M - 1; j++ )
240 : {
241 0 : tmpv = sub( sub( lsf_tmp[j + 1], lsf_tmp[j] ), ftmp_fx ); /*QX2.56 */
242 0 : L_tmp = L_mac0( L_tmp, tmpv, tmpv ); /*QX6.5536 */
243 : }
244 :
245 0 : C[i] = Mpy_32_16_1( L_tmp, 1928 /*.0588235f Q15*/ );
246 0 : move32(); /*QX6.5536 */
247 :
248 0 : IF( GT_32( C[i], max_val[0] ) )
249 : {
250 0 : max_val[1] = max_val[0];
251 0 : move32();
252 0 : max_idx[1] = max_idx[0];
253 0 : move16();
254 0 : max_val[0] = C[i];
255 0 : move32();
256 0 : max_idx[0] = i;
257 0 : move16();
258 : }
259 0 : ELSE IF( GT_32( C[i], max_val[1] ) )
260 : {
261 0 : max_val[1] = C[i];
262 0 : move32();
263 0 : max_idx[1] = i;
264 0 : move16();
265 : }
266 : }
267 :
268 0 : FOR( i = 0; i < M; i++ )
269 : {
270 0 : L_tmp = 0;
271 0 : move32();
272 0 : FOR( j = 0; j < hDtxEnc->cng_hist_size; j++ )
273 : {
274 0 : L_tmp = L_add( L_tmp, L_deposit_l( hTdCngEnc->cng_lsp_hist_fx[j * M + i] ) ); /*Q15 */
275 : }
276 :
277 0 : L_tmp = L_sub( L_tmp, L_add( L_deposit_l( hTdCngEnc->cng_lsp_hist_fx[max_idx[0] * M + i] ), L_deposit_l( hTdCngEnc->cng_lsp_hist_fx[max_idx[1] * M + i] ) ) ); /*Q15 */
278 0 : tmpv = div_s( 1, sub( hDtxEnc->cng_hist_size, 2 ) ); /*Q15 */
279 0 : L_tmp = Mpy_32_16_1( L_tmp, tmpv ); /*Q15 */
280 0 : lsp_new[i] = extract_l( L_tmp ); /*Q15 */
281 0 : move16();
282 : }
283 0 : max_idx1[0] = max_idx[0];
284 0 : move16();
285 0 : max_idx1[1] = max_idx[1];
286 0 : move16();
287 : }
288 :
289 : /*-----------------------------------------------------------------*
290 : * Quantize CNG spectral envelope (only in SID frame)
291 : * Quantize the LSF vector
292 : *-----------------------------------------------------------------*/
293 0 : *allow_cn_step = 0;
294 0 : move16();
295 0 : test();
296 0 : test();
297 0 : test();
298 0 : test();
299 0 : test();
300 0 : test();
301 0 : IF( ( ( hDtxEnc->cng_cnt == 0 ) &&
302 : GT_16( hTdCngEnc->lp_sp_enr_fx, 1536 /* 6.0, Q8 */ ) &&
303 : ( LT_16( add( st_lp_sp_enr, 1024 /* 4.0, Q8 */ ), sp_enr ) ) &&
304 : ( hDtxEnc->first_CNG != 0 ) &&
305 : ( hTdCngEnc->old_enr_index >= 0 ) &&
306 : ( GT_32( st_fx->last_core_brate, SID_2k40 ) ) ) ||
307 : EQ_16( force_cn_step, 1 ) )
308 : {
309 0 : *allow_cn_step = 1;
310 0 : move16();
311 : }
312 :
313 : /* Initialize the CNG spectral envelope in case of the very first CNG frame */
314 0 : IF( hDtxEnc->first_CNG == 0 )
315 : {
316 0 : Copy( st_fx->lsp_old_fx, hDtxEnc->lspCNG_fx, M );
317 :
318 : /* Average the CNG spectral envelope in case of the very first CNG frame */
319 0 : IF( st_fx->element_mode != EVS_MONO )
320 : {
321 0 : FOR( i = 0; i < M; i++ )
322 : {
323 : /*lsp_new[i] = 0.5f * (lsp_mid[i] + lsp_new[i]);*/
324 0 : lsp_new[i] = mac_r( L_mult( lsp_mid[i], 16384 ), lsp_new[i], 16384 /*.5 Q15*/ );
325 0 : move16();
326 : }
327 : }
328 : }
329 :
330 :
331 0 : test();
332 0 : IF( EQ_32( st_fx->core_brate, SID_2k40 ) || EQ_32( st_fx->core_brate, SID_1k75 ) )
333 : {
334 : /* LSF quantization */
335 0 : IF( st_fx->Opt_AMR_WB != 0 )
336 : {
337 0 : isf_enc_amr_wb_fx( st_fx, lsf_new, lsp_new, 0 );
338 : }
339 : ELSE
340 : {
341 0 : lsf_enc_fx( st_fx, lsf_new, lsp_new, NULL, NULL, 100, 0, 0, Q_new );
342 : }
343 : /* Reset CNG history if CNG frame length is changed */
344 0 : test();
345 0 : test();
346 0 : if ( EQ_16( st_fx->bwidth, WB ) && hDtxEnc->first_CNG != 0 && NE_16( st_fx->L_frame, hDtxEnc->last_CNG_L_frame ) )
347 : {
348 0 : hTdCngEnc->ho_hist_size = 0;
349 0 : move16();
350 : }
351 : }
352 : ELSE
353 : {
354 : /* Use old LSP vector */
355 0 : Copy( st_fx->lsp_old_fx, lsp_new, M );
356 0 : Copy( st_fx->lsf_old_fx, lsf_new, M );
357 : }
358 :
359 : /*---------------------------------------------------------------------*
360 : * CNG spectral envelope update
361 : * Find A(z) coefficients
362 : *---------------------------------------------------------------------*/
363 :
364 0 : IF( LE_32( st_fx->last_core_brate, SID_2k40 ) )
365 : {
366 : /* Reset hangover counter if not first SID period */
367 0 : if ( GT_32( st_fx->core_brate, FRAME_NO_DATA ) )
368 : {
369 0 : hTdCngEnc->num_ho = 0;
370 0 : move16();
371 : }
372 : /* Update LSPs if last SID energy not outlier or insufficient number of hangover frames */
373 0 : test();
374 0 : IF( LT_16( hTdCngEnc->num_ho, 3 ) || LT_32( Mult_32_16( hTdCngEnc->Enew_fx, 21845 /*1/1.5f, Q15*/ ), hTdCngEnc->lp_ener_fx ) )
375 : {
376 0 : FOR( i = 0; i < M; i++ )
377 : {
378 : /* AR low-pass filter */
379 0 : hDtxEnc->lspCNG_fx[i] = mac_r( L_mult( CNG_ISF_FACT_FX, hDtxEnc->lspCNG_fx[i] ), 32768 - CNG_ISF_FACT_FX, lsp_new[i] );
380 0 : move16(); /* Q15 (15+15+1-16) */
381 : }
382 : }
383 : }
384 : ELSE
385 : {
386 : /* Update CNG_mode if allowed */
387 0 : test();
388 0 : test();
389 0 : test();
390 0 : test();
391 0 : IF( st_fx->element_mode == EVS_MONO && ( ( st_fx->Opt_AMR_WB || EQ_16( st_fx->bwidth, WB ) ) && ( !hDtxEnc->first_CNG || GE_16( hTdCngEnc->act_cnt2, MIN_ACT_CNG_UPD ) ) ) )
392 : {
393 0 : IF( GT_32( hDtxEnc->last_active_brate, ACELP_16k40 ) )
394 : {
395 0 : hDtxEnc->CNG_mode = -1;
396 0 : move16();
397 : }
398 : ELSE
399 : {
400 0 : hDtxEnc->CNG_mode = get_cng_mode( hDtxEnc->last_active_brate );
401 0 : move16();
402 : }
403 : }
404 :
405 : /* If first sid after active burst update LSF history from circ buffer */
406 0 : hTdCngEnc->burst_ho_cnt = s_min( hTdCngEnc->burst_ho_cnt, hTdCngEnc->ho_circ_size );
407 0 : move16();
408 0 : hTdCngEnc->act_cnt = 0;
409 0 : move16();
410 0 : s_ptr = add( sub( hTdCngEnc->ho_circ_ptr, hTdCngEnc->burst_ho_cnt ), 1 );
411 :
412 0 : if ( s_ptr < 0 )
413 : {
414 0 : s_ptr = add( s_ptr, hTdCngEnc->ho_circ_size );
415 : }
416 :
417 0 : FOR( ll = hTdCngEnc->burst_ho_cnt; ll > 0; ll-- )
418 : {
419 0 : hTdCngEnc->ho_hist_ptr = add( hTdCngEnc->ho_hist_ptr, 1 );
420 0 : move16();
421 0 : if ( EQ_16( hTdCngEnc->ho_hist_ptr, HO_HIST_SIZE ) )
422 : {
423 0 : hTdCngEnc->ho_hist_ptr = 0;
424 0 : move16();
425 : }
426 :
427 : /* Conversion between 12.8k and 16k LSPs */
428 0 : test();
429 0 : test();
430 0 : IF( EQ_16( st_fx->L_frame, L_FRAME ) && EQ_16( hTdCngEnc->ho_16k_lsp[s_ptr], 1 ) )
431 : {
432 : /* Conversion from 16k LPSs to 12k8 */
433 0 : lsp_convert_poly_fx( &( hTdCngEnc->ho_lsp_circ_fx[s_ptr * M] ), st_fx->L_frame, 0 );
434 : }
435 0 : ELSE IF( EQ_16( st_fx->L_frame, L_FRAME16k ) && hTdCngEnc->ho_16k_lsp[s_ptr] == 0 )
436 : {
437 : /* 16k LSPs already converted and stored, just copy to the other buffer */
438 0 : Copy( &( hTdCngEnc->ho_lsp_circ2_fx[s_ptr * M] ), &( hTdCngEnc->ho_lsp_circ_fx[s_ptr * M] ), M );
439 : }
440 : /* update the circular buffers */
441 0 : Copy( &( hTdCngEnc->ho_lsp_circ_fx[s_ptr * M] ), &( hTdCngEnc->ho_lsp_hist_fx[hTdCngEnc->ho_hist_ptr * M] ), M );
442 0 : Copy32( &( hTdCngEnc->ho_ener_circ_fx[s_ptr] ), &( hTdCngEnc->ho_ener_hist_fx[hTdCngEnc->ho_hist_ptr] ), 1 );
443 0 : hTdCngEnc->ho_sid_bw = L_shl( L_and( hTdCngEnc->ho_sid_bw, (Word32) 0x3fffffffL ), 1 );
444 0 : move32();
445 0 : Copy32( &( hTdCngEnc->ho_env_circ_fx[s_ptr * NUM_ENV_CNG] ), &( hTdCngEnc->ho_env_hist_fx[hTdCngEnc->ho_hist_ptr * NUM_ENV_CNG] ), NUM_ENV_CNG );
446 :
447 0 : hTdCngEnc->ho_hist_size = add( hTdCngEnc->ho_hist_size, 1 );
448 0 : move16();
449 0 : if ( GT_16( hTdCngEnc->ho_hist_size, HO_HIST_SIZE ) )
450 : {
451 0 : hTdCngEnc->ho_hist_size = HO_HIST_SIZE;
452 0 : move16();
453 : }
454 :
455 0 : s_ptr = add( s_ptr, 1 );
456 :
457 0 : if ( EQ_16( s_ptr, hTdCngEnc->ho_circ_size ) )
458 : {
459 0 : s_ptr = 0;
460 0 : move16();
461 : }
462 : }
463 :
464 0 : IF( hTdCngEnc->burst_ho_cnt > 0 )
465 : {
466 : /**allow_cn_step |= ( hTdCngEnc->ho_ener_hist_fx[hTdCngEnc->ho_hist_ptr] > 4 * hTdCngEnc->lp_ener_fx ); */
467 : /*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);*/
468 : /* (hTdCngEnc->ho_ener_hist[hTdCngEnc->ho_hist_ptr] > lp_ener_thr_scale * hTdCngEnc->lp_ener); */
469 0 : L_tmp1 = L_shr( hTdCngEnc->ho_ener_hist_fx[hTdCngEnc->ho_hist_ptr], 2 );
470 0 : IF( NE_16( lp_ener_thr_scale, 8 ) )
471 : {
472 0 : L_tmp1 = L_add( L_tmp1, L_shr( hTdCngEnc->lp_ener_fx, 8 ) );
473 : }
474 0 : L_tmp1 = L_sub( L_tmp1, hTdCngEnc->lp_ener_fx );
475 0 : test();
476 0 : test();
477 0 : IF( ( hDtxEnc->first_CNG > 0 || st_fx->element_mode == EVS_MONO ) && L_tmp1 > 0 )
478 : {
479 0 : *allow_cn_step = s_or( *allow_cn_step, 1 );
480 0 : move16();
481 : }
482 : }
483 0 : test();
484 0 : IF( *allow_cn_step == 0 && hTdCngEnc->ho_hist_size > 0 )
485 : {
486 : /* Use average of energies below last energy */
487 0 : ptr = hTdCngEnc->ho_hist_ptr;
488 0 : move16();
489 0 : Copy( &( hTdCngEnc->ho_lsp_hist_fx[ptr * M] ), tmp, M );
490 0 : m1 = 0;
491 0 : move16();
492 0 : IF( L_and( hTdCngEnc->ho_sid_bw, (Word32) 0x1 ) == 0 )
493 : {
494 0 : Copy32( &hTdCngEnc->ho_env_hist_fx[ptr * NUM_ENV_CNG], tmp_env, NUM_ENV_CNG );
495 0 : m1 = 1;
496 0 : move16();
497 : }
498 0 : L_enr = Mult_32_16( hTdCngEnc->ho_ener_hist_fx[ptr], W_DTX_HO_FX[0] ); /* Q6+15-15->Q6 */
499 :
500 0 : weights = W_DTX_HO_FX[0]; /* Q15 */
501 0 : move16();
502 0 : m = 1;
503 0 : move16();
504 0 : FOR( k = 1; k < hTdCngEnc->ho_hist_size; k++ )
505 : {
506 0 : ptr = sub( ptr, 1 );
507 0 : if ( ptr < 0 )
508 : {
509 0 : ptr = HO_HIST_SIZE - 1;
510 0 : move16();
511 : }
512 :
513 0 : test();
514 0 : IF( LT_32( Mult_32_16( hTdCngEnc->ho_ener_hist_fx[ptr], ONE_OVER_BUF_H_NRG_FX ), hTdCngEnc->ho_ener_hist_fx[hTdCngEnc->ho_hist_ptr] ) &&
515 : GT_32( hTdCngEnc->ho_ener_hist_fx[ptr], Mult_32_16( hTdCngEnc->ho_ener_hist_fx[hTdCngEnc->ho_hist_ptr], BUF_L_NRG_FX ) ) )
516 : {
517 : /*enr += W_DTX_HO[k] * st_fx->ho_ener_hist[ptr]; */
518 0 : L_tmp1 = Mult_32_16( hTdCngEnc->ho_ener_hist_fx[ptr], W_DTX_HO_FX[k] ); /* Q6+15-15->Q6 */
519 0 : L_enr = L_add( L_enr, L_tmp1 ); /* Q6 */
520 :
521 : /*weights += W_DTX_HO[k]; */
522 0 : weights = add( weights, W_DTX_HO_FX[k] ); /* Q15 */
523 :
524 0 : Copy( &hTdCngEnc->ho_lsp_hist_fx[ptr * M], &tmp[m * M], M );
525 0 : IF( L_and( hTdCngEnc->ho_sid_bw, L_shl( (Word32) 0x1, k ) ) == 0 )
526 : {
527 0 : Copy32( &hTdCngEnc->ho_env_hist_fx[ptr * NUM_ENV_CNG], &tmp_env[m1 * NUM_ENV_CNG], NUM_ENV_CNG );
528 0 : m1 = add( m1, 1 );
529 : }
530 0 : m = add( m, 1 );
531 : }
532 : }
533 :
534 : /*enr /= weights; */
535 0 : exp = norm_s( weights );
536 0 : tmp1 = div_s( shl( 1, sub( 14, exp ) ), weights ); /* Q(15+14-exp-15) */
537 0 : L_tmp1 = Mult_32_16( L_enr, tmp1 ); /* Q(14-exp+6-15)->Q(5-exp) */
538 0 : L_enr = L_shl( L_tmp1, add( exp, 1 ) ); /* Q6 */
539 :
540 0 : hTdCngEnc->lp_ener_fx = L_enr;
541 0 : move32(); /* Q6 */
542 :
543 0 : set32_fx( max_val, 0, 2 );
544 0 : set16_fx( max_idx, 0, 2 );
545 :
546 0 : FOR( i = 0; i < m; i++ )
547 : {
548 0 : IF( EQ_16( st_fx->L_frame, L_FRAME ) )
549 : {
550 0 : lsp2lsf_fx( &tmp[i * M], lsf_tmp, M, INT_FS_FX );
551 0 : ftmp_fx = 964; /*(6400/(M+1))X2.56*/
552 0 : move16(); /*QX2.56 */
553 0 : tmpv = sub( 16384, add( lsf_tmp[M - 1], ftmp_fx ) ); /*QX2.56 */
554 0 : L_tmp = L_mult0( tmpv, tmpv ); /*QX6.5536 */
555 : }
556 : ELSE
557 : {
558 0 : lsp2lsf_fx( &tmp[i * M], lsf_tmp, M, INT_FS_16k );
559 0 : ftmp_fx = 1205; /*(8000/(M+1))X2.56*/
560 0 : move16(); /*QX2.56 */
561 0 : tmpv = sub( 20480, add( lsf_tmp[M - 1], ftmp_fx ) ); /*QX2.56 */
562 0 : L_tmp = L_mult0( tmpv, tmpv ); /*QX6.5536 */
563 : }
564 :
565 0 : tmpv = sub( lsf_tmp[0], ftmp_fx ); /*QX2.56 */
566 0 : L_tmp = L_mac0( L_tmp, tmpv, tmpv ); /*QX6.5536 */
567 0 : FOR( j = 0; j < M - 1; j++ )
568 : {
569 0 : tmpv = sub( sub( lsf_tmp[j + 1], lsf_tmp[j] ), ftmp_fx ); /*QX2.56 */
570 0 : L_tmp = L_mac0( L_tmp, tmpv, tmpv ); /*QX6.5536 */
571 : }
572 :
573 0 : C[i] = Mpy_32_16_1( L_tmp, 1928 );
574 0 : move32(); /*QX6.5536 */
575 :
576 0 : IF( GT_32( C[i], max_val[0] ) )
577 : {
578 0 : max_val[1] = max_val[0];
579 0 : move32();
580 0 : max_idx[1] = max_idx[0];
581 0 : move16();
582 0 : max_val[0] = C[i];
583 0 : move32();
584 0 : max_idx[0] = i;
585 0 : move16();
586 : }
587 0 : ELSE IF( GT_32( C[i], max_val[1] ) )
588 : {
589 0 : max_val[1] = C[i];
590 0 : move32();
591 0 : max_idx[1] = i;
592 0 : move16();
593 : }
594 : }
595 :
596 0 : IF( EQ_16( m, 1 ) )
597 : {
598 0 : Copy( tmp, lsp_tmp, M );
599 : }
600 0 : ELSE IF( LT_16( m, 4 ) )
601 : {
602 0 : FOR( i = 0; i < M; i++ )
603 : {
604 0 : L_tmp = L_deposit_l( 0 );
605 0 : FOR( j = 0; j < m; j++ )
606 : {
607 0 : L_tmp = L_add( L_tmp, L_deposit_l( tmp[j * M + i] ) );
608 : }
609 :
610 0 : L_tmp = L_sub( L_tmp, L_deposit_l( tmp[max_idx[0] * M + i] ) );
611 0 : tmpv = div_s( 1, sub( m, 1 ) ); /*Q15 */
612 0 : L_tmp = Mpy_32_16_1( L_tmp, tmpv ); /*Q15 */
613 0 : lsp_tmp[i] = extract_l( L_tmp ); /*Q15 */
614 : }
615 : }
616 : ELSE
617 : {
618 0 : FOR( i = 0; i < M; i++ )
619 : {
620 0 : L_tmp = L_deposit_l( 0 );
621 0 : FOR( j = 0; j < m; j++ )
622 : {
623 0 : L_tmp = L_add( L_tmp, L_deposit_l( tmp[j * M + i] ) );
624 : }
625 :
626 0 : L_tmp = L_sub( L_tmp, L_add( L_deposit_l( tmp[max_idx[0] * M + i] ), L_deposit_l( tmp[max_idx[1] * M + i] ) ) ); /*Q15 */
627 0 : tmpv = div_s( 1, sub( m, 2 ) ); /*Q15 */
628 0 : L_tmp = Mpy_32_16_1( L_tmp, tmpv ); /*Q15 */
629 0 : lsp_tmp[i] = extract_l( L_tmp ); /*Q15 */
630 : }
631 : }
632 :
633 0 : dist = 0; /*Q15 */
634 0 : max_dev = 0; /*Q15 */
635 0 : move16();
636 0 : move16();
637 0 : FOR( i = 0; i < M; i++ )
638 : {
639 0 : dev = abs_s( sub( lsp_tmp[i], lsp_new[i] ) ); /*Q15 */
640 : #ifdef ISSUE_1867_replace_overflow_libenc
641 0 : dist = add_sat( dist, dev ); /*Q15 */
642 : #else
643 : dist = add_o( dist, dev, &Overflow ); /*Q15 */
644 : #endif
645 0 : if ( GT_16( dev, max_dev ) )
646 : {
647 0 : max_dev = dev;
648 0 : move16();
649 : }
650 : }
651 :
652 0 : test();
653 0 : IF( GT_16( dist, 13107 ) || GT_16( max_dev, 3277 ) )
654 : {
655 0 : FOR( i = 0; i < M; i++ )
656 : {
657 0 : hDtxEnc->lspCNG_fx[i] = lsp_tmp[i];
658 0 : move16(); /*Q15 */
659 : }
660 : }
661 : ELSE
662 : {
663 0 : FOR( i = 0; i < M; i++ )
664 : {
665 : /* AR low-pass filter */
666 0 : hDtxEnc->lspCNG_fx[i] = add( mult_r( 26214, lsp_tmp[i] ), mult_r( 6554, lsp_new[i] ) );
667 0 : move16();
668 : }
669 : }
670 0 : IF( m1 > 0 )
671 : {
672 0 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
673 : {
674 0 : L_tmp = L_deposit_l( 0 );
675 0 : FOR( j = 0; j < m1; j++ )
676 : {
677 : /* env[i] += tmp_env[j*NUM_ENV_CNG+i]; */
678 0 : L_tmp = L_add_sat( L_tmp, tmp_env[j * NUM_ENV_CNG + i] );
679 : }
680 : /* env[i] /= (float)m1; */
681 : /* env[i] = env[i] - 2*hTdCngEnc->lp_ener_fx; */
682 0 : IF( EQ_16( m1, 1 ) )
683 : {
684 0 : L_tmp = L_sub_sat( L_tmp, L_add_sat( hTdCngEnc->lp_ener_fx, hTdCngEnc->lp_ener_fx ) );
685 : }
686 : ELSE
687 : {
688 0 : tmp1 = div_s( 1, m1 );
689 0 : L_tmp = Mult_32_16( L_tmp, tmp1 );
690 0 : L_tmp = L_sub_sat( L_tmp, L_add_sat( hTdCngEnc->lp_ener_fx, hTdCngEnc->lp_ener_fx ) );
691 : }
692 :
693 0 : env[i] = L_tmp;
694 0 : move32();
695 : }
696 0 : Copy32( env, hTdCngEnc->lp_env_fx, NUM_ENV_CNG );
697 : }
698 : }
699 : ELSE
700 : {
701 0 : Copy( lsp_new, hDtxEnc->lspCNG_fx, M ); /* use newly analyzed ISFs */
702 : }
703 : }
704 0 : IF( st_fx->Opt_AMR_WB != 0 )
705 : {
706 0 : E_LPC_f_isp_a_conversion( hDtxEnc->lspCNG_fx, Aq, M );
707 : }
708 : ELSE
709 : {
710 0 : E_LPC_f_lsp_a_conversion( hDtxEnc->lspCNG_fx, Aq, M ); /* Find A(z) (not interpolated) */
711 : }
712 :
713 0 : tmp_loop = shr( st_fx->L_frame, 6 );
714 0 : FOR( i = 1; i < tmp_loop; i++ )
715 : {
716 0 : Copy( Aq, &Aq[i * ( M + 1 )], M + 1 );
717 : }
718 : /*-----------------------------------------------------------------*
719 : * Find residual signal
720 : * Calculate residual signal energy per sample
721 : *-----------------------------------------------------------------*/
722 :
723 : /* calculate the residual signal */
724 0 : Residu3_fx( Aq, speech, res, st_fx->L_frame, 0 );
725 0 : Copy( res, res1, st_fx->L_frame );
726 0 : test();
727 0 : IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) )
728 : {
729 : }
730 0 : ELSE IF( NE_16( st_fx->bwidth, NB ) )
731 : {
732 0 : test();
733 0 : IF( EQ_16( st_fx->bwidth, WB ) && hDtxEnc->CNG_mode >= 0 )
734 : {
735 0 : ftmp_fx = HO_ATT_FX[hDtxEnc->CNG_mode];
736 0 : move16();
737 : }
738 : ELSE
739 : {
740 0 : ftmp_fx = 19661; /*0.6f in Q15*/
741 0 : move16();
742 : }
743 :
744 0 : att = mult( ftmp_fx, 5461 /*1/6f in Q15*/ ); /* Q15 */
745 0 : L_tmp = L_mult( att, 8 ); /* Q16 */
746 0 : tmp1 = extract_l( L_shr( L_tmp, 2 ) ); /* Q14 */
747 0 : tmp1 = add( 16384, tmp1 );
748 0 : att = div_s( 16374, tmp1 ); /* Q15 */
749 :
750 0 : att = s_max( att, ftmp_fx );
751 0 : FOR( i = 0; i < st_fx->L_frame; i++ )
752 : {
753 : /*res1[i] *= att;*/
754 0 : res1[i] = mult( res1[i], att );
755 0 : move16(); /* Q_new */
756 : }
757 0 : att = shr( att, 7 ); /* Q8 */
758 : }
759 :
760 : /* calculate the spectrum of residual signal */
761 0 : Copy( res1, fft_io, st_fx->L_frame );
762 :
763 0 : IF( EQ_16( st_fx->L_frame, L_FRAME16k ) )
764 : {
765 0 : modify_Fs_fx( fft_io, L_FRAME16k, 16000, fft_io, 12800, hTdCngEnc->exc_mem2_fx, 0 );
766 : }
767 :
768 0 : fft_rel_fx( fft_io, L_FFT, LOG2_L_FFT );
769 0 : ptR = &fft_io[1];
770 0 : ptI = &fft_io[L_FFT - 1];
771 0 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
772 : {
773 : /* env[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */
774 : #ifdef ISSUE_1867_replace_overflow_libenc
775 0 : L_tmp = L_mult_sat( *ptR, *ptR ); /* 2*Q_new+1 */
776 0 : L_tmp = L_add_sat( L_tmp, L_mult_sat( *ptI, *ptI ) ); /* 2*Q_new+1 */
777 0 : L_tmp = L_add_sat( L_tmp, L_tmp ); /* 2*Q_new+1 */
778 : #else
779 : L_tmp = L_mult_o( *ptR, *ptR, &Overflow ); /* 2*Q_new+1 */
780 : L_tmp = L_add_o( L_tmp, L_mult_o( *ptI, *ptI, &Overflow ), &Overflow ); /* 2*Q_new+1 */
781 : L_tmp = L_add_o( L_tmp, L_tmp, &Overflow ); /* 2*Q_new+1 */
782 : #endif
783 0 : L_tmp = Mult_32_16( L_tmp, 128 ); /* 2*Q_new+1 */
784 0 : tmp1 = add( add( Q_new, Q_new ), 1 );
785 0 : env[i] = L_shr( L_tmp, sub( tmp1, 6 ) );
786 0 : move32(); /* Q6 */
787 0 : ptR++;
788 0 : ptI--;
789 : }
790 :
791 0 : Copy32( env, &( hTdCngEnc->cng_res_env_fx[( hTdCngEnc->cng_hist_ptr ) * NUM_ENV_CNG] ), NUM_ENV_CNG );
792 :
793 : /* calculate the residual signal energy */
794 : /*enr = dotp( res, res, L_frame ) / L_frame; */
795 0 : maxv = 0;
796 0 : move16();
797 0 : FOR( i = 0; i < st_fx->L_frame; i++ )
798 : {
799 0 : maxv = s_max( maxv, abs_s( res[i] ) );
800 : }
801 0 : scale = norm_s( maxv );
802 0 : pt_res = res;
803 0 : L_ener = L_deposit_l( 1 );
804 0 : IF( EQ_16( st_fx->L_frame, L_FRAME ) )
805 : {
806 0 : FOR( j = 0; j < 128; j++ )
807 : {
808 0 : tmpv = shl( *pt_res, scale );
809 0 : L_tmp = L_mult0( tmpv, tmpv );
810 0 : pt_res++;
811 0 : tmpv = shl( *pt_res, scale );
812 0 : L_tmp = L_mac0_sat( L_tmp, tmpv, tmpv ); /* 2*(Q_new+scale) */
813 0 : pt_res++;
814 0 : L_ener = L_add_sat( L_ener, L_shr( L_tmp, 7 ) ); /* 2*(Q_new+scale)+1, divide by L_frame done here */
815 : }
816 : }
817 : ELSE /* L_FRAME16k */
818 : {
819 0 : FOR( j = 0; j < 160; j++ )
820 : {
821 0 : tmpv = shl( *pt_res, scale );
822 0 : L_tmp = L_mult0( tmpv, tmpv );
823 0 : pt_res++;
824 0 : tmpv = shl( *pt_res, scale );
825 0 : L_tmp = L_mac0_sat( L_tmp, tmpv, tmpv ); /* 2*(Q_new+scale) */
826 0 : pt_res++;
827 0 : L_ener = L_add_sat( L_ener, L_shr( Mult_32_16( L_tmp, 26214 /* 256/320, Q15 */ ), 7 ) ); /* 2*(Q_new+scale)+15+1-16+1, divide by L_frame done here */
828 : }
829 : }
830 : /* convert log2 of residual signal energy */
831 : /*enr = (float)log10( enr + 0.1f ) / (float)log10( 2.0f ); */
832 0 : hi = norm_l( L_ener );
833 0 : lo = Log2_norm_lc( L_shl( L_ener, hi ) );
834 0 : hi = sub( 29, hi ); /* log2 exp in Q2*(Q_new+scale) */
835 0 : hi = sub( hi, shl( add( Q_new, scale ), 1 ) ); /* Q0 */
836 0 : L_tmp = L_Comp( hi, lo ); /* Q16 */
837 0 : enr = round_fx( L_shl( L_tmp, 8 ) ); /* Q8 (16+8-16) */
838 :
839 : /* update the circular buffer of old energies */
840 0 : hTdCngEnc->cng_ener_hist_fx[hTdCngEnc->cng_hist_ptr] = enr;
841 0 : move16(); /* Q8 */
842 :
843 : /*-----------------------------------------------------------------*
844 : * Quantize residual signal energy (only in SID frame)
845 : *-----------------------------------------------------------------*/
846 0 : test();
847 0 : IF( EQ_32( st_fx->core_brate, SID_2k40 ) || EQ_32( st_fx->core_brate, SID_1k75 ) )
848 : {
849 0 : IF( GE_16( hDtxEnc->cng_cnt, sub( hDtxEnc->cng_hist_size, 1 ) ) )
850 : {
851 : /* average the envelope except outliers */
852 0 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
853 : {
854 0 : L_tmp1 = L_add( env[i], 0 );
855 0 : FOR( j = 0; j < hDtxEnc->cng_hist_size; j++ )
856 : {
857 0 : L_tmp1 = L_add_sat( L_tmp1, hTdCngEnc->cng_res_env_fx[j * NUM_ENV_CNG + i] );
858 : }
859 0 : L_tmp = L_add( hTdCngEnc->cng_res_env_fx[max_idx1[0] * NUM_ENV_CNG + i], hTdCngEnc->cng_res_env_fx[max_idx1[1] * NUM_ENV_CNG + i] );
860 0 : L_tmp1 = L_sub( L_tmp1, L_tmp );
861 :
862 : /* env[i] /= (float)(st_fx->cng_hist_size - 2); */
863 0 : tmp1 = sub( hDtxEnc->cng_hist_size, 2 );
864 0 : IF( GT_16( tmp1, 1 ) )
865 : {
866 0 : tmp1 = div_s( 1, tmp1 );
867 0 : L_tmp1 = Mult_32_16( L_tmp1, tmp1 );
868 : }
869 :
870 0 : env[i] = L_tmp1;
871 0 : move32();
872 : }
873 : /* compute average excitation energy */
874 0 : L_tmp = L_deposit_l( 0 );
875 0 : ptr = hTdCngEnc->cng_hist_ptr;
876 0 : move16();
877 :
878 0 : FOR( k = 0; k < hDtxEnc->cng_hist_size; k++ )
879 : {
880 : /* enr += W_HIST[k]*cng_ener_hist[ptr] */
881 0 : L_tmp = L_mac0( L_tmp, W_HIST_FX[k], hTdCngEnc->cng_ener_hist_fx[ptr] ); /* Q24 (8+16) */
882 0 : ptr = sub( ptr, 1 );
883 0 : if ( ptr < 0 ) /* check for circular pointer */
884 : {
885 0 : ptr = DTX_HIST_SIZE - 1;
886 0 : move16();
887 : }
888 : }
889 : /*-----------------------------------------------------------
890 : * here we want to divide L_tmp by the sum
891 : * of all the coefs used W_HIST[0..cng_hist_size-1]
892 : * The table W_HIST_S already contains the inverted sum.
893 : * That is
894 : * W_HIST_S[k] 1
895 : * ------------- = ---------------------------
896 : * 4096 W_HIST[0] + ... + W_HIST[k]
897 : *
898 : * 1 / Sum(W_HIST[0..k]) is always > 1 since the sum
899 : * of the coefs 0..k is always < 1 but > 0
900 : * enr is in Q8 since the history buffer constains Q8 energies
901 : *-----------------------------------------------------------*/
902 : /*L_tmp = Mpy_32_16_1(L_tmp, W_HIST_S_FX[k-1]); */ /* normalize average value */
903 0 : L_tmp = Mult_32_16( L_tmp, W_HIST_S_FX[k - 1] ); /* Q21 (24+12+1-16) */
904 0 : L_tmp = L_shl( L_tmp, 3 ); /* Q24 */
905 0 : enr = round_fx( L_tmp ); /* Q8 */
906 : }
907 : /* decrease the energy in case of WB input */
908 0 : test();
909 0 : IF( EQ_16( st_fx->element_mode, IVAS_SCE ) || EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) )
910 : {
911 : }
912 0 : ELSE IF( NE_16( st_fx->bwidth, NB ) )
913 : {
914 0 : IF( EQ_16( st_fx->bwidth, WB ) )
915 : {
916 0 : IF( hDtxEnc->CNG_mode >= 0 )
917 : {
918 : /* Bitrate adapted attenuation */
919 0 : att = ENR_ATT_fx[hDtxEnc->CNG_mode];
920 0 : move16();
921 : }
922 : ELSE
923 : {
924 : /* Use least attenuation for higher bitrates */
925 0 : att = ENR_ATT_fx[4];
926 0 : move16();
927 : }
928 : }
929 : ELSE
930 : {
931 0 : att = 384;
932 0 : move16(); /*Q8*/
933 : }
934 0 : enr = sub( enr, att );
935 : }
936 : /* intialize the energy quantization parameters */
937 0 : IF( st_fx->Opt_AMR_WB == 0 )
938 : {
939 0 : step = STEP_SID_FX;
940 0 : move16();
941 0 : step_inv = ISTEP_SID_FX;
942 0 : move16();
943 0 : maxl = 127;
944 0 : move16();
945 0 : num_bits = 7;
946 0 : move16();
947 : }
948 : ELSE
949 : {
950 0 : step = STEP_AMR_WB_SID_FX;
951 0 : move16();
952 0 : step_inv = ISTEP_AMR_WB_SID_FX;
953 0 : move16();
954 0 : maxl = 63;
955 0 : move16();
956 0 : num_bits = 6;
957 0 : move16();
958 : }
959 :
960 : /* calculate the energy quantization index */
961 0 : enr_index = add( enr, 512 /* Q8(2.0) */ ); /* enr + 2.0 */
962 0 : enr_index = extract_l( L_shr( L_mult0( enr_index, step ), 12 + 8 ) ); /* Q0 (8+12-(8+12)) */
963 :
964 : /* limit the energy quantization index */
965 0 : enr_index = s_min( enr_index, maxl );
966 0 : enr_index = s_max( enr_index, 0 );
967 :
968 : /* allow only slow energy increase */
969 0 : test();
970 0 : IF( hTdCngEnc->old_enr_index >= 0 && GT_16( enr_index, add( hTdCngEnc->old_enr_index, MAX_DELTA ) ) )
971 : {
972 0 : IF( *allow_cn_step != 0 )
973 : {
974 0 : tmp1 = mult( 27853 /* Q15(0.85) */, sub( enr_index, hTdCngEnc->old_enr_index ) );
975 0 : enr_index = add( hTdCngEnc->old_enr_index, tmp1 );
976 : }
977 : ELSE
978 : {
979 0 : enr_index = add( hTdCngEnc->old_enr_index, MAX_DELTA );
980 : }
981 : }
982 0 : hTdCngEnc->old_enr_index = enr_index;
983 0 : move16();
984 :
985 0 : push_indice( hBstr, IND_ENERGY, enr_index, num_bits );
986 0 : if ( enr_index == 0 )
987 : {
988 0 : enr_index = -5;
989 0 : move16();
990 : }
991 : /* Find quantized energy */
992 : /* *Enew = (float)enr_index / step - 2.0 */
993 : /* *Enew = (float)pow(2.0, *Enew) */
994 0 : L_tmp = L_mult( enr_index, step_inv ); /* Q16(0+15+1) */
995 : /* substract by 2 not done to leave Energy in Q2 */
996 0 : lo = L_Extract_lc( L_tmp, &hi );
997 0 : hTdCngEnc->Enew_fx = Pow2( add( hi, 4 ), lo ); /* Q6 */
998 0 : move32();
999 0 : IF( EQ_32( st_fx->core_brate, SID_2k40 ) )
1000 : {
1001 : /* enr1 = (float)log10( st->Enew*L_frame + 0.1f ) / (float)log10( 2.0f );*/
1002 0 : exp = norm_l( hTdCngEnc->Enew_fx );
1003 0 : L_tmp = L_shl( hTdCngEnc->Enew_fx, exp ); /*Q(exp+6) */
1004 0 : L_tmp = Mult_32_16( L_tmp, shl( st_fx->L_frame, 5 ) ); /* Q(exp+6+5-15=exp-4) */
1005 :
1006 0 : L_tmp = L_shr_sat( L_tmp, sub( exp, 10 ) ); /* Q6 */
1007 :
1008 0 : exp = norm_l( L_tmp );
1009 0 : fra = Log2_norm_lc( L_shl( L_tmp, exp ) );
1010 0 : exp = sub( sub( 30, exp ), 6 );
1011 0 : L_tmp = L_Comp( exp, fra );
1012 0 : enr1 = L_shr( L_tmp, 10 ); /* Q6 */
1013 :
1014 0 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
1015 : {
1016 : /* env[i] -= 2 * st->Enew;*/
1017 0 : L_tmp1 = L_add( env[i], 0 );
1018 0 : L_tmp = L_add( hTdCngEnc->Enew_fx, hTdCngEnc->Enew_fx );
1019 0 : L_tmp1 = L_sub( L_tmp1, L_tmp ); /*Q6*/
1020 :
1021 0 : IF( L_tmp1 < 0 )
1022 : {
1023 0 : L_tmp1 = L_deposit_l( 6 ); /* (0.1)Q6 */
1024 : }
1025 : /* env[i] = (float)log10( env[i] + 0.1f ) / (float)log10( 2.0f ); */
1026 0 : exp = norm_l( L_tmp1 );
1027 0 : fra = Log2_norm_lc( L_shl( L_tmp1, exp ) );
1028 0 : exp = sub( sub( 30, exp ), 6 );
1029 0 : L_tmp = L_Comp( exp, fra );
1030 0 : L_tmp1 = L_shr( L_tmp, 10 ); /* Q6 */
1031 :
1032 0 : L_tmp = L_shr( L_deposit_l( att ), 2 ); /* Q6 */
1033 0 : L_tmp1 = L_sub( L_tmp1, L_tmp );
1034 :
1035 0 : IF( L_tmp1 < 0 )
1036 : {
1037 0 : L_tmp1 = L_deposit_l( 0 );
1038 : }
1039 :
1040 0 : L_tmp1 = L_sub( enr1, L_tmp1 );
1041 :
1042 0 : env[i] = L_tmp1;
1043 0 : move32();
1044 : }
1045 :
1046 : /* codebook search */
1047 0 : min1 = L_add( 1310588928, 0 ); /* Q17 */
1048 0 : min1_idx = 0;
1049 0 : move16();
1050 :
1051 0 : FOR( i = 0; i < 64; i++ )
1052 : {
1053 0 : d = L_deposit_l( 0 );
1054 0 : FOR( j = 0; j < NUM_ENV_CNG; j++ )
1055 : {
1056 : /* d += (env[j] - CNG_details_codebook_fx[i][j]) * (env[j] - CNG_details_codebook_fx[i][j]);*/
1057 0 : L_tmp = L_sub( env[j], L_deposit_l( CNG_details_codebook_fx[i][j] ) ); /* Q6 */
1058 0 : exp = norm_l( L_tmp );
1059 0 : L_tmp = L_shl( L_tmp, exp ); /*Q(exp+6)*/
1060 0 : tmp1 = extract_h( L_tmp ); /*Q(exp+6-16)=exp-10*/
1061 : #ifdef ISSUE_1867_replace_overflow_libenc
1062 0 : L_tmp = L_mult_sat( tmp1, tmp1 ); /*Q(2*exp - 19)*/
1063 : #else
1064 : L_tmp = L_mult_o( tmp1, tmp1, &Overflow ); /*Q(2*exp - 19)*/
1065 : #endif
1066 0 : L_tmp = L_shr( L_tmp, sub( add( exp, exp ), 36 ) ); /* Q17 */
1067 0 : d = L_add( d, L_tmp );
1068 : }
1069 :
1070 0 : IF( LT_32( d, min1 ) )
1071 : {
1072 0 : min1 = L_add( d, 0 );
1073 0 : min1_idx = i;
1074 0 : move16();
1075 : }
1076 : }
1077 0 : push_indice( hBstr, IND_CNG_ENV1, min1_idx, 6 );
1078 : /* get quantized res_env_details */
1079 0 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
1080 : {
1081 0 : q_env[i] = L_deposit_l( CNG_details_codebook_fx[min1_idx][i] );
1082 0 : move32();
1083 : }
1084 : }
1085 : /* Update hangover memory during CNG */
1086 0 : test();
1087 0 : IF( *allow_cn_step == 0 && LT_32( Mult_32_16( hTdCngEnc->Enew_fx, 21845 /*1/1.5f, Q15*/ ), hTdCngEnc->lp_ener_fx ) )
1088 : {
1089 : /* update the pointer to circular buffer of old LSP vectors */
1090 0 : hTdCngEnc->ho_hist_ptr = add( hTdCngEnc->ho_hist_ptr, 1 );
1091 0 : move16();
1092 0 : if ( EQ_16( hTdCngEnc->ho_hist_ptr, HO_HIST_SIZE ) )
1093 : {
1094 0 : hTdCngEnc->ho_hist_ptr = 0;
1095 0 : move16();
1096 : }
1097 :
1098 : /* update the circular buffer of old LSP vectors with the new LSP vector */
1099 0 : Copy( lsp_new, &( hTdCngEnc->ho_lsp_hist_fx[( hTdCngEnc->ho_hist_ptr ) * M] ), M );
1100 :
1101 : /* update the hangover energy buffer */
1102 0 : hTdCngEnc->ho_ener_hist_fx[hTdCngEnc->ho_hist_ptr] = hTdCngEnc->Enew_fx;
1103 0 : move32();
1104 0 : IF( EQ_32( st_fx->core_brate, SID_2k40 ) )
1105 : {
1106 0 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
1107 : {
1108 : /* get quantized envelope */
1109 : /* env[i] = pow(2.0f,(enr1 - q_env[i])) + 2*st->Enew;*/
1110 0 : L_tmp = L_sub( enr1, q_env[i] ); /* Q6 */
1111 0 : L_tmp = L_shl( L_tmp, 10 ); /* 16 */
1112 0 : temp_lo_fx = L_Extract_lc( L_tmp, &temp_hi_fx );
1113 :
1114 0 : exp_pow = sub( 14, temp_hi_fx );
1115 0 : L_tmp = Pow2( 14, temp_lo_fx ); /* Qexp_pow */
1116 0 : env[i] = L_shl( L_tmp, sub( 6, exp_pow ) );
1117 0 : move32(); /* Q6 */
1118 0 : L_tmp = L_add( hTdCngEnc->Enew_fx, hTdCngEnc->Enew_fx );
1119 0 : env[i] = L_add( env[i], L_tmp );
1120 0 : move32(); /* Q6 */
1121 : }
1122 0 : Copy32( env, &( hTdCngEnc->ho_env_hist_fx[( hTdCngEnc->ho_hist_ptr ) * NUM_ENV_CNG] ), NUM_ENV_CNG );
1123 : }
1124 0 : hTdCngEnc->ho_hist_size = add( hTdCngEnc->ho_hist_size, 1 );
1125 0 : move16();
1126 0 : if ( GT_16( hTdCngEnc->ho_hist_size, HO_HIST_SIZE ) )
1127 : {
1128 0 : hTdCngEnc->ho_hist_size = HO_HIST_SIZE;
1129 0 : move16();
1130 : }
1131 : }
1132 : }
1133 : /* dithering bit for AMR-WB IO mode is always set to 0 */
1134 0 : IF( EQ_32( st_fx->core_brate, SID_1k75 ) )
1135 : {
1136 0 : push_indice( hBstr, IND_DITHERING, 0, 1 );
1137 : }
1138 0 : IF( EQ_32( st_fx->core_brate, SID_2k40 ) )
1139 : {
1140 0 : IF( EQ_16( st_fx->L_frame, L_FRAME16k ) )
1141 : {
1142 0 : push_indice( hBstr, IND_ACELP_16KHZ, 1, 1 );
1143 : }
1144 : ELSE
1145 : {
1146 0 : push_indice( hBstr, IND_ACELP_16KHZ, 0, 1 );
1147 : }
1148 :
1149 0 : push_indice( hBstr, IND_CNG_HO, s_min( hTdCngEnc->burst_ho_cnt, 7 ), 3 );
1150 0 : hTdCngEnc->num_ho = m;
1151 0 : move16();
1152 0 : push_indice( hBstr, IND_SID_TYPE, 0, 1 );
1153 :
1154 0 : test();
1155 0 : IF( LT_32( st_fx->input_Fs, 32000 ) && NE_16( st_fx->element_mode, IVAS_CPE_DFT ) )
1156 : {
1157 0 : push_indice( hBstr, IND_SID_BW, 0, 1 );
1158 0 : *sid_bw = 0;
1159 0 : move16();
1160 : }
1161 : }
1162 :
1163 : /*-----------------------------------------------------------------*
1164 : * Updates
1165 : *-----------------------------------------------------------------*/
1166 : /* update the SID frames counter */
1167 0 : test();
1168 0 : IF( EQ_32( st_fx->core_brate, SID_2k40 ) || EQ_32( st_fx->core_brate, SID_1k75 ) )
1169 : {
1170 0 : hDtxEnc->cng_cnt = 0;
1171 0 : move16();
1172 0 : hTdCngEnc->cng_hist_ptr = -1;
1173 0 : move16();
1174 : /* update frame length memory */
1175 0 : hDtxEnc->last_CNG_L_frame = st_fx->L_frame;
1176 0 : move16();
1177 : }
1178 : ELSE
1179 : {
1180 0 : hDtxEnc->cng_cnt = add( hDtxEnc->cng_cnt, 1 );
1181 0 : move16();
1182 : }
1183 :
1184 0 : return;
1185 : }
1186 :
1187 2438 : void CNG_enc_ivas_fx(
1188 : Encoder_State *st_fx, /* i/o: State structure */
1189 : Word16 Aq[], /* o : LP coefficients Q12 */
1190 : const Word16 *speech, /* i : pointer to current frame input speech buffer Q_new */
1191 : // Word32 L_ener, /* i : residual energy from Levinson-Durbin Q6 */
1192 : const Word16 *lsp_mid, /* i : mid frame LSPs Q15 */
1193 : Word16 *lsp_new, /* i/o: current frame ISPs Q15 */
1194 : Word16 *lsf_new, /* i/o: current frame ISFs Qlog2(2.56) */
1195 : Word16 *allow_cn_step, /* o : allow CN step Q0 */
1196 : Word16 Q_new, /* i : Q value of speech */
1197 : Word32 *q_env,
1198 : Word16 *sid_bw )
1199 : {
1200 : Word16 enr_index;
1201 : Word16 i, j, ptr;
1202 : Word16 m1;
1203 : Word16 res[L_FRAME16k];
1204 : Word16 step_inv;
1205 : Word16 hi, lo;
1206 : Word16 maxl;
1207 : Word16 num_bits;
1208 : Word16 step;
1209 : Word16 enr;
1210 : Word32 L_tmp;
1211 : Word16 k, tmp1;
1212 : Word16 weights;
1213 : Word16 sp_enr;
1214 : Word32 L_tmp1;
1215 : Word16 exp;
1216 : Word16 m;
1217 : Word16 tmp[HO_HIST_SIZE * M];
1218 : Word16 ll, s_ptr;
1219 : Word16 tmpv, att;
1220 : Word16 lsf_tmp[M];
1221 : Word32 C[M];
1222 : Word32 max_val[2];
1223 : Word16 max_idx[2];
1224 : Word16 ftmp_fx;
1225 : Word16 lsp_tmp[M];
1226 : Word32 dev;
1227 : Word32 max_dev;
1228 : Word32 dist;
1229 : Word16 max_idx1[2];
1230 : Word16 fft_io[L_FRAME16k];
1231 : Word16 *ptR, *ptI;
1232 : Word32 enr1;
1233 : Word32 env[NUM_ENV_CNG];
1234 : Word32 min1;
1235 : Word16 min1_idx;
1236 : Word32 d;
1237 : Word16 res1[L_FRAME16k];
1238 : Word32 tmp_env[HO_HIST_SIZE * NUM_ENV_CNG];
1239 : Word16 fra;
1240 : Word16 temp_lo_fx, temp_hi_fx;
1241 : Word16 exp_pow;
1242 : Word16 force_cn_step;
1243 : Word16 tmp_loop;
1244 : Word16 st_lp_sp_enr;
1245 2438 : DTX_ENC_HANDLE hDtxEnc = st_fx->hDtxEnc;
1246 2438 : TD_CNG_ENC_HANDLE hTdCngEnc = st_fx->hTdCngEnc;
1247 2438 : BSTR_ENC_HANDLE hBstr = st_fx->hBstr;
1248 : Word16 lp_ener_thr_scale;
1249 : Word64 w_temp;
1250 : Word32 inv_frame_len;
1251 : Word32 L_ener;
1252 : #ifndef ISSUE_1867_replace_overflow_libenc
1253 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1254 : Flag Overflow = 0;
1255 : move32();
1256 : #endif
1257 : #endif
1258 2438 : step_inv = 0;
1259 2438 : move16();
1260 2438 : maxl = 0;
1261 2438 : move16();
1262 2438 : num_bits = 0;
1263 2438 : move16();
1264 2438 : step = 0;
1265 2438 : move16();
1266 2438 : m = 0;
1267 2438 : move16();
1268 2438 : att = 1;
1269 2438 : move16();
1270 2438 : max_idx1[0] = 0;
1271 2438 : max_idx1[1] = 0;
1272 2438 : move16();
1273 2438 : move16();
1274 2438 : enr1 = 0;
1275 2438 : move32();
1276 2438 : force_cn_step = 0;
1277 2438 : move16();
1278 2438 : st_lp_sp_enr = hTdCngEnc->lp_sp_enr_fx;
1279 2438 : move16();
1280 : /* Temp variables for floating point functions */
1281 :
1282 2438 : lp_ener_thr_scale = 8; /* 4.0f*/ /* Q1 */
1283 2438 : move16();
1284 2438 : if ( st_fx->element_mode != EVS_MONO )
1285 : {
1286 2438 : lp_ener_thr_scale = 7; /* 3.5f;*/ /* Q1 */
1287 2438 : move16();
1288 : }
1289 :
1290 2438 : w_temp = 1;
1291 2438 : move64();
1292 :
1293 725062 : FOR( j = 0; j < st_fx->L_frame; j++ )
1294 : {
1295 722624 : w_temp = W_mac0_16_16( w_temp, speech[j], speech[j] );
1296 : }
1297 2438 : exp = W_norm( w_temp );
1298 :
1299 2438 : inv_frame_len = 0;
1300 2438 : move32();
1301 :
1302 2438 : SWITCH( st_fx->L_frame )
1303 : {
1304 0 : case L_FRAME25_6k:
1305 0 : inv_frame_len = ONE_BY_L_FRAME25_6k_Q31;
1306 0 : move16();
1307 0 : BREAK;
1308 899 : case L_FRAME:
1309 899 : inv_frame_len = ONE_BY_L_FRAME_Q31;
1310 899 : move16();
1311 899 : BREAK;
1312 0 : case L_FRAME48k:
1313 0 : inv_frame_len = ONE_BY_L_FRAME48k_Q31;
1314 0 : move16();
1315 0 : BREAK;
1316 0 : case 240:
1317 0 : inv_frame_len = ONE_BY_240_Q31;
1318 0 : move16();
1319 0 : BREAK;
1320 0 : case L_FRAME32k:
1321 0 : inv_frame_len = ONE_BY_L_FRAME32k_Q31;
1322 0 : move16();
1323 0 : BREAK;
1324 1539 : case L_FRAME16k:
1325 1539 : inv_frame_len = ONE_BY_L_FRAME16k_Q31;
1326 1539 : move16();
1327 1539 : BREAK;
1328 0 : case L_FRAME8k:
1329 0 : inv_frame_len = ONE_BY_L_FRAME8k_Q31;
1330 0 : move16();
1331 0 : BREAK;
1332 0 : case L_FRAME4k:
1333 0 : inv_frame_len = ONE_BY_L_FRAME4k_Q31;
1334 0 : move16();
1335 0 : BREAK;
1336 0 : default:
1337 0 : inv_frame_len = divide3216( 1, st_fx->L_frame );
1338 : }
1339 2438 : L_ener = W_extract_h( W_shl( w_temp, exp ) ); /* Q = 2*Q_new+exp-32 */
1340 2438 : L_ener = Mpy_32_32( L_ener, inv_frame_len ); /* Q = 2*Q_new+exp-32 */
1341 2438 : L_ener = L_shl( L_ener, sub( 33, exp ) ); /* Q = 2*Q_new+1 */
1342 :
1343 2438 : hi = norm_l( L_ener );
1344 2438 : lo = Log2_norm_lc( L_shl( L_ener, hi ) );
1345 2438 : hi = sub( 29, hi ); /* log2 exp in Q2*Q_new */
1346 2438 : hi = sub( hi, shl( Q_new, 1 ) ); /* Q0 */
1347 2438 : L_tmp = L_Comp( hi, lo ); /* Q16 */
1348 2438 : sp_enr = round_fx( L_shl( L_tmp, 8 ) ); /* Q8 (16+8-16) */
1349 :
1350 2438 : if ( sp_enr < 0 )
1351 : {
1352 156 : sp_enr = 0;
1353 156 : move16();
1354 : }
1355 2438 : test();
1356 2438 : IF( hDtxEnc->first_CNG == 0 || hTdCngEnc->old_enr_index < 0 )
1357 : {
1358 28 : hTdCngEnc->lp_sp_enr_fx = sp_enr;
1359 28 : move16(); /* Q8 */
1360 : }
1361 : ELSE
1362 : {
1363 2410 : test();
1364 2410 : test();
1365 2410 : test();
1366 2410 : test();
1367 2410 : test();
1368 2410 : IF( GT_32( st_fx->last_core_brate, SID_2k40 ) && ( EQ_16( st_fx->last_core, HQ_CORE ) || st_fx->hTdCngEnc->burst_ho_cnt > 0 ) && LT_16( hTdCngEnc->lp_sp_enr_fx, 1536 /*6.0f in Q8*/ ) &&
1369 : GT_16( sub( sp_enr, hTdCngEnc->lp_sp_enr_fx ), 1024 /*4.0f in Q8*/ ) && GT_16( sp_enr, 1536 /*6.0f in Q8*/ ) )
1370 : {
1371 0 : hTdCngEnc->lp_sp_enr_fx = sp_enr; /* Q8 */
1372 0 : move16();
1373 0 : force_cn_step = 1;
1374 0 : move16();
1375 : }
1376 : ELSE
1377 : {
1378 2410 : hTdCngEnc->lp_sp_enr_fx = round_fx( L_mac( L_mult( 29491 /* 0.9, Q15 */, hTdCngEnc->lp_sp_enr_fx ), 3277 /* 0.1, Q15 */, sp_enr ) ); /* Q8 (8+15+1-16) */
1379 2410 : move16();
1380 : }
1381 : }
1382 : /* update the pointer to circular buffer of old LSP vectors */
1383 2438 : hTdCngEnc->cng_hist_ptr = add( hTdCngEnc->cng_hist_ptr, 1 );
1384 2438 : move16();
1385 2438 : if ( EQ_16( hTdCngEnc->cng_hist_ptr, DTX_HIST_SIZE ) )
1386 : {
1387 0 : hTdCngEnc->cng_hist_ptr = 0;
1388 0 : move16();
1389 : }
1390 :
1391 : /* update the circular buffer of old LSP vectors with the new LSP vector */
1392 2438 : Copy( lsp_new, &( hTdCngEnc->cng_lsp_hist_fx[( hTdCngEnc->cng_hist_ptr ) * M] ), M );
1393 :
1394 : /*-----------------------------------------------------------------*
1395 : * Find CNG spectral envelope
1396 : * Find LSP median
1397 : *-----------------------------------------------------------------*/
1398 2438 : test();
1399 2438 : test();
1400 2438 : IF( ( EQ_32( st_fx->core_brate, SID_2k40 ) || EQ_32( st_fx->core_brate, SID_1k75 ) ) && GE_16( hDtxEnc->cng_cnt, sub( hDtxEnc->cng_hist_size, 1 ) ) )
1401 : {
1402 232 : set32_fx( max_val, 0, 2 );
1403 232 : set16_fx( max_idx, 0, 2 );
1404 :
1405 2088 : FOR( i = 0; i < hDtxEnc->cng_hist_size; i++ )
1406 : {
1407 1856 : IF( EQ_16( st_fx->L_frame, L_FRAME ) )
1408 : {
1409 672 : lsp2lsf_fx( &hTdCngEnc->cng_lsp_hist_fx[i * M], lsf_tmp, M, INT_FS_FX );
1410 672 : ftmp_fx = 964; /*(6400/(M+1))X2.56*/
1411 672 : move16(); /*QX2.56 */
1412 672 : tmpv = sub( 16384, add( lsf_tmp[M - 1], ftmp_fx ) ); /*QX2.56 */
1413 672 : L_tmp = L_mult0( tmpv, tmpv ); /*QX6.5536 */
1414 : }
1415 : ELSE
1416 : {
1417 1184 : lsp2lsf_fx( &hTdCngEnc->cng_lsp_hist_fx[i * M], lsf_tmp, M, INT_FS_16k );
1418 1184 : ftmp_fx = 1205; /*(8000/(M+1))X2.56*/
1419 1184 : move16(); /*QX2.56 */
1420 1184 : tmpv = sub( 20480, add( lsf_tmp[M - 1], ftmp_fx ) ); /*QX2.56 */
1421 1184 : L_tmp = L_mult0( tmpv, tmpv ); /*QX6.5536 */
1422 : }
1423 :
1424 1856 : tmpv = sub( lsf_tmp[0], ftmp_fx ); /*QX2.56 */
1425 1856 : L_tmp = L_mac0( L_tmp, tmpv, tmpv ); /*QX6.5536 */
1426 29696 : FOR( j = 0; j < M - 1; j++ )
1427 : {
1428 27840 : tmpv = sub( sub( lsf_tmp[j + 1], lsf_tmp[j] ), ftmp_fx ); /*QX2.56 */
1429 27840 : L_tmp = L_mac0( L_tmp, tmpv, tmpv ); /*QX6.5536 */
1430 : }
1431 :
1432 1856 : C[i] = Mpy_32_16_1( L_tmp, 1928 );
1433 1856 : move32(); /*QX6.5536 */
1434 :
1435 1856 : IF( GT_32( C[i], max_val[0] ) )
1436 : {
1437 617 : max_val[1] = max_val[0];
1438 617 : move32();
1439 617 : max_idx[1] = max_idx[0];
1440 617 : move16();
1441 617 : max_val[0] = C[i];
1442 617 : move32();
1443 617 : max_idx[0] = i;
1444 617 : move16();
1445 : }
1446 1239 : ELSE IF( GT_32( C[i], max_val[1] ) )
1447 : {
1448 387 : max_val[1] = C[i];
1449 387 : move32();
1450 387 : max_idx[1] = i;
1451 387 : move16();
1452 : }
1453 : }
1454 :
1455 3944 : FOR( i = 0; i < M; i++ )
1456 : {
1457 3712 : L_tmp = 0;
1458 3712 : move32();
1459 33408 : FOR( j = 0; j < hDtxEnc->cng_hist_size; j++ )
1460 : {
1461 29696 : L_tmp = L_add( L_tmp, L_deposit_l( hTdCngEnc->cng_lsp_hist_fx[j * M + i] ) ); /*Q15 */
1462 : }
1463 :
1464 3712 : L_tmp = L_sub( L_tmp, L_add( L_deposit_l( hTdCngEnc->cng_lsp_hist_fx[max_idx[0] * M + i] ), L_deposit_l( hTdCngEnc->cng_lsp_hist_fx[max_idx[1] * M + i] ) ) ); /*Q15 */
1465 3712 : tmpv = div_s( 1, sub( hDtxEnc->cng_hist_size, 2 ) ); /*Q15 */
1466 3712 : L_tmp = Mpy_32_16_1( L_tmp, tmpv ); /*Q15 */
1467 3712 : lsp_new[i] = extract_l( L_tmp ); /*Q15 */
1468 3712 : move16();
1469 : }
1470 232 : max_idx1[0] = max_idx[0];
1471 232 : move16();
1472 232 : max_idx1[1] = max_idx[1];
1473 232 : move16();
1474 : }
1475 :
1476 : /*-----------------------------------------------------------------*
1477 : * Quantize CNG spectral envelope (only in SID frame)
1478 : * Quantize the LSF vector
1479 : *-----------------------------------------------------------------*/
1480 2438 : *allow_cn_step = 0;
1481 2438 : move16();
1482 2438 : test();
1483 2438 : test();
1484 2438 : test();
1485 2438 : test();
1486 2438 : test();
1487 2438 : test();
1488 2438 : IF( ( ( hDtxEnc->cng_cnt == 0 ) &&
1489 : GT_16( hTdCngEnc->lp_sp_enr_fx, 1536 /* 6.0, Q8 */ ) &&
1490 : ( LT_16( add( st_lp_sp_enr, 1024 /* 4.0, Q8 */ ), sp_enr ) ) &&
1491 : ( hDtxEnc->first_CNG != 0 ) &&
1492 : ( hTdCngEnc->old_enr_index >= 0 ) &&
1493 : ( GT_32( st_fx->last_core_brate, SID_2k40 ) ) ) ||
1494 : EQ_16( force_cn_step, 1 ) )
1495 : {
1496 0 : *allow_cn_step = 1;
1497 0 : move16();
1498 : }
1499 :
1500 : /* Initialize the CNG spectral envelope in case of the very first CNG frame */
1501 2438 : IF( hDtxEnc->first_CNG == 0 )
1502 : {
1503 28 : Copy( st_fx->lsp_old_fx, hDtxEnc->lspCNG_fx, M );
1504 :
1505 : /* Average the CNG spectral envelope in case of the very first CNG frame */
1506 28 : IF( st_fx->element_mode != EVS_MONO )
1507 : {
1508 476 : FOR( i = 0; i < M; i++ )
1509 : {
1510 : /*lsp_new[i] = 0.5f * (lsp_mid[i] + lsp_new[i]);*/
1511 448 : lsp_new[i] = mac_r( L_mult( lsp_mid[i], 16384 /*.5f Q15*/ ), lsp_new[i], 16384 /*.5f Q15*/ );
1512 448 : move16();
1513 : }
1514 : }
1515 : }
1516 :
1517 :
1518 2438 : test();
1519 2438 : IF( EQ_32( st_fx->core_brate, SID_2k40 ) || EQ_32( st_fx->core_brate, SID_1k75 ) )
1520 : {
1521 : /* LSF quantization */
1522 447 : IF( st_fx->Opt_AMR_WB != 0 )
1523 : {
1524 0 : isf_enc_amr_wb_fx( st_fx, lsf_new, lsp_new, 0 );
1525 : }
1526 : ELSE
1527 : {
1528 447 : lsf_enc_ivas_fx( st_fx, lsf_new, lsp_new, NULL, NULL, 0, 0, NULL, Q_new );
1529 : }
1530 : /* Reset CNG history if CNG frame length is changed */
1531 447 : test();
1532 447 : test();
1533 447 : if ( EQ_16( st_fx->bwidth, WB ) && hDtxEnc->first_CNG != 0 && NE_16( st_fx->L_frame, hDtxEnc->last_CNG_L_frame ) )
1534 : {
1535 4 : hTdCngEnc->ho_hist_size = 0;
1536 4 : move16();
1537 : }
1538 : }
1539 : ELSE
1540 : {
1541 : /* Use old LSP vector */
1542 1991 : Copy( st_fx->lsp_old_fx, lsp_new, M );
1543 1991 : Copy( st_fx->lsf_old_fx, lsf_new, M );
1544 : }
1545 :
1546 : /*---------------------------------------------------------------------*
1547 : * CNG spectral envelope update
1548 : * Find A(z) coefficients
1549 : *---------------------------------------------------------------------*/
1550 2438 : test();
1551 2438 : test();
1552 2438 : IF( ( st_fx->last_core_brate == FRAME_NO_DATA ) || EQ_32( st_fx->last_core_brate, SID_1k75 ) || EQ_32( st_fx->last_core_brate, SID_2k40 ) )
1553 : {
1554 : /* Reset hangover counter if not first SID period */
1555 2223 : if ( st_fx->core_brate > FRAME_NO_DATA )
1556 : {
1557 232 : hTdCngEnc->num_ho = 0;
1558 232 : move16();
1559 : }
1560 : /* Update LSPs if last SID energy not outlier or insufficient number of hangover frames */
1561 2223 : test();
1562 2223 : IF( LT_16( hTdCngEnc->num_ho, 3 ) || LT_32( Mult_32_16( hTdCngEnc->Enew_fx, 21845 /*1/1.5f, Q15*/ ), hTdCngEnc->lp_ener_fx ) )
1563 : {
1564 37757 : FOR( i = 0; i < M; i++ )
1565 : {
1566 : /* AR low-pass filter */
1567 35536 : hDtxEnc->lspCNG_fx[i] = mac_r( L_mult( CNG_ISF_FACT_FX, hDtxEnc->lspCNG_fx[i] ), 32768 /*1f Q15*/ - CNG_ISF_FACT_FX, lsp_new[i] );
1568 35536 : move16(); /* Q15 (15+15+1-16) */
1569 : }
1570 : }
1571 : }
1572 : ELSE
1573 : {
1574 : /* Update CNG_mode if allowed */
1575 215 : test();
1576 215 : test();
1577 215 : test();
1578 215 : test();
1579 215 : IF( ( st_fx->element_mode == EVS_MONO ) && ( ( st_fx->Opt_AMR_WB || EQ_16( st_fx->bwidth, WB ) ) && ( !hDtxEnc->first_CNG || GE_16( hTdCngEnc->act_cnt2, MIN_ACT_CNG_UPD ) ) ) )
1580 : {
1581 0 : IF( GT_32( hDtxEnc->last_active_brate, ACELP_16k40 ) )
1582 : {
1583 0 : hDtxEnc->CNG_mode = -1;
1584 0 : move16();
1585 : }
1586 : ELSE
1587 : {
1588 0 : hDtxEnc->CNG_mode = get_cng_mode( hDtxEnc->last_active_brate );
1589 0 : move16();
1590 : }
1591 : }
1592 :
1593 : /* If first sid after active burst update LSF history from circ buffer */
1594 215 : hTdCngEnc->burst_ho_cnt = s_min( hTdCngEnc->burst_ho_cnt, hTdCngEnc->ho_circ_size );
1595 215 : move16();
1596 215 : hTdCngEnc->act_cnt = 0;
1597 215 : move16();
1598 215 : s_ptr = add( sub( hTdCngEnc->ho_circ_ptr, hTdCngEnc->burst_ho_cnt ), 1 );
1599 :
1600 215 : if ( s_ptr < 0 )
1601 : {
1602 27 : s_ptr = add( s_ptr, hTdCngEnc->ho_circ_size );
1603 : }
1604 :
1605 478 : FOR( ll = hTdCngEnc->burst_ho_cnt; ll > 0; ll-- )
1606 : {
1607 263 : hTdCngEnc->ho_hist_ptr = add( hTdCngEnc->ho_hist_ptr, 1 );
1608 263 : move16();
1609 263 : if ( EQ_16( hTdCngEnc->ho_hist_ptr, HO_HIST_SIZE ) )
1610 : {
1611 32 : hTdCngEnc->ho_hist_ptr = 0;
1612 32 : move16();
1613 : }
1614 :
1615 : /* Conversion between 12.8k and 16k LSPs */
1616 263 : test();
1617 263 : test();
1618 263 : IF( EQ_16( st_fx->L_frame, L_FRAME ) && EQ_16( hTdCngEnc->ho_16k_lsp[s_ptr], 1 ) )
1619 : {
1620 : /* Conversion from 16k LPSs to 12k8 */
1621 0 : lsp_convert_poly_fx( &( hTdCngEnc->ho_lsp_circ_fx[s_ptr * M] ), st_fx->L_frame, 0 );
1622 : }
1623 263 : ELSE IF( EQ_16( st_fx->L_frame, L_FRAME16k ) && hTdCngEnc->ho_16k_lsp[s_ptr] == 0 )
1624 : {
1625 : /* 16k LSPs already converted and stored, just copy to the other buffer */
1626 62 : Copy( &( hTdCngEnc->ho_lsp_circ2_fx[s_ptr * M] ), &( hTdCngEnc->ho_lsp_circ_fx[s_ptr * M] ), M );
1627 : }
1628 : /* update the circular buffers */
1629 263 : Copy( &( hTdCngEnc->ho_lsp_circ_fx[s_ptr * M] ), &( hTdCngEnc->ho_lsp_hist_fx[hTdCngEnc->ho_hist_ptr * M] ), M );
1630 263 : Copy32( &( hTdCngEnc->ho_ener_circ_fx[s_ptr] ), &( hTdCngEnc->ho_ener_hist_fx[hTdCngEnc->ho_hist_ptr] ), 1 );
1631 263 : hTdCngEnc->ho_sid_bw = L_shl( L_and( hTdCngEnc->ho_sid_bw, (Word32) 0x3fffffffL ), 1 );
1632 263 : move32();
1633 263 : Copy32( &( hTdCngEnc->ho_env_circ_fx[s_ptr * NUM_ENV_CNG] ), &( hTdCngEnc->ho_env_hist_fx[hTdCngEnc->ho_hist_ptr * NUM_ENV_CNG] ), NUM_ENV_CNG );
1634 :
1635 263 : hTdCngEnc->ho_hist_size = add( hTdCngEnc->ho_hist_size, 1 );
1636 263 : move16();
1637 263 : if ( GT_16( hTdCngEnc->ho_hist_size, HO_HIST_SIZE ) )
1638 : {
1639 32 : hTdCngEnc->ho_hist_size = HO_HIST_SIZE;
1640 32 : move16();
1641 : }
1642 :
1643 263 : s_ptr = add( s_ptr, 1 );
1644 :
1645 263 : if ( EQ_16( s_ptr, hTdCngEnc->ho_circ_size ) )
1646 : {
1647 30 : s_ptr = 0;
1648 30 : move16();
1649 : }
1650 : }
1651 :
1652 215 : IF( hTdCngEnc->burst_ho_cnt > 0 )
1653 : {
1654 : /**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 );*/
1655 53 : w_temp = W_msu_32_16( W_shl( W_deposit32_l( hTdCngEnc->ho_ener_hist_fx[hTdCngEnc->ho_hist_ptr] ), 2 ), hTdCngEnc->lp_ener_fx, lp_ener_thr_scale ); /*Q8*/
1656 :
1657 53 : test();
1658 53 : test();
1659 53 : IF( ( hDtxEnc->first_CNG > 0 || ( st_fx->element_mode == EVS_MONO ) ) && w_temp > 0 )
1660 : {
1661 11 : *allow_cn_step = s_or( *allow_cn_step, 1 );
1662 11 : move16();
1663 : }
1664 : }
1665 215 : test();
1666 215 : IF( *allow_cn_step == 0 && hTdCngEnc->ho_hist_size > 0 )
1667 : {
1668 : /* Use average of energies below last energy */
1669 168 : ptr = hTdCngEnc->ho_hist_ptr;
1670 168 : move16();
1671 168 : Copy( &( hTdCngEnc->ho_lsp_hist_fx[ptr * M] ), tmp, M );
1672 168 : m1 = 0;
1673 168 : move16();
1674 168 : IF( L_and( hTdCngEnc->ho_sid_bw, 1 ) == 0 )
1675 : {
1676 42 : Copy32( &hTdCngEnc->ho_env_hist_fx[ptr * NUM_ENV_CNG], tmp_env, NUM_ENV_CNG );
1677 42 : m1 = 1;
1678 42 : move16();
1679 : }
1680 168 : L_ener = Mult_32_16( hTdCngEnc->ho_ener_hist_fx[ptr], W_DTX_HO_FX[0] ); /* Q6+15-15->Q6 */
1681 :
1682 168 : weights = W_DTX_HO_FX[0]; /* Q15 */
1683 168 : move16();
1684 168 : m = 1;
1685 168 : move16();
1686 794 : FOR( k = 1; k < hTdCngEnc->ho_hist_size; k++ )
1687 : {
1688 626 : ptr = sub( ptr, 1 );
1689 626 : if ( ptr < 0 )
1690 : {
1691 18 : ptr = HO_HIST_SIZE - 1;
1692 18 : move16();
1693 : }
1694 :
1695 626 : test();
1696 626 : IF( LT_32( Mult_32_16( hTdCngEnc->ho_ener_hist_fx[ptr], ONE_OVER_BUF_H_NRG_FX ), hTdCngEnc->ho_ener_hist_fx[hTdCngEnc->ho_hist_ptr] ) &&
1697 : GT_32( hTdCngEnc->ho_ener_hist_fx[ptr], Mult_32_16( hTdCngEnc->ho_ener_hist_fx[hTdCngEnc->ho_hist_ptr], BUF_L_NRG_FX ) ) )
1698 : {
1699 : /*enr += W_DTX_HO[k] * st_fx->ho_ener_hist[ptr]; */
1700 302 : L_tmp1 = Mult_32_16( hTdCngEnc->ho_ener_hist_fx[ptr], W_DTX_HO_FX[k] ); /* Q6+15-15->Q6 */
1701 302 : L_ener = L_add( L_ener, L_tmp1 ); /* Q6 */
1702 :
1703 : /*weights += W_DTX_HO[k]; */
1704 302 : weights = add( weights, W_DTX_HO_FX[k] ); /* Q15 */
1705 :
1706 302 : Copy( &hTdCngEnc->ho_lsp_hist_fx[ptr * M], &tmp[m * M], M );
1707 302 : IF( L_and( hTdCngEnc->ho_sid_bw, L_shl( 1, k ) ) == 0 )
1708 : {
1709 22 : Copy32( &hTdCngEnc->ho_env_hist_fx[ptr * NUM_ENV_CNG], &tmp_env[m1 * NUM_ENV_CNG], NUM_ENV_CNG );
1710 22 : m1 = add( m1, 1 );
1711 : }
1712 302 : m = add( m, 1 );
1713 : }
1714 : }
1715 :
1716 : /*enr /= weights; */
1717 168 : exp = norm_s( weights );
1718 168 : tmp1 = div_s( shl( 1, sub( 14, exp ) ), weights ); /* Q(15+14-exp-15) */
1719 168 : L_tmp1 = Mult_32_16( L_ener, tmp1 ); /* Q(14-exp+6-15)->Q(5-exp) */
1720 168 : L_ener = L_shl( L_tmp1, add( exp, 1 ) ); /* Q6 */
1721 :
1722 168 : hTdCngEnc->lp_ener_fx = L_ener;
1723 168 : move32(); /* Q6 */
1724 :
1725 168 : set32_fx( max_val, 0, 2 );
1726 168 : set16_fx( max_idx, 0, 2 );
1727 :
1728 638 : FOR( i = 0; i < m; i++ )
1729 : {
1730 470 : IF( EQ_16( st_fx->L_frame, L_FRAME ) )
1731 : {
1732 226 : lsp2lsf_fx( &tmp[i * M], lsf_tmp, M, INT_FS_FX );
1733 226 : ftmp_fx = 964; /*(6400/(M+1))X2.56*/
1734 226 : move16(); /*QX2.56 */
1735 226 : tmpv = sub( 16384, add( lsf_tmp[M - 1], ftmp_fx ) ); /*QX2.56 */
1736 226 : L_tmp = L_mult0( tmpv, tmpv ); /*QX6.5536 */
1737 : }
1738 : ELSE
1739 : {
1740 244 : lsp2lsf_fx( &tmp[i * M], lsf_tmp, M, INT_FS_16k );
1741 244 : ftmp_fx = 1205; /*(8000/(M+1))X2.56*/
1742 244 : move16(); /*QX2.56 */
1743 244 : tmpv = sub( 20480, add( lsf_tmp[M - 1], ftmp_fx ) ); /*QX2.56 */
1744 244 : L_tmp = L_mult0( tmpv, tmpv ); /*QX6.5536 */
1745 : }
1746 :
1747 470 : tmpv = sub( lsf_tmp[0], ftmp_fx ); /*QX2.56 */
1748 470 : L_tmp = L_mac0( L_tmp, tmpv, tmpv ); /*QX6.5536 */
1749 7520 : FOR( j = 0; j < M - 1; j++ )
1750 : {
1751 7050 : tmpv = sub( sub( lsf_tmp[j + 1], lsf_tmp[j] ), ftmp_fx ); /*QX2.56 */
1752 7050 : L_tmp = L_mac0( L_tmp, tmpv, tmpv ); /*QX6.5536 */
1753 : }
1754 :
1755 470 : C[i] = Mpy_32_16_1( L_tmp, 1928 );
1756 470 : move32(); /*QX6.5536 */
1757 :
1758 470 : IF( GT_32( C[i], max_val[0] ) )
1759 : {
1760 284 : max_val[1] = max_val[0];
1761 284 : move32();
1762 284 : max_idx[1] = max_idx[0];
1763 284 : move16();
1764 284 : max_val[0] = C[i];
1765 284 : move32();
1766 284 : max_idx[0] = i;
1767 284 : move16();
1768 : }
1769 186 : ELSE IF( GT_32( C[i], max_val[1] ) )
1770 : {
1771 99 : max_val[1] = C[i];
1772 99 : move32();
1773 99 : max_idx[1] = i;
1774 99 : move16();
1775 : }
1776 : }
1777 :
1778 168 : IF( EQ_16( m, 1 ) )
1779 : {
1780 58 : Copy( tmp, lsp_tmp, M );
1781 : }
1782 110 : ELSE IF( LT_16( m, 4 ) )
1783 : {
1784 1037 : FOR( i = 0; i < M; i++ )
1785 : {
1786 976 : L_tmp = L_deposit_l( 0 );
1787 3424 : FOR( j = 0; j < m; j++ )
1788 : {
1789 2448 : L_tmp = L_add( L_tmp, L_deposit_l( tmp[j * M + i] ) );
1790 : }
1791 :
1792 976 : L_tmp = L_sub( L_tmp, L_deposit_l( tmp[max_idx[0] * M + i] ) );
1793 976 : tmpv = div_s( 1, sub( m, 1 ) ); /*Q15 */
1794 976 : L_tmp = Mpy_32_16_1( L_tmp, tmpv ); /*Q15 */
1795 976 : lsp_tmp[i] = extract_l( L_tmp ); /*Q15 */
1796 976 : move16();
1797 : }
1798 : }
1799 : ELSE
1800 : {
1801 833 : FOR( i = 0; i < M; i++ )
1802 : {
1803 784 : L_tmp = L_deposit_l( 0 );
1804 4928 : FOR( j = 0; j < m; j++ )
1805 : {
1806 4144 : L_tmp = L_add( L_tmp, L_deposit_l( tmp[j * M + i] ) );
1807 : }
1808 :
1809 784 : L_tmp = L_sub( L_tmp, L_add( L_deposit_l( tmp[max_idx[0] * M + i] ), L_deposit_l( tmp[max_idx[1] * M + i] ) ) ); /*Q15 */
1810 784 : tmpv = div_s( 1, sub( m, 2 ) ); /*Q15 */ /*Q15 */
1811 784 : L_tmp = Mpy_32_16_1( L_tmp, tmpv ); /*Q15 */ /*Q15 */
1812 784 : lsp_tmp[i] = extract_l( L_tmp ); /*Q15 */ /*Q15 */
1813 784 : move16();
1814 : }
1815 : }
1816 :
1817 168 : dist = 0; /*Q15 */
1818 168 : move32();
1819 168 : max_dev = 0; /*Q15 */
1820 168 : move32();
1821 2856 : FOR( i = 0; i < M; i++ )
1822 : {
1823 2688 : dev = L_abs( L_sub( L_deposit_l( lsp_tmp[i] ), L_deposit_l( lsp_new[i] ) ) ); /*Q15 */
1824 2688 : dist = L_add( dist, dev ); /*Q15 */
1825 2688 : if ( GT_32( dev, max_dev ) )
1826 : {
1827 860 : max_dev = dev;
1828 860 : move32();
1829 : }
1830 : }
1831 :
1832 168 : test();
1833 168 : IF( GT_32( dist, 13107 ) || GT_32( max_dev, 3277 ) )
1834 : {
1835 153 : FOR( i = 0; i < M; i++ )
1836 : {
1837 144 : hDtxEnc->lspCNG_fx[i] = lsp_tmp[i];
1838 144 : move16(); /*Q15 */
1839 : }
1840 : }
1841 : ELSE
1842 : {
1843 2703 : FOR( i = 0; i < M; i++ )
1844 : {
1845 : /* AR low-pass filter */
1846 2544 : hDtxEnc->lspCNG_fx[i] = add( mult_r( 26214 /*.8f Q15*/, lsp_tmp[i] ), mult_r( 6554 /*.2f Q15*/, lsp_new[i] ) ); /* Q15 */
1847 2544 : move16();
1848 : }
1849 : }
1850 168 : IF( m1 > 0 )
1851 : {
1852 882 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
1853 : {
1854 840 : L_tmp = L_deposit_l( 0 );
1855 2120 : FOR( j = 0; j < m1; j++ )
1856 : {
1857 : /* env[i] += tmp_env[j*NUM_ENV_CNG+i]; */
1858 1280 : L_tmp = L_add_sat( L_tmp, tmp_env[j * NUM_ENV_CNG + i] );
1859 : }
1860 : /* env[i] /= (float)m1; */
1861 : /* env[i] = env[i] - 2*hTdCngEnc->lp_ener_fx; */
1862 840 : IF( EQ_16( m1, 1 ) )
1863 : {
1864 700 : L_tmp = L_sub_sat( L_tmp, L_add_sat( hTdCngEnc->lp_ener_fx, hTdCngEnc->lp_ener_fx ) );
1865 : }
1866 : ELSE
1867 : {
1868 140 : tmp1 = div_s( 1, m1 );
1869 140 : L_tmp = Mult_32_16( L_tmp, tmp1 );
1870 140 : L_tmp = L_sub_sat( L_tmp, L_add_sat( hTdCngEnc->lp_ener_fx, hTdCngEnc->lp_ener_fx ) );
1871 : }
1872 :
1873 840 : env[i] = L_tmp; /* Q6*/
1874 840 : move32();
1875 : }
1876 42 : Copy32( env, hTdCngEnc->lp_env_fx, NUM_ENV_CNG ); /* Q6 */
1877 : }
1878 : }
1879 : ELSE
1880 : {
1881 47 : Copy( lsp_new, hDtxEnc->lspCNG_fx, M ); /* use newly analyzed ISFs */ /* Q15 */
1882 : }
1883 : }
1884 2438 : IF( st_fx->Opt_AMR_WB != 0 )
1885 : {
1886 0 : E_LPC_f_isp_a_conversion( hDtxEnc->lspCNG_fx, Aq, M );
1887 : }
1888 : ELSE
1889 : {
1890 2438 : E_LPC_f_lsp_a_conversion( hDtxEnc->lspCNG_fx, Aq, M );
1891 2438 : exp = sub( Q14, norm_s( Aq[0] ) );
1892 2438 : Scale_sig( Aq, M + 1, sub( Q12, exp ) ); // Q12
1893 : }
1894 :
1895 2438 : tmp_loop = shr( st_fx->L_frame, 6 );
1896 11291 : FOR( i = 1; i < tmp_loop; i++ )
1897 : {
1898 8853 : Copy( Aq, &Aq[i * ( M + 1 )], M + 1 );
1899 : }
1900 : /*-----------------------------------------------------------------*
1901 : * Find residual signal
1902 : * Calculate residual signal energy per sample
1903 : *-----------------------------------------------------------------*/
1904 :
1905 : /* calculate the residual signal */
1906 2438 : Residu3_fx( Aq, speech, res, st_fx->L_frame, 0 );
1907 2438 : Copy( res, res1, st_fx->L_frame ); /* Q_new */
1908 2438 : test();
1909 2438 : IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) )
1910 : {
1911 2438 : L_tmp1 = L_mult0( hTdCngEnc->CNG_att_fx, 26214 /* 1/20.0f in Q19 */ ); // Q26 (7 + 19)
1912 2438 : L_tmp1 = BASOP_Util_fPow( 1342177280 /*10 in Q27 */, 4, L_tmp1, 5, &exp );
1913 2438 : att = extract_h( L_shl( L_sub( L_tmp1, EPSILON_FX ), exp ) ); // Q15 // Subtracting by EPSILON_FX to avoid assertion when L_tmp1 value is 1073741824 and exp =1
1914 2438 : v_multc_fixed_16_16( res1, att, res1, st_fx->L_frame ); /* Q_new */
1915 : }
1916 0 : ELSE IF( st_fx->bwidth != NB )
1917 : {
1918 0 : test();
1919 0 : IF( EQ_16( st_fx->bwidth, WB ) && hDtxEnc->CNG_mode >= 0 )
1920 : {
1921 0 : ftmp_fx = HO_ATT_FX[hDtxEnc->CNG_mode];
1922 0 : move16();
1923 : }
1924 : ELSE
1925 : {
1926 0 : ftmp_fx = 19661; /*.6f in Q15*/
1927 0 : move16();
1928 : }
1929 :
1930 0 : att = mult( ftmp_fx, 5461 ); /* Q15 */
1931 0 : L_tmp = L_mult( att, 8 ); /* Q16 */
1932 0 : tmp1 = extract_l( L_shr( L_tmp, 2 ) ); /* Q14 */
1933 0 : tmp1 = add( 16384, tmp1 );
1934 0 : att = div_s( 16374, tmp1 ); /* Q15 */
1935 :
1936 0 : att = s_max( att, ftmp_fx );
1937 0 : FOR( i = 0; i < st_fx->L_frame; i++ )
1938 : {
1939 : /*res1[i] *= att;*/
1940 0 : res1[i] = mult( res1[i], att );
1941 0 : move16(); /* Q_new */
1942 : }
1943 0 : att = shr( att, 7 ); /* Q8 */
1944 : }
1945 :
1946 : /* calculate the spectrum of residual signal */
1947 2438 : Copy( res1, fft_io, st_fx->L_frame ); /* Q_new */
1948 :
1949 2438 : IF( EQ_16( st_fx->L_frame, L_FRAME16k ) )
1950 : {
1951 1539 : modify_Fs_fx( fft_io, L_FRAME16k, 16000, fft_io, 12800, hTdCngEnc->exc_mem2_fx, 0 );
1952 : }
1953 :
1954 2438 : fft_rel_fx( fft_io, L_FFT, LOG2_L_FFT );
1955 2438 : ptR = &fft_io[1];
1956 2438 : ptI = &fft_io[L_FFT - 1];
1957 51198 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
1958 : {
1959 : /* env[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */
1960 : #ifdef ISSUE_1867_replace_overflow_libenc
1961 48760 : L_tmp = L_mult_sat( *ptR, *ptR ); /* 2*Q_new+1 */
1962 48760 : L_tmp = L_add_sat( L_tmp, L_mult_sat( *ptI, *ptI ) ); /* 2*Q_new+1 */
1963 48760 : L_tmp = L_add_sat( L_tmp, L_tmp ); /* 2*Q_new+1 */
1964 : #else
1965 : L_tmp = L_mult_o( *ptR, *ptR, &Overflow ); /* 2*Q_new+1 */
1966 : L_tmp = L_add_o( L_tmp, L_mult_o( *ptI, *ptI, &Overflow ), &Overflow ); /* 2*Q_new+1 */
1967 : L_tmp = L_add_o( L_tmp, L_tmp, &Overflow ); /* 2*Q_new+1 */
1968 : #endif
1969 48760 : L_tmp = Mult_32_16( L_tmp, 128 ); /* 2*Q_new+1 */
1970 48760 : tmp1 = add( add( Q_new, Q_new ), 1 );
1971 48760 : env[i] = L_shr( L_tmp, sub( tmp1, 6 ) );
1972 48760 : move32(); /* Q6 */
1973 48760 : ptR++;
1974 48760 : ptI--;
1975 : }
1976 :
1977 2438 : Copy32( env, &( hTdCngEnc->cng_res_env_fx[( hTdCngEnc->cng_hist_ptr ) * NUM_ENV_CNG] ), NUM_ENV_CNG );
1978 :
1979 : /* calculate the residual signal energy */
1980 : /*enr = dotp( res, res, L_frame ) / L_frame; */
1981 2438 : w_temp = 1;
1982 2438 : move64();
1983 725062 : FOR( j = 0; j < st_fx->L_frame; j++ )
1984 : {
1985 722624 : w_temp = W_mac0_16_16( w_temp, res[j], res[j] );
1986 : }
1987 2438 : exp = W_norm( w_temp );
1988 :
1989 2438 : SWITCH( st_fx->L_frame )
1990 : {
1991 0 : case L_FRAME25_6k:
1992 0 : inv_frame_len = ONE_BY_L_FRAME25_6k_Q31;
1993 0 : move16();
1994 0 : BREAK;
1995 899 : case L_FRAME:
1996 899 : inv_frame_len = ONE_BY_L_FRAME_Q31;
1997 899 : move16();
1998 899 : BREAK;
1999 0 : case L_FRAME48k:
2000 0 : inv_frame_len = ONE_BY_L_FRAME48k_Q31;
2001 0 : move16();
2002 0 : BREAK;
2003 0 : case 240:
2004 0 : inv_frame_len = ONE_BY_240_Q31;
2005 0 : move16();
2006 0 : BREAK;
2007 0 : case L_FRAME32k:
2008 0 : inv_frame_len = ONE_BY_L_FRAME32k_Q31;
2009 0 : move16();
2010 0 : BREAK;
2011 1539 : case L_FRAME16k:
2012 1539 : inv_frame_len = ONE_BY_L_FRAME16k_Q31;
2013 1539 : move16();
2014 1539 : BREAK;
2015 0 : case L_FRAME8k:
2016 0 : inv_frame_len = ONE_BY_L_FRAME8k_Q31;
2017 0 : move16();
2018 0 : BREAK;
2019 0 : case L_FRAME4k:
2020 0 : inv_frame_len = ONE_BY_L_FRAME4k_Q31;
2021 0 : move16();
2022 0 : BREAK;
2023 0 : default:
2024 0 : inv_frame_len = divide3216( 1, st_fx->L_frame );
2025 : }
2026 2438 : L_ener = W_extract_h( W_shl( w_temp, exp ) ); /* Q = 2*Q_new+exp-32 */
2027 2438 : L_ener = Mpy_32_32( L_ener, inv_frame_len ); /* Q = 2*Q_new+exp-32 */
2028 2438 : L_ener = L_shl( L_ener, sub( 33, exp ) ); /* Q = 2*Q_new+1 */
2029 :
2030 : /* convert log2 of residual signal energy */
2031 : /*enr = (float)log10( enr + 0.1f ) / (float)log10( 2.0f ); */
2032 :
2033 2438 : IF( L_ener == 0 )
2034 : {
2035 0 : enr = -850; /*log(0.1) base 2 in Q8*/
2036 0 : move16();
2037 : }
2038 : ELSE
2039 : {
2040 2438 : hi = norm_l( L_ener );
2041 2438 : lo = Log2_norm_lc( L_shl( L_ener, hi ) );
2042 2438 : hi = sub( 29, hi ); /* log2 exp in Q2*Q_new */
2043 2438 : hi = sub( hi, shl( Q_new, 1 ) ); /* Q0 */
2044 2438 : L_tmp = L_Comp( hi, lo ); /* Q16 */
2045 2438 : enr = round_fx( L_shl( L_tmp, 8 ) ); /* Q8 (16+8-16) */
2046 : }
2047 : /* update the circular buffer of old energies */
2048 2438 : hTdCngEnc->cng_ener_hist_fx[hTdCngEnc->cng_hist_ptr] = enr;
2049 2438 : move16(); /* Q8 */
2050 :
2051 : /*-----------------------------------------------------------------*
2052 : * Quantize residual signal energy (only in SID frame)
2053 : *-----------------------------------------------------------------*/
2054 2438 : test();
2055 2438 : IF( EQ_32( st_fx->core_brate, SID_2k40 ) || EQ_32( st_fx->core_brate, SID_1k75 ) )
2056 : {
2057 447 : IF( GE_16( hDtxEnc->cng_cnt, sub( hDtxEnc->cng_hist_size, 1 ) ) )
2058 : {
2059 : /* average the envelope except outliers */
2060 4872 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
2061 : {
2062 4640 : L_tmp1 = L_add( env[i], 0 );
2063 41760 : FOR( j = 0; j < hDtxEnc->cng_hist_size; j++ )
2064 : {
2065 37120 : L_tmp1 = L_add_sat( L_tmp1, hTdCngEnc->cng_res_env_fx[j * NUM_ENV_CNG + i] );
2066 : }
2067 4640 : L_tmp = L_add( hTdCngEnc->cng_res_env_fx[max_idx1[0] * NUM_ENV_CNG + i], hTdCngEnc->cng_res_env_fx[max_idx1[1] * NUM_ENV_CNG + i] );
2068 4640 : L_tmp1 = L_sub( L_tmp1, L_tmp );
2069 :
2070 : /* env[i] /= (float)(st_fx->cng_hist_size - 2); */
2071 4640 : tmp1 = sub( hDtxEnc->cng_hist_size, 2 );
2072 4640 : IF( GT_16( tmp1, 1 ) )
2073 : {
2074 4640 : tmp1 = div_s( 1, tmp1 );
2075 4640 : L_tmp1 = Mult_32_16( L_tmp1, tmp1 );
2076 : }
2077 :
2078 4640 : env[i] = L_tmp1;
2079 4640 : move32();
2080 : }
2081 : /* compute average excitation energy */
2082 232 : L_tmp = L_deposit_l( 0 );
2083 232 : ptr = hTdCngEnc->cng_hist_ptr;
2084 232 : move16();
2085 :
2086 2088 : FOR( k = 0; k < hDtxEnc->cng_hist_size; k++ )
2087 : {
2088 : /* enr += W_HIST[k]*cng_ener_hist[ptr] */
2089 1856 : L_tmp = L_mac0( L_tmp, W_HIST_FX[k], hTdCngEnc->cng_ener_hist_fx[ptr] ); /* Q24 (8+16) */
2090 1856 : ptr = sub( ptr, 1 );
2091 1856 : if ( ptr < 0 ) /* check for circular pointer */
2092 : {
2093 232 : ptr = DTX_HIST_SIZE - 1;
2094 232 : move16();
2095 : }
2096 : }
2097 : /*-----------------------------------------------------------
2098 : * here we want to divide L_tmp by the sum
2099 : * of all the coefs used W_HIST[0..cng_hist_size-1]
2100 : * The table W_HIST_S already contains the inverted sum.
2101 : * That is
2102 : * W_HIST_S[k] 1
2103 : * ------------- = ---------------------------
2104 : * 4096 W_HIST[0] + ... + W_HIST[k]
2105 : *
2106 : * 1 / Sum(W_HIST[0..k]) is always > 1 since the sum
2107 : * of the coefs 0..k is always < 1 but > 0
2108 : * enr is in Q8 since the history buffer constains Q8 energies
2109 : *-----------------------------------------------------------*/
2110 : /*L_tmp = Mpy_32_16_1(L_tmp, W_HIST_S_FX[k-1]); */ /* normalize average value */
2111 232 : L_tmp = Mult_32_16( L_tmp, W_HIST_S_FX[k - 1] ); /* Q21 (24+12+1-16) */
2112 232 : L_tmp = L_shl( L_tmp, 3 ); /* Q24 */
2113 232 : enr = round_fx( L_tmp ); /* Q8 */
2114 : }
2115 : /* decrease the energy in case of WB input */
2116 447 : test();
2117 447 : IF( EQ_16( st_fx->element_mode, IVAS_SCE ) || EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) )
2118 : {
2119 447 : enr = add( enr, mult( hTdCngEnc->CNG_att_fx, FAC_LOG2_BY10_Q16 ) ); /* Q8 (Q7 + Q16 - Q15)*/
2120 : }
2121 0 : ELSE IF( st_fx->bwidth != NB )
2122 : {
2123 0 : IF( EQ_16( st_fx->bwidth, WB ) )
2124 : {
2125 0 : IF( hDtxEnc->CNG_mode >= 0 )
2126 : {
2127 : /* Bitrate adapted attenuation */
2128 0 : att = ENR_ATT_fx[hDtxEnc->CNG_mode];
2129 0 : move16();
2130 : }
2131 : ELSE
2132 : {
2133 : /* Use least attenuation for higher bitrates */
2134 0 : att = ENR_ATT_fx[4];
2135 0 : move16();
2136 : }
2137 : }
2138 : ELSE
2139 : {
2140 0 : att = 384;
2141 0 : move16(); /*1.5f Q8*/
2142 : }
2143 0 : enr = sub( enr, att );
2144 : }
2145 : /* intialize the energy quantization parameters */
2146 447 : IF( st_fx->Opt_AMR_WB == 0 )
2147 : {
2148 447 : step = STEP_SID_FX; // Q12
2149 447 : move16();
2150 447 : step_inv = ISTEP_SID_FX;
2151 447 : move16();
2152 447 : maxl = 127;
2153 447 : move16();
2154 447 : num_bits = 7;
2155 447 : move16();
2156 : }
2157 : ELSE
2158 : {
2159 0 : step = STEP_AMR_WB_SID_FX;
2160 0 : move16();
2161 0 : step_inv = ISTEP_AMR_WB_SID_FX;
2162 0 : move16();
2163 0 : maxl = 63;
2164 0 : move16();
2165 0 : num_bits = 6;
2166 0 : move16();
2167 : }
2168 :
2169 : /* calculate the energy quantization index */
2170 447 : enr_index = add( enr, 512 /* Q8(2.0) */ ); /* enr + 2.0 */
2171 447 : enr_index = extract_l( L_shr( L_mult0( enr_index, step ), 12 + 8 ) ); /* Q0 (8+12-(8+12)) */
2172 :
2173 : /* limit the energy quantization index */
2174 447 : enr_index = s_min( enr_index, maxl );
2175 447 : enr_index = s_max( enr_index, 0 );
2176 :
2177 : /* allow only slow energy increase */
2178 447 : test();
2179 447 : IF( hTdCngEnc->old_enr_index >= 0 && GT_16( enr_index, add( hTdCngEnc->old_enr_index, MAX_DELTA ) ) )
2180 : {
2181 75 : IF( *allow_cn_step != 0 )
2182 : {
2183 0 : tmp1 = mult( 27853 /* Q15(0.85) */, sub( enr_index, hTdCngEnc->old_enr_index ) );
2184 0 : enr_index = add( hTdCngEnc->old_enr_index, tmp1 );
2185 : }
2186 : ELSE
2187 : {
2188 75 : enr_index = add( hTdCngEnc->old_enr_index, MAX_DELTA );
2189 : }
2190 : }
2191 447 : hTdCngEnc->old_enr_index = enr_index;
2192 447 : move16();
2193 :
2194 447 : push_indice( hBstr, IND_ENERGY, enr_index, num_bits );
2195 447 : if ( enr_index == 0 )
2196 : {
2197 26 : enr_index = -5;
2198 26 : move16();
2199 : }
2200 : /* Find quantized energy */
2201 : /* *Enew = (float)enr_index / step - 2.0 */
2202 : /* *Enew = (float)pow(2.0, *Enew) */
2203 447 : L_tmp = L_mult( enr_index, step_inv ); /* Q16(0+15+1) */
2204 : /* substract by 2 not done to leave Energy in Q2 */
2205 447 : lo = L_Extract_lc( L_tmp, &hi );
2206 447 : hTdCngEnc->Enew_fx = Pow2( add( hi, 4 ), lo ); /* Q6 */
2207 447 : move32();
2208 447 : IF( EQ_32( st_fx->core_brate, SID_2k40 ) )
2209 : {
2210 : /* enr1 = (float)log10( st->Enew*L_frame + 0.1f ) / (float)log10( 2.0f );*/
2211 447 : exp = norm_l( hTdCngEnc->Enew_fx );
2212 447 : L_tmp = L_shl( hTdCngEnc->Enew_fx, exp ); /*Q(exp+6) */
2213 447 : L_tmp = Mult_32_16( L_tmp, shl( st_fx->L_frame, 5 ) ); /* Q(exp+6+5-15=exp-4) */
2214 :
2215 447 : L_tmp = L_shr_sat( L_tmp, sub( exp, 10 ) ); /* Q6 */
2216 :
2217 447 : exp = norm_l( L_tmp );
2218 447 : fra = Log2_norm_lc( L_shl( L_tmp, exp ) );
2219 447 : exp = sub( sub( 30, exp ), 6 );
2220 447 : L_tmp = L_Comp( exp, fra );
2221 447 : enr1 = L_shr( L_tmp, 10 ); /* Q6 */
2222 :
2223 9387 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
2224 : {
2225 : /* env[i] -= 2 * st->Enew;*/
2226 8940 : L_tmp1 = L_add( env[i], 0 );
2227 8940 : L_tmp = L_add( hTdCngEnc->Enew_fx, hTdCngEnc->Enew_fx );
2228 8940 : L_tmp1 = L_sub( L_tmp1, L_tmp ); /*Q6*/
2229 :
2230 8940 : IF( L_tmp1 < 0 )
2231 : {
2232 7152 : L_tmp1 = L_deposit_l( 6 ); /* (0.1)Q6 */
2233 : }
2234 : /* env[i] = (float)log10( env[i] + 0.1f ) / (float)log10( 2.0f ); */
2235 8940 : exp = norm_l( L_tmp1 );
2236 8940 : fra = Log2_norm_lc( L_shl( L_tmp1, exp ) );
2237 8940 : exp = sub( sub( 30, exp ), 6 );
2238 8940 : L_tmp = L_Comp( exp, fra );
2239 8940 : L_tmp1 = L_shr( L_tmp, 10 ); /* Q6 */
2240 :
2241 8940 : L_tmp = L_shr( L_deposit_l( att ), 2 ); /* Q6 */
2242 8940 : L_tmp1 = L_sub( L_tmp1, L_tmp );
2243 :
2244 8940 : IF( L_tmp1 < 0 )
2245 : {
2246 8940 : L_tmp1 = L_deposit_l( 0 );
2247 : }
2248 :
2249 8940 : L_tmp1 = L_sub( enr1, L_tmp1 );
2250 :
2251 8940 : env[i] = L_tmp1;
2252 8940 : move32();
2253 : }
2254 :
2255 : /* codebook search */
2256 447 : min1 = 1310588928; /* 9999.0f Q17 */
2257 447 : move32();
2258 447 : min1_idx = 0;
2259 447 : move16();
2260 :
2261 29055 : FOR( i = 0; i < 64; i++ )
2262 : {
2263 28608 : d = L_deposit_l( 0 );
2264 600768 : FOR( j = 0; j < NUM_ENV_CNG; j++ )
2265 : {
2266 : /* d += (env[j] - CNG_details_codebook_fx[i][j]) * (env[j] - CNG_details_codebook_fx[i][j]);*/
2267 572160 : L_tmp = L_sub( env[j], L_deposit_l( CNG_details_codebook_fx[i][j] ) ); /* Q6 */
2268 572160 : exp = norm_l( L_tmp );
2269 572160 : L_tmp = L_shl( L_tmp, exp ); /*Q(exp+6)*/
2270 572160 : tmp1 = extract_h( L_tmp ); /*Q(exp+6-16)=exp-10*/
2271 : #ifdef ISSUE_1867_replace_overflow_libenc
2272 572160 : L_tmp = L_mult_sat( tmp1, tmp1 ); /*Q(2*exp - 19)*/
2273 : #else
2274 : L_tmp = L_mult_o( tmp1, tmp1, &Overflow ); /*Q(2*exp - 19)*/
2275 : #endif
2276 572160 : L_tmp = L_shr( L_tmp, sub( add( exp, exp ), 36 ) ); /* Q17 */
2277 572160 : d = L_add( d, L_tmp ); /* Q17 */
2278 : }
2279 :
2280 28608 : IF( LT_32( d, min1 ) )
2281 : {
2282 4085 : min1 = d;
2283 4085 : move32();
2284 4085 : min1_idx = i;
2285 4085 : move16();
2286 : }
2287 : }
2288 447 : push_indice( hBstr, IND_CNG_ENV1, min1_idx, 6 );
2289 : /* get quantized res_env_details */
2290 9387 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
2291 : {
2292 8940 : q_env[i] = L_deposit_l( CNG_details_codebook_fx[min1_idx][i] );
2293 8940 : move32();
2294 : }
2295 : }
2296 : /* Update hangover memory during CNG */
2297 447 : test();
2298 447 : IF( *allow_cn_step == 0 && LT_32( Mult_32_16( hTdCngEnc->Enew_fx, 21845 /*1/1.5f, Q15*/ ), hTdCngEnc->lp_ener_fx ) )
2299 : {
2300 : /* update the pointer to circular buffer of old LSP vectors */
2301 376 : hTdCngEnc->ho_hist_ptr = add( hTdCngEnc->ho_hist_ptr, 1 );
2302 376 : move16();
2303 376 : if ( EQ_16( hTdCngEnc->ho_hist_ptr, HO_HIST_SIZE ) )
2304 : {
2305 36 : hTdCngEnc->ho_hist_ptr = 0;
2306 36 : move16();
2307 : }
2308 :
2309 : /* update the circular buffer of old LSP vectors with the new LSP vector */
2310 376 : Copy( lsp_new, &( hTdCngEnc->ho_lsp_hist_fx[( hTdCngEnc->ho_hist_ptr ) * M] ), M );
2311 :
2312 : /* update the hangover energy buffer */
2313 376 : hTdCngEnc->ho_ener_hist_fx[hTdCngEnc->ho_hist_ptr] = hTdCngEnc->Enew_fx;
2314 376 : move32();
2315 376 : IF( EQ_32( st_fx->core_brate, SID_2k40 ) )
2316 : {
2317 7896 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
2318 : {
2319 : /* get quantized envelope */
2320 : /* env[i] = pow(2.0f,(enr1 - q_env[i])) + 2*st->Enew;*/
2321 7520 : L_tmp = L_sub( enr1, q_env[i] ); /* Q6 */
2322 7520 : L_tmp = L_shl( L_tmp, 10 ); /* 16 */
2323 7520 : temp_lo_fx = L_Extract_lc( L_tmp, &temp_hi_fx );
2324 :
2325 7520 : exp_pow = sub( 14, temp_hi_fx );
2326 7520 : L_tmp = Pow2( 14, temp_lo_fx ); /* Qexp_pow */
2327 7520 : env[i] = L_shl( L_tmp, sub( 6, exp_pow ) );
2328 7520 : move32(); /* Q6 */
2329 7520 : L_tmp = L_add( hTdCngEnc->Enew_fx, hTdCngEnc->Enew_fx );
2330 7520 : env[i] = L_add( env[i], L_tmp );
2331 7520 : move32(); /* Q6 */
2332 : }
2333 376 : Copy32( env, &( hTdCngEnc->ho_env_hist_fx[( hTdCngEnc->ho_hist_ptr ) * NUM_ENV_CNG] ), NUM_ENV_CNG );
2334 : }
2335 376 : hTdCngEnc->ho_hist_size = add( hTdCngEnc->ho_hist_size, 1 );
2336 376 : move16();
2337 376 : if ( GT_16( hTdCngEnc->ho_hist_size, HO_HIST_SIZE ) )
2338 : {
2339 231 : hTdCngEnc->ho_hist_size = HO_HIST_SIZE;
2340 231 : move16();
2341 : }
2342 : }
2343 : }
2344 : /* dithering bit for AMR-WB IO mode is always set to 0 */
2345 2438 : IF( EQ_32( st_fx->core_brate, SID_1k75 ) )
2346 : {
2347 0 : push_indice( hBstr, IND_DITHERING, 0, 1 );
2348 : }
2349 2438 : IF( EQ_32( st_fx->core_brate, SID_2k40 ) )
2350 : {
2351 447 : IF( EQ_16( st_fx->L_frame, L_FRAME16k ) )
2352 : {
2353 277 : push_indice( hBstr, IND_ACELP_16KHZ, 1, 1 );
2354 : }
2355 : ELSE
2356 : {
2357 170 : push_indice( hBstr, IND_ACELP_16KHZ, 0, 1 );
2358 : }
2359 :
2360 447 : push_indice( hBstr, IND_CNG_HO, s_min( hTdCngEnc->burst_ho_cnt, HO_HIST_SIZE - 1 ), 3 );
2361 447 : hTdCngEnc->num_ho = m;
2362 447 : move16();
2363 447 : push_indice( hBstr, IND_SID_TYPE, 0, 1 );
2364 :
2365 447 : test();
2366 447 : IF( LT_32( st_fx->input_Fs, 32000 ) && NE_16( st_fx->element_mode, IVAS_CPE_DFT ) )
2367 : {
2368 0 : push_indice( hBstr, IND_SID_BW, 0, 1 );
2369 0 : *sid_bw = 0;
2370 0 : move16();
2371 : }
2372 : }
2373 :
2374 : /*-----------------------------------------------------------------*
2375 : * Updates
2376 : *-----------------------------------------------------------------*/
2377 : /* update the SID frames counter */
2378 2438 : test();
2379 2438 : IF( EQ_32( st_fx->core_brate, SID_2k40 ) || EQ_32( st_fx->core_brate, SID_1k75 ) )
2380 : {
2381 447 : hDtxEnc->cng_cnt = 0;
2382 447 : move16();
2383 447 : hTdCngEnc->cng_hist_ptr = -1;
2384 447 : move16();
2385 : /* update frame length memory */
2386 447 : hDtxEnc->last_CNG_L_frame = st_fx->L_frame;
2387 447 : move16();
2388 : }
2389 : ELSE
2390 : {
2391 1991 : hDtxEnc->cng_cnt = add( hDtxEnc->cng_cnt, 1 );
2392 1991 : move16();
2393 : }
2394 :
2395 2438 : return;
2396 : }
2397 : /*---------------------------------------------------------------------*
2398 : * swb_CNG_enc()
2399 : *
2400 : * SWB DTX/CNG encoding
2401 : *---------------------------------------------------------------------*/
2402 0 : void swb_CNG_enc_fx(
2403 : Encoder_State *st_fx, /* i/o: State structure */
2404 : const Word16 *shb_speech_fx, /* i : SHB target signal (6-14kHz) at 16kHz (Q0) */
2405 : const Word16 *syn_12k8_16k_fx /* i : ACELP core synthesis at 12.8kHz or 16kHz (st_fx->Q_syn = 0) */
2406 : )
2407 : {
2408 0 : Word16 shb_SID_updt_fx = 0;
2409 0 : move16();
2410 0 : TD_CNG_ENC_HANDLE hTdCngEnc = st_fx->hTdCngEnc;
2411 :
2412 0 : test();
2413 0 : IF( EQ_32( st_fx->core_brate, SID_2k40 ) || st_fx->core_brate == FRAME_NO_DATA )
2414 : {
2415 0 : IF( EQ_16( st_fx->cng_type, LP_CNG ) )
2416 : {
2417 0 : IF( GE_32( st_fx->input_Fs, L_FRAME32k * FRAMES_PER_SEC ) )
2418 : {
2419 : /* decide if SHB SID encoding or not */
2420 0 : shb_SID_updt_fx = shb_DTX_fx( st_fx, shb_speech_fx, syn_12k8_16k_fx );
2421 :
2422 : /* SHB CNG encoding */
2423 0 : shb_CNG_encod_fx( st_fx, shb_SID_updt_fx );
2424 : }
2425 0 : ELSE IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) && EQ_32( st_fx->core_brate, SID_2k40 ) )
2426 : {
2427 : }
2428 : }
2429 0 : hTdCngEnc->last_vad = 0;
2430 0 : move16();
2431 : }
2432 : ELSE
2433 : {
2434 0 : hTdCngEnc->last_vad = 1;
2435 0 : move16();
2436 : }
2437 :
2438 0 : return;
2439 : }
2440 :
2441 : /*---------------------------------------------------------------------*
2442 : * shb_CNG_encod()
2443 : *
2444 : * SID parameters encoding for SHB signal
2445 : *---------------------------------------------------------------------*/
2446 0 : static void shb_CNG_encod_fx(
2447 : Encoder_State *st_fx, /* i/o: State structure */
2448 : const Word16 update_fx /* i : SID update flag */
2449 : )
2450 : {
2451 : Word16 idx_ener_fx;
2452 0 : TD_CNG_ENC_HANDLE hTdCngEnc = st_fx->hTdCngEnc;
2453 0 : BSTR_ENC_HANDLE hBstr = st_fx->hBstr;
2454 :
2455 0 : idx_ener_fx = 0;
2456 0 : move16();
2457 0 : IF( EQ_16( update_fx, 1 ) )
2458 : {
2459 : /* SHB energy quantization */
2460 0 : IF( EQ_16( st_fx->element_mode, EVS_MONO ) )
2461 : {
2462 0 : idx_ener_fx = shr( add( mult( hTdCngEnc->mov_shb_cng_ener_fx, 9797 ), 1510 ), 8 ); /* Q0 */
2463 : }
2464 : ELSE
2465 : {
2466 : }
2467 :
2468 0 : if ( LT_16( st_fx->bwidth, SWB ) )
2469 : {
2470 0 : idx_ener_fx = 0;
2471 0 : move16();
2472 : }
2473 :
2474 0 : IF( GT_16( idx_ener_fx, 15 ) )
2475 : {
2476 0 : idx_ener_fx = 15;
2477 0 : move16();
2478 : }
2479 : ELSE
2480 : {
2481 0 : idx_ener_fx = s_max( idx_ener_fx, 0 );
2482 : }
2483 :
2484 0 : push_indice( hBstr, IND_SHB_CNG_GAIN, idx_ener_fx, 4 );
2485 0 : push_indice( hBstr, IND_SID_BW, 1, 1 );
2486 0 : delete_indice( hBstr, IND_CNG_ENV1 );
2487 0 : move16();
2488 0 : move16();
2489 :
2490 0 : if ( st_fx->element_mode == IVAS_CPE_DFT )
2491 : {
2492 : }
2493 : else
2494 : {
2495 0 : push_indice( hBstr, IND_UNUSED, 0, 2 );
2496 : }
2497 0 : hTdCngEnc->ho_sid_bw = L_shl( L_and( hTdCngEnc->ho_sid_bw, (Word32) 0x3fffffffL ), 1 );
2498 0 : hTdCngEnc->ho_sid_bw = L_or( hTdCngEnc->ho_sid_bw, 0x1L );
2499 0 : move32();
2500 0 : move32();
2501 : }
2502 : ELSE
2503 : {
2504 0 : IF( EQ_32( st_fx->core_brate, SID_2k40 ) )
2505 : {
2506 0 : hTdCngEnc->ho_sid_bw = L_shl( L_and( hTdCngEnc->ho_sid_bw, (Word32) 0x3fffffffL ), 1 );
2507 0 : push_indice( hBstr, IND_SID_BW, 0, 1 );
2508 : }
2509 : }
2510 :
2511 0 : return;
2512 : }
2513 :
2514 : /*---------------------------------------------------------------------*
2515 : * shb_DTX()
2516 : *
2517 : * Decide if encoding SHB SID or not
2518 : *---------------------------------------------------------------------*/
2519 0 : static Word16 shb_DTX_fx(
2520 : Encoder_State *st_fx, /* i/o: State structure */
2521 : const Word16 *shb_speech_fx, /* i : SHB target signal (6-14kHz) at 16kHz (Q0) */
2522 : const Word16 *syn_12k8_16k /* i : ACELP core synthesis at 12.8kHz or 16kHz (st_fx->Q_syn = 0) */
2523 : )
2524 : {
2525 : Word16 i;
2526 : Word16 update_fx;
2527 : Word16 shb_old_speech_fx[( ACELP_LOOK_12k8 + L_SUBFR + L_FRAME ) * 5 / 4];
2528 : Word16 *shb_new_speech_fx;
2529 : Word32 wb_ener_fx;
2530 : Word32 shb_ener_fx;
2531 : Word16 log_wb_ener_fx;
2532 : Word16 log_shb_ener_fx;
2533 : Word16 tmp;
2534 : Word16 exp;
2535 : Word16 fra;
2536 : Word16 att; /*Q8*/
2537 0 : Word16 allow_cn_step_fx = 0;
2538 0 : move16();
2539 0 : DTX_ENC_HANDLE hDtxEnc = st_fx->hDtxEnc;
2540 0 : TD_CNG_ENC_HANDLE hTdCngEnc = st_fx->hTdCngEnc;
2541 0 : TD_BWE_ENC_HANDLE hBWE_TD = st_fx->hBWE_TD;
2542 : #ifndef ISSUE_1867_replace_overflow_libenc
2543 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
2544 : Flag Overflow = 0;
2545 : move32();
2546 : #endif
2547 : #endif
2548 0 : shb_new_speech_fx = shb_old_speech_fx + ( ACELP_LOOK_12k8 + L_SUBFR ) * 5 / 4;
2549 0 : Copy( hBWE_TD->old_speech_shb_fx, shb_old_speech_fx, ( ACELP_LOOK_12k8 + L_SUBFR ) * 5 / 4 );
2550 0 : Copy( shb_speech_fx, shb_new_speech_fx, L_FRAME16k );
2551 0 : Copy( shb_old_speech_fx + L_FRAME16k, hBWE_TD->old_speech_shb_fx, ( ACELP_LOOK_12k8 + L_SUBFR ) * 5 / 4 );
2552 :
2553 0 : shb_ener_fx = L_deposit_l( 0 );
2554 0 : FOR( i = 0; i < L_FRAME16k; i++ )
2555 : {
2556 0 : shb_ener_fx = L_mac_sat( shb_ener_fx, shb_old_speech_fx[i], shb_old_speech_fx[i] );
2557 : }
2558 :
2559 0 : shb_ener_fx = L_add( Mpy_32_16_1( shb_ener_fx, 102 ), 1 ); /* 102 in Q15, shb_ener_fx in Q1 */
2560 :
2561 0 : wb_ener_fx = L_deposit_l( 0 );
2562 0 : FOR( i = 0; i < st_fx->L_frame; i++ )
2563 : {
2564 : #ifdef ISSUE_1867_replace_overflow_libenc
2565 0 : wb_ener_fx = L_mac_sat( wb_ener_fx, syn_12k8_16k[i], syn_12k8_16k[i] );
2566 : #else
2567 : wb_ener_fx = L_mac_o( wb_ener_fx, syn_12k8_16k[i], syn_12k8_16k[i], &Overflow );
2568 : #endif
2569 : }
2570 :
2571 0 : wb_ener_fx = L_add( Mpy_32_16_1( wb_ener_fx, 128 ), 1 ); /* 128 in Q15, wb_ener_fx in Q1 */
2572 :
2573 0 : exp = norm_l( wb_ener_fx );
2574 0 : fra = Log2_norm_lc( L_shl( wb_ener_fx, exp ) );
2575 0 : exp = sub( 30 - 1, exp );
2576 0 : wb_ener_fx = Mpy_32_16( exp, fra, LG10 );
2577 : #ifdef ISSUE_1867_replace_overflow_libenc
2578 0 : log_wb_ener_fx = round_fx_sat( L_shl_sat( wb_ener_fx, 10 ) ); /* log_wb_ener_fx in Q8 */
2579 : #else
2580 : log_wb_ener_fx = round_fx_o( L_shl_o( wb_ener_fx, 10, &Overflow ), &Overflow ); /* log_wb_ener_fx in Q8 */
2581 : #endif
2582 0 : exp = norm_l( shb_ener_fx );
2583 0 : fra = Log2_norm_lc( L_shl( shb_ener_fx, exp ) );
2584 0 : exp = sub( 30 - 1, exp );
2585 0 : shb_ener_fx = Mpy_32_16( exp, fra, LG10 );
2586 :
2587 0 : test();
2588 0 : IF( EQ_16( st_fx->element_mode, IVAS_SCE ) || EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) )
2589 : {
2590 0 : att = 0;
2591 0 : move16();
2592 : // PMT("apply_scale is not implemented")
2593 : }
2594 : ELSE
2595 : {
2596 0 : att = 1664; /*6.5 in Q8*/
2597 0 : move16();
2598 : }
2599 :
2600 : #ifdef ISSUE_1867_replace_overflow_libenc
2601 0 : log_shb_ener_fx = sub_sat( round_fx_sat( L_shl_sat( shb_ener_fx, 10 ) ), att ); /* log_shb_ener_fx in Q8 */
2602 : #else
2603 : log_shb_ener_fx = sub_o( round_fx_o( L_shl_o( shb_ener_fx, 10, &Overflow ), &Overflow ), att, &Overflow ); /* log_shb_ener_fx in Q8 */
2604 : #endif
2605 0 : IF( hDtxEnc->first_CNG == 0 )
2606 : {
2607 0 : hTdCngEnc->mov_wb_cng_ener_fx = log_wb_ener_fx;
2608 0 : move16();
2609 0 : hTdCngEnc->mov_shb_cng_ener_fx = log_shb_ener_fx;
2610 0 : move16();
2611 0 : hTdCngEnc->last_wb_cng_ener_fx = log_wb_ener_fx;
2612 0 : move16();
2613 0 : hTdCngEnc->last_shb_cng_ener_fx = log_shb_ener_fx;
2614 0 : move16();
2615 : }
2616 :
2617 0 : if ( GT_16( abs_s( sub( log_wb_ener_fx, hTdCngEnc->mov_wb_cng_ener_fx ) ), 3072 /*12.0f Q8*/ ) )
2618 : {
2619 0 : allow_cn_step_fx = 1;
2620 0 : move16();
2621 : }
2622 :
2623 0 : IF( EQ_16( allow_cn_step_fx, 1 ) )
2624 : {
2625 0 : hTdCngEnc->mov_wb_cng_ener_fx = log_wb_ener_fx;
2626 0 : move16();
2627 0 : hTdCngEnc->mov_shb_cng_ener_fx = log_shb_ener_fx;
2628 0 : move16();
2629 : }
2630 : ELSE
2631 : {
2632 0 : tmp = sub( log_wb_ener_fx, hTdCngEnc->mov_wb_cng_ener_fx ); /* Q8 */
2633 0 : tmp = mult( tmp, 29491 /*.9f in Q15*/ ); /* Q8 */
2634 0 : hTdCngEnc->mov_wb_cng_ener_fx = add( hTdCngEnc->mov_wb_cng_ener_fx, tmp ); /* Q8 */
2635 0 : move16();
2636 0 : tmp = sub( log_shb_ener_fx, hTdCngEnc->mov_shb_cng_ener_fx );
2637 0 : tmp = mult( tmp, 8192 /*.25f in Q15*/ ); /* Q8 */
2638 0 : hTdCngEnc->mov_shb_cng_ener_fx = add( hTdCngEnc->mov_shb_cng_ener_fx, tmp ); /* Q8 */
2639 0 : move16();
2640 : }
2641 0 : hTdCngEnc->shb_NO_DATA_cnt = add( hTdCngEnc->shb_NO_DATA_cnt, 1 );
2642 0 : move16();
2643 0 : update_fx = 0;
2644 0 : move16();
2645 0 : IF( EQ_32( st_fx->core_brate, SID_2k40 ) )
2646 : {
2647 0 : test();
2648 0 : test();
2649 0 : IF( hDtxEnc->first_CNG == 0 || EQ_16( hTdCngEnc->last_vad, 1 ) || GE_16( hTdCngEnc->shb_NO_DATA_cnt, 100 ) )
2650 : {
2651 0 : update_fx = 1;
2652 0 : move16();
2653 : }
2654 : ELSE
2655 : {
2656 0 : IF( hTdCngEnc->shb_cng_ini_cnt > 0 )
2657 : {
2658 0 : update_fx = 1;
2659 0 : move16();
2660 0 : hTdCngEnc->shb_cng_ini_cnt = sub( hTdCngEnc->shb_cng_ini_cnt, 1 );
2661 0 : move16();
2662 : }
2663 : ELSE
2664 : {
2665 0 : IF( GT_16( abs_s( sub( sub( hTdCngEnc->mov_wb_cng_ener_fx, hTdCngEnc->mov_shb_cng_ener_fx ), sub( hTdCngEnc->last_wb_cng_ener_fx, hTdCngEnc->last_shb_cng_ener_fx ) ) ), 768 /*3.0f in Q8*/ ) )
2666 : {
2667 0 : update_fx = 1;
2668 0 : move16();
2669 : }
2670 : ELSE
2671 : {
2672 0 : test();
2673 0 : IF( GE_16( st_fx->bwidth, SWB ) && LT_16( hTdCngEnc->last_SID_bwidth, SWB ) )
2674 : {
2675 0 : update_fx = 1;
2676 0 : move16();
2677 : }
2678 : ELSE
2679 : {
2680 0 : test();
2681 0 : IF( LT_16( st_fx->bwidth, SWB ) && GE_16( hTdCngEnc->last_SID_bwidth, SWB ) )
2682 : {
2683 0 : update_fx = 1;
2684 0 : move16();
2685 : }
2686 : }
2687 : }
2688 : }
2689 : }
2690 :
2691 0 : hTdCngEnc->last_SID_bwidth = st_fx->bwidth;
2692 0 : move16();
2693 : }
2694 : /* LF-boost not yet implemented in decoder which means that the specific wb_sid information is not used */
2695 0 : test();
2696 0 : test();
2697 0 : if ( ( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) && EQ_32( st_fx->core_brate, SID_2k40 ) )
2698 : {
2699 0 : update_fx = 1;
2700 0 : move16();
2701 : }
2702 :
2703 0 : IF( EQ_16( update_fx, 1 ) )
2704 : {
2705 0 : hTdCngEnc->last_wb_cng_ener_fx = hTdCngEnc->mov_wb_cng_ener_fx;
2706 0 : move16();
2707 0 : hTdCngEnc->last_shb_cng_ener_fx = hTdCngEnc->mov_shb_cng_ener_fx;
2708 0 : move16();
2709 0 : hTdCngEnc->shb_NO_DATA_cnt = 0;
2710 0 : move16();
2711 : }
2712 :
2713 :
2714 0 : return ( update_fx );
2715 : }
2716 :
2717 : /*---------------------------------------------------------------------*
2718 : * calculate_hangover_attenuation_gain_fx()
2719 : *
2720 : *
2721 : *---------------------------------------------------------------------*/
2722 1423 : void calculate_hangover_attenuation_gain_fx(
2723 : Encoder_State *st, /* i : encoder state structure */
2724 : Word16 *att, /* o : attenuation factor Q15 */
2725 : const Word16 vad_hover_flag /* i : VAD hangover flag */
2726 : )
2727 : {
2728 : Word16 offset;
2729 1423 : TD_CNG_ENC_HANDLE hTdCngEnc = st->hTdCngEnc;
2730 :
2731 1423 : *att = 32767; // 1.0f in Q15
2732 :
2733 1423 : move16();
2734 : /* smoothing in case of CNG */
2735 1423 : IF( hTdCngEnc != NULL )
2736 : {
2737 1423 : test();
2738 1423 : test();
2739 1423 : test();
2740 1423 : IF( hTdCngEnc->burst_ho_cnt > 0 && ( vad_hover_flag != 0 ) && ( NE_16( st->bwidth, NB ) || st->element_mode > EVS_MONO ) ) /* corresponds to line 504 in FLT acelp_core_enc.c */
2741 : {
2742 0 : if ( st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD )
2743 : {
2744 : }
2745 : else
2746 : {
2747 0 : offset = 5;
2748 0 : move16();
2749 0 : test();
2750 0 : if ( EQ_16( st->bwidth, WB ) && st->hDtxEnc->CNG_mode >= 0 )
2751 : {
2752 0 : offset = st->hDtxEnc->CNG_mode;
2753 0 : move16();
2754 : }
2755 0 : assert( hTdCngEnc->burst_ho_cnt > 0 );
2756 0 : *att = CNG_burst_att_fx[offset][hTdCngEnc->burst_ho_cnt - 1]; /*Q15*/
2757 0 : move16();
2758 : }
2759 : }
2760 : }
2761 1423 : return;
2762 : }
2763 :
2764 184695 : void calculate_hangover_attenuation_gain_ivas_fx(
2765 : Encoder_State *st, /* i : encoder state structure */
2766 : Word16 *att, /* o : attenuation factor Q15 */
2767 : const Word16 vad_hover_flag /* i : VAD hangover flag */
2768 : )
2769 : {
2770 : Word16 lim, result_e;
2771 :
2772 184695 : *att = 32767; // 1.0f in Q15
2773 184695 : move16();
2774 :
2775 184695 : test();
2776 184695 : test();
2777 184695 : test();
2778 184695 : test();
2779 184695 : IF( st->hTdCngEnc != NULL && ( vad_hover_flag != 0 ) && GT_16( st->hTdCngEnc->burst_ho_cnt, 0 ) && ( NE_16( st->bwidth, NB ) || st->element_mode > EVS_MONO ) )
2780 : {
2781 2654 : test();
2782 2654 : IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) )
2783 2232 : {
2784 2232 : Word32 exp = Mpy_32_16_1( L_mult( 26214 /*26214 = 1 / 160.f in Q22*/, st->hTdCngEnc->burst_ho_cnt ), st->hTdCngEnc->CNG_att_fx ); /* Q15 (22 + 1 + 7 - 15) */
2785 2232 : Word32 L_tmp = BASOP_Util_fPow( 1342177280 /* 10 in Q27 */, 4, exp, 16, &result_e );
2786 2232 : *att = extract_h( L_shl_sat( L_tmp, result_e ) );
2787 2232 : move16();
2788 : }
2789 : ELSE
2790 : {
2791 422 : test();
2792 422 : IF( EQ_16( st->bwidth, WB ) && st->hDtxEnc->CNG_mode >= 0 )
2793 : {
2794 0 : lim = HO_ATT_FX[st->hDtxEnc->CNG_mode];
2795 : }
2796 : ELSE
2797 : {
2798 422 : lim = 19660; /* 0.6 in Q15*/
2799 : }
2800 422 : move16();
2801 :
2802 422 : *att = mult_r( lim, 5461 ); /* 1/6.f in Q15*/
2803 422 : move16();
2804 422 : *att = divide1616( 32767, add( 2048, imult1616( *att, st->hTdCngEnc->burst_ho_cnt ) ) ); /* 2048 = 1 in Q11*/
2805 422 : move16();
2806 :
2807 422 : if ( LT_16( *att, lim ) )
2808 : {
2809 0 : *att = lim;
2810 0 : move16();
2811 : }
2812 : }
2813 : }
2814 :
2815 184695 : return;
2816 : }
2817 :
2818 44242 : void swb_CNG_enc_ivas_fx(
2819 : Encoder_State *st, /* i/o: State structure */
2820 : const Word16 *shb_speech_fx, /* i : SHB target signal (6-14kHz) at 16kHz Q0 */
2821 : const Word16 *syn_12k8_16k_fx /* i : ACELP core synthesis at 12.8kHz or 16kHz Q0 */
2822 : )
2823 : {
2824 : Word16 shb_SID_updt;
2825 :
2826 44242 : test();
2827 44242 : IF( EQ_32( st->core_brate, SID_2k40 ) || st->core_brate == FRAME_NO_DATA )
2828 : {
2829 11699 : IF( st->cng_type == LP_CNG )
2830 : {
2831 2438 : test();
2832 2438 : IF( GE_32( st->input_Fs, L_FRAME32k * FRAMES_PER_SEC ) )
2833 : {
2834 : /* decide if SHB SID encoding or not */
2835 2084 : shb_SID_updt = shb_DTX_ivas_fx( st, shb_speech_fx, syn_12k8_16k_fx );
2836 :
2837 : /* SHB CNG encoding */
2838 2084 : shb_CNG_encod_ivas_fx( st, shb_SID_updt );
2839 : }
2840 354 : ELSE IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) && EQ_32( st->core_brate, SID_2k40 ) )
2841 : {
2842 : /* LF-boost not used in DFT-stereo, instead the bandwidth is transmitted */
2843 48 : delete_indice( st->hBstr, IND_CNG_ENV1 );
2844 48 : push_indice( st->hBstr, IND_BWIDTH, st->bwidth, 2 );
2845 48 : push_indice( st->hBstr, IND_UNUSED, 0, 4 );
2846 48 : push_indice( st->hBstr, IND_SID_BW, 1, 1 );
2847 : }
2848 : }
2849 11699 : st->hTdCngEnc->last_vad = 0;
2850 11699 : move16();
2851 : }
2852 : ELSE
2853 : {
2854 32543 : st->hTdCngEnc->last_vad = 1;
2855 32543 : move16();
2856 : }
2857 :
2858 44242 : return;
2859 : }
2860 :
2861 :
2862 : /*---------------------------------------------------------------------*
2863 : * shb_CNG_encod()
2864 : *
2865 : * SID parameters encoding for SHB signal
2866 : *---------------------------------------------------------------------*/
2867 :
2868 2084 : static void shb_CNG_encod_ivas_fx(
2869 : Encoder_State *st, /* i/o: State structure */
2870 : const Word16 update /* i : SID update flag */
2871 : )
2872 : {
2873 2084 : Word16 idx_ener = 0;
2874 2084 : move16();
2875 2084 : BSTR_ENC_HANDLE hBstr = st->hBstr;
2876 :
2877 : Word16 ener_mid_dec_thr_fx;
2878 :
2879 2084 : IF( EQ_16( update, 1 ) )
2880 : {
2881 399 : IF( st->element_mode == EVS_MONO )
2882 : {
2883 : /* 6.0 in Q8 -> 1510 */
2884 : /* 0.9 in Q15 29491 */
2885 : /* ( 1 / log10(2.0) ) * 0.1 in Q15 ->10886 */
2886 0 : idx_ener = shr( mult( add( mult( st->hTdCngEnc->mov_shb_cng_ener_fx, 10886 ), 1510 ), 29491 ), 8 ); /* Q0 */
2887 : }
2888 : ELSE
2889 : {
2890 : /*idx_ener = (int16_t)(0.7f * (0.1f * st->hTdCngEnc->mov_shb_cng_ener / (float)log10(2.0f) + 6.0f) + 0.5f);*/
2891 : // PMT("shb_CNG_encod_fx quantization in missing")
2892 : /* 6.0 in Q8 -> 1510 */
2893 : /* 0.7 in Q15 22938 */
2894 : /* ( 1 / log10(2.0) ) * 0.1 in Q15 -> 10886 */
2895 399 : idx_ener = shr( mult( add( mult( st->hTdCngEnc->mov_shb_cng_ener_fx, 10886 ), 1510 ), 22938 ), 8 ); /* Q0 */
2896 : }
2897 :
2898 :
2899 399 : if ( LT_16( st->bwidth, SWB ) )
2900 : {
2901 2 : idx_ener = 0;
2902 2 : move16();
2903 : }
2904 :
2905 399 : IF( GT_16( idx_ener, 15 ) )
2906 : {
2907 0 : idx_ener = 15;
2908 0 : move16();
2909 : }
2910 399 : ELSE IF( idx_ener < 0 )
2911 : {
2912 0 : idx_ener = 0;
2913 0 : move16();
2914 : }
2915 :
2916 : /* prevent toggling of idx_ener by adding small dead-zone interval around decision thresholds */
2917 399 : IF( st->element_mode != EVS_MONO )
2918 : {
2919 399 : IF( EQ_16( abs_s( sub( idx_ener, st->hTdCngEnc->last_idx_ener ) ), 1 ) )
2920 : {
2921 :
2922 : Word16 tmp, tmp1, tmp2, scale, exp1, exp2, ener_mid_dec_thr_e;
2923 30 : tmp = BASOP_Util_Divide1616_Scale( st->hTdCngEnc->last_idx_ener, 22938, &scale ); // 0.7 in Q15 ->exp 0
2924 30 : scale = add( scale, ( 15 - 0 ) );
2925 30 : tmp = sub( tmp, shl( 6, sub( Q15, scale ) ) );
2926 30 : tmp1 = BASOP_Util_Divide1616_Scale( tmp, 3277, &exp1 );
2927 30 : exp1 = add( exp1, ( scale - 0 ) );
2928 :
2929 30 : ener_mid_dec_thr_fx = shr( mult( tmp1, 9864 ), 1 ); // exp = exp
2930 :
2931 30 : tmp = BASOP_Util_Divide1616_Scale( idx_ener, 22938, &scale ); // 0.7 in Q15 ->exp 0
2932 30 : scale = add( scale, ( 15 - 0 ) );
2933 30 : tmp = sub( tmp, shl( 6, sub( Q15, scale ) ) );
2934 30 : tmp1 = BASOP_Util_Divide1616_Scale( tmp, 3277, &exp2 );
2935 30 : exp2 = add( exp2, ( scale - 0 ) );
2936 :
2937 30 : tmp2 = shr( mult( tmp1, 9864 ), 1 ); // exp = exp
2938 :
2939 30 : ener_mid_dec_thr_e = BASOP_Util_Add_MantExp( tmp2, exp2, ener_mid_dec_thr_fx, exp1, &ener_mid_dec_thr_fx );
2940 :
2941 :
2942 30 : scale = BASOP_Util_Add_MantExp( st->hTdCngEnc->mov_shb_cng_ener_fx, 7, negate( ener_mid_dec_thr_fx ), ener_mid_dec_thr_e, &tmp );
2943 30 : tmp1 = BASOP_Util_Divide1616_Scale( tmp, ener_mid_dec_thr_fx, &exp1 );
2944 30 : exp1 = add( exp1, sub( scale, ener_mid_dec_thr_e ) );
2945 30 : IF( LT_16( abs_s( tmp1 ), shr( 328, sub( 15, exp1 ) ) ) )
2946 : {
2947 0 : idx_ener = st->hTdCngEnc->last_idx_ener;
2948 0 : move16();
2949 : }
2950 : }
2951 : }
2952 :
2953 399 : st->hTdCngEnc->last_idx_ener = idx_ener;
2954 399 : move16();
2955 :
2956 399 : push_indice( hBstr, IND_SHB_CNG_GAIN, idx_ener, 4 );
2957 399 : push_indice( hBstr, IND_SID_BW, 1, 1 );
2958 399 : delete_indice( hBstr, IND_CNG_ENV1 );
2959 399 : IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) )
2960 : {
2961 399 : push_indice( st->hBstr, IND_BWIDTH, st->bwidth, 2 );
2962 : }
2963 : ELSE
2964 : {
2965 0 : push_indice( hBstr, IND_UNUSED, 0, 2 );
2966 : }
2967 399 : st->hTdCngEnc->ho_sid_bw = L_shl( L_and( st->hTdCngEnc->ho_sid_bw, (Word32) 0x3fffffffL ), 1 );
2968 399 : st->hTdCngEnc->ho_sid_bw = L_or( st->hTdCngEnc->ho_sid_bw, 0x1L );
2969 399 : move32();
2970 399 : move32();
2971 : }
2972 1685 : ELSE IF( EQ_32( st->core_brate, SID_2k40 ) )
2973 : {
2974 0 : st->hTdCngEnc->ho_sid_bw = L_shl( L_and( st->hTdCngEnc->ho_sid_bw, (Word32) 0x3fffffffL ), 1 );
2975 0 : move32();
2976 0 : push_indice( hBstr, IND_SID_BW, 0, 1 );
2977 : }
2978 :
2979 2084 : return;
2980 : }
2981 :
2982 : /*---------------------------------------------------------------------*
2983 : * shb_DTX()
2984 : *
2985 : * Decide if encoding SHB SID or not
2986 : *---------------------------------------------------------------------*/
2987 :
2988 2084 : static Word16 shb_DTX_ivas_fx(
2989 : Encoder_State *st, /* i/o: State structure */
2990 : const Word16 *shb_speech_fx, /* i : SHB target signal (6-14kHz) at 16kHz Q0 */
2991 : const Word16 *syn_12k8_16k_fx /* i : ACELP core synthesis at 12.8kHz or 16kHz Q0 */
2992 : )
2993 : {
2994 : Word16 i;
2995 : Word16 update;
2996 :
2997 2084 : Word16 allow_cn_step = 0;
2998 2084 : move16();
2999 : Word16 shb_old_speech_fx[( ACELP_LOOK_12k8 + L_SUBFR + L_FRAME ) * 5 / 4];
3000 : Word16 *shb_new_speech_fx;
3001 : Word32 wb_ener_fx;
3002 : Word32 shb_ener_fx;
3003 : Word16 log_wb_ener_fx;
3004 : Word16 log_shb_ener_fx;
3005 : Word16 tmp;
3006 : Word16 exp;
3007 : Word16 fra;
3008 : Word16 att_fx; /*Q8*/
3009 :
3010 2084 : TD_CNG_ENC_HANDLE hTdCngEnc = st->hTdCngEnc;
3011 2084 : TD_BWE_ENC_HANDLE hBWE_TD = st->hBWE_TD;
3012 :
3013 : #ifndef ISSUE_1867_replace_overflow_libenc
3014 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
3015 : Flag Overflow = 0;
3016 : move16();
3017 : #endif
3018 : #endif
3019 :
3020 2084 : shb_new_speech_fx = shb_old_speech_fx + ( ACELP_LOOK_12k8 + L_SUBFR ) * 5 / 4;
3021 2084 : Copy( hBWE_TD->old_speech_shb_fx, shb_old_speech_fx, ( ACELP_LOOK_12k8 + L_SUBFR ) * 5 / 4 ); // old_speech_shb_fx -> Q0
3022 2084 : Copy( shb_speech_fx, shb_new_speech_fx, L_FRAME16k ); // Q0
3023 2084 : Copy( shb_old_speech_fx + L_FRAME16k, hBWE_TD->old_speech_shb_fx, ( ACELP_LOOK_12k8 + L_SUBFR ) * 5 / 4 ); // Q0
3024 :
3025 2084 : shb_ener_fx = L_deposit_l( 0 );
3026 668964 : FOR( i = 0; i < L_FRAME16k; i++ )
3027 : {
3028 666880 : shb_ener_fx = L_mac_sat( shb_ener_fx, shb_old_speech_fx[i], shb_old_speech_fx[i] ); // ( Q0 + Q0 + Q1 ) --> Q1 due to left shift in L_mac
3029 : }
3030 :
3031 2084 : shb_ener_fx = L_add( Mpy_32_16_1( shb_ener_fx, 102 ), 1 ); /* ( 1 / L_FRAME16K ) -> 102 in Q15, shb_ener_fx in Q1 */
3032 :
3033 2084 : wb_ener_fx = L_deposit_l( 0 );
3034 611428 : FOR( i = 0; i < st->L_frame; i++ )
3035 : {
3036 : #ifdef ISSUE_1867_replace_overflow_libenc
3037 609344 : wb_ener_fx = L_mac_sat( wb_ener_fx, syn_12k8_16k_fx[i], syn_12k8_16k_fx[i] ); // ( Q0 + Q0 + Q1 ) --> Q1 due to left shift in L_mac
3038 : #else
3039 : wb_ener_fx = L_mac_o( wb_ener_fx, syn_12k8_16k_fx[i], syn_12k8_16k_fx[i], &Overflow ); // ( Q0 + Q0 + Q1 ) --> Q1 due to left shift in L_mac
3040 : #endif
3041 : }
3042 :
3043 2084 : wb_ener_fx = L_add( Mpy_32_16_1( wb_ener_fx, 128 ), 1 ); /* 128 in Q15, wb_ener_fx in Q1 */
3044 :
3045 2084 : exp = norm_l( wb_ener_fx );
3046 2084 : fra = Log2_norm_lc( L_shl( wb_ener_fx, exp ) );
3047 2084 : exp = sub( 30 - 1, exp );
3048 2084 : wb_ener_fx = Mpy_32_16( exp, fra, LG10 );
3049 :
3050 : #ifdef ISSUE_1867_replace_overflow_libenc
3051 2084 : log_wb_ener_fx = round_fx_sat( L_shl_sat( wb_ener_fx, 10 ) ); /* log_wb_ener_fx in Q8 */
3052 : #else
3053 : log_wb_ener_fx = round_fx_o( L_shl_o( wb_ener_fx, 10, &Overflow ), &Overflow ); /* log_wb_ener_fx in Q8 */
3054 : #endif
3055 2084 : exp = norm_l( shb_ener_fx );
3056 2084 : fra = Log2_norm_lc( L_shl( shb_ener_fx, exp ) );
3057 2084 : exp = sub( 30 - 1, exp );
3058 2084 : shb_ener_fx = Mpy_32_16( exp, fra, LG10 );
3059 :
3060 :
3061 2084 : test();
3062 2084 : IF( EQ_16( st->element_mode, IVAS_SCE ) || EQ_16( st->element_mode, IVAS_CPE_DFT ) )
3063 2084 : {
3064 2084 : Word32 att_fx32 = 0;
3065 2084 : move32();
3066 : Word16 index;
3067 :
3068 2084 : apply_scale_ivas_fx( &att_fx32, st->hFdCngEnc->hFdCngCom->CngBandwidth, st->hFdCngEnc->hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO, &index ); // Q23;
3069 :
3070 2084 : att_fx = extract_l( L_shr( att_fx32, 15 ) ); // Q8
3071 : }
3072 : ELSE
3073 : {
3074 0 : att_fx = -1664; // Q8
3075 0 : move16();
3076 : }
3077 :
3078 : #ifdef ISSUE_1867_replace_overflow_libenc
3079 2084 : log_shb_ener_fx = sub_sat( round_fx_sat( L_shl_sat( shb_ener_fx, 10 ) ), att_fx ); /* log_shb_ener_fx in Q8 */
3080 : #else
3081 : log_shb_ener_fx = sub_o( round_fx_o( L_shl_o( shb_ener_fx, 10, &Overflow ), &Overflow ), att_fx, &Overflow ); /* log_shb_ener_fx in Q8 */
3082 : #endif
3083 :
3084 2084 : IF( st->hDtxEnc->first_CNG == 0 )
3085 : {
3086 :
3087 :
3088 22 : hTdCngEnc->mov_wb_cng_ener_fx = log_wb_ener_fx; // Q8
3089 22 : hTdCngEnc->mov_shb_cng_ener_fx = log_shb_ener_fx; // Q8
3090 22 : hTdCngEnc->last_wb_cng_ener_fx = log_wb_ener_fx; // Q8
3091 22 : hTdCngEnc->last_shb_cng_ener_fx = log_shb_ener_fx; // Q8
3092 22 : move16();
3093 22 : move16();
3094 22 : move16();
3095 22 : move16();
3096 : }
3097 2084 : IF( GT_16( abs_s( sub( log_wb_ener_fx, hTdCngEnc->mov_wb_cng_ener_fx ) ), 3072 /*12 in Q8*/ ) )
3098 : {
3099 20 : allow_cn_step = 1;
3100 20 : move16();
3101 : }
3102 :
3103 : /* Also allow step if shb energy has dropped 12 dB */
3104 2084 : test();
3105 2084 : test();
3106 2084 : IF( ( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) && GT_16( sub( hTdCngEnc->mov_shb_cng_ener_fx, log_shb_ener_fx ), 3072 /*12 in Q8*/ ) )
3107 : {
3108 21 : allow_cn_step = 1;
3109 21 : move16();
3110 : }
3111 :
3112 2084 : IF( EQ_16( allow_cn_step, 1 ) )
3113 : {
3114 22 : hTdCngEnc->mov_wb_cng_ener_fx = log_wb_ener_fx;
3115 22 : hTdCngEnc->mov_shb_cng_ener_fx = log_shb_ener_fx;
3116 22 : move16();
3117 22 : move16();
3118 : }
3119 : ELSE
3120 : {
3121 2062 : tmp = sub( log_wb_ener_fx, hTdCngEnc->mov_wb_cng_ener_fx ); /* Q8 */
3122 2062 : tmp = mult( tmp, 29491 /* .9f in Q15*/ ); /* Q8 */
3123 2062 : hTdCngEnc->mov_wb_cng_ener_fx = add( hTdCngEnc->mov_wb_cng_ener_fx, tmp ); /* Q8 */
3124 2062 : move16();
3125 :
3126 2062 : tmp = sub( log_shb_ener_fx, hTdCngEnc->mov_shb_cng_ener_fx );
3127 2062 : tmp = mult( tmp, 8192 /* .25f in Q15*/ ); /* Q8 */
3128 2062 : hTdCngEnc->mov_shb_cng_ener_fx = add( hTdCngEnc->mov_shb_cng_ener_fx, tmp ); /* Q8 */
3129 2062 : move16();
3130 : }
3131 :
3132 2084 : hTdCngEnc->shb_NO_DATA_cnt = add( hTdCngEnc->shb_NO_DATA_cnt, 1 );
3133 2084 : update = 0;
3134 :
3135 2084 : move16();
3136 2084 : move16();
3137 :
3138 2084 : IF( EQ_32( st->core_brate, SID_2k40 ) )
3139 : {
3140 399 : test();
3141 399 : test();
3142 399 : test();
3143 399 : IF( st->hDtxEnc->first_CNG == 0 )
3144 : {
3145 22 : update = 1;
3146 22 : move16();
3147 : }
3148 377 : ELSE IF( hTdCngEnc->shb_cng_ini_cnt > 0 )
3149 : {
3150 22 : hTdCngEnc->shb_cng_ini_cnt = sub( hTdCngEnc->shb_cng_ini_cnt, 1 );
3151 22 : update = 1;
3152 22 : move16();
3153 22 : move16();
3154 : }
3155 355 : ELSE IF( EQ_16( hTdCngEnc->last_vad, 1 ) )
3156 : {
3157 163 : update = 1;
3158 163 : move16();
3159 : }
3160 192 : ELSE IF( GE_16( hTdCngEnc->shb_NO_DATA_cnt, 100 ) )
3161 : {
3162 0 : update = 1;
3163 0 : move16();
3164 : }
3165 192 : ELSE IF( GT_16( abs_s( sub( sub( hTdCngEnc->mov_wb_cng_ener_fx, hTdCngEnc->mov_shb_cng_ener_fx ), sub( hTdCngEnc->last_wb_cng_ener_fx, hTdCngEnc->last_shb_cng_ener_fx ) ) ), 768 ) )
3166 : {
3167 47 : update = 1;
3168 47 : move16();
3169 : }
3170 145 : ELSE IF( ( GE_16( st->bwidth, SWB ) && LT_16( hTdCngEnc->last_SID_bwidth, SWB ) ) || ( LT_16( st->bwidth, SWB ) && GE_16( hTdCngEnc->last_SID_bwidth, SWB ) ) )
3171 : {
3172 0 : update = 1;
3173 0 : move16();
3174 : }
3175 :
3176 399 : hTdCngEnc->last_SID_bwidth = st->bwidth;
3177 399 : move16();
3178 : }
3179 :
3180 : /* LF-boost not yet implemented in decoder which means that the specific wb_sid information is not used */
3181 2084 : test();
3182 2084 : test();
3183 2084 : if ( ( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) && EQ_32( st->core_brate, SID_2k40 ) )
3184 : {
3185 399 : update = 1;
3186 399 : move16();
3187 : }
3188 :
3189 2084 : IF( EQ_16( update, 1 ) )
3190 : {
3191 399 : hTdCngEnc->last_wb_cng_ener_fx = hTdCngEnc->mov_wb_cng_ener_fx;
3192 399 : hTdCngEnc->last_shb_cng_ener_fx = hTdCngEnc->mov_shb_cng_ener_fx;
3193 399 : hTdCngEnc->shb_NO_DATA_cnt = 0;
3194 399 : move16();
3195 399 : move16();
3196 399 : move16();
3197 : }
3198 :
3199 2084 : return ( update );
3200 : }
|