Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 : #include <stdint.h>
6 : #include "options.h" /* Compilation switches */
7 : #include "cnst.h"
8 : #include "rom_com.h"
9 : #include "prot_fx.h"
10 : #include "ivas_cnst.h"
11 :
12 : /*Temporary location to be move in prot* when merge is done*/
13 : void E_LPC_f_isp_a_conversion( const Word16 *isp, Word16 *a, const Word16 m );
14 : void E_LPC_f_lsp_a_conversion( const Word16 *isp, Word16 *a, const Word16 m );
15 :
16 : /*-----------------------------------------------------------------*
17 : * Local function prototypes
18 : *-----------------------------------------------------------------*/
19 :
20 : static void shb_CNG_decod_fx( Decoder_State *st_fx, const Word16 *synth_fx, Word16 *shb_synth_fx, const Word16 sid_bw, const Word16 Qsyn );
21 :
22 : static void shb_CNG_decod_ivas_fx( Decoder_State *st_fx, const Word16 *synth_fx, Word16 *shb_synth_fx, const Word16 sid_bw, const Word16 Qsyn );
23 :
24 : /*-----------------------------------------------------------------*
25 : * Decode residual signal energy
26 : *-----------------------------------------------------------------*/
27 :
28 : #ifndef REMOVE_EVS_DUPLICATES
29 : void CNG_dec_fx(
30 : Decoder_State *st_fx, /* i/o: State structure */
31 : const Word16 last_element_mode, /* i : last element mode Q0 */
32 : Word16 Aq[], /* o : LP coefficients Q12 */
33 : Word16 *lsp_new, /* i/o: current frame LSPs Q15 */
34 : Word16 *lsf_new, /* i/o: current frame LSFs Qlog2(2.56) */
35 : Word16 *allow_cn_step, /* o : allow CN step Q0 */
36 : Word16 *sid_bw /* i : 0-NB/WB, 1-SWB SID Q0 */
37 : ,
38 : Word32 *q_env )
39 : {
40 : Word16 istep;
41 : Word16 i, L_enr_index;
42 : Word32 L_ener;
43 : Word16 ener_fra, ener_int;
44 : Word16 num_bits;
45 : Word16 weights, ptr, j, k;
46 : Word16 m1;
47 : Word16 m = 0;
48 : move16();
49 : Word16 tmp[HO_HIST_SIZE * M];
50 : Word16 burst_ho_cnt = 0;
51 : move16();
52 : Word16 ll, s_ptr;
53 : Word32 L_enr, L_tmp1;
54 : Word16 tmp1, exp;
55 : Word16 lsf_tmp[M];
56 : Word32 C[M];
57 : Word32 max_val[2];
58 : Word16 max_idx[2];
59 : Word16 ftmp_fx;
60 : Word16 lsp_tmp[M];
61 : Word16 dev;
62 : Word16 max_dev;
63 : Word16 dist;
64 : Word16 tmpv;
65 : Word16 env_idx[2];
66 : Word32 enr1;
67 : Word32 env[NUM_ENV_CNG];
68 : Word32 tmp_env[HO_HIST_SIZE * NUM_ENV_CNG];
69 : Word32 L_tmp;
70 : Word16 fra;
71 : Word16 temp_lo_fx, temp_hi_fx;
72 : Word16 exp_pow;
73 : Word16 tmp_loop;
74 : Word16 enr_new, Aq_tmp[M + 1];
75 :
76 : Word16 LSF_Q_prediction; /* o : LSF prediction mode - just temporary variable in CNG */
77 : TD_CNG_DEC_HANDLE hTdCngDec;
78 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
79 : Flag Overflow = 0;
80 : move32();
81 : #endif
82 : hTdCngDec = st_fx->hTdCngDec;
83 :
84 : m = 0;
85 : move16();
86 : /*-----------------------------------------------------------------*
87 : * Decode CNG spectral envelope (only in SID frame)
88 : *-----------------------------------------------------------------*/
89 : test();
90 : IF( EQ_32( st_fx->core_brate, SID_1k75 ) || EQ_32( st_fx->core_brate, SID_2k40 ) )
91 : {
92 : /* de-quantize the LSF vector */
93 : IF( st_fx->Opt_AMR_WB != 0 )
94 : {
95 : /* Flt function */
96 : isf_dec_amr_wb_fx( st_fx, Aq, lsf_new, lsp_new );
97 : /* check IF ISPs may trigger too much synthesis energy */
98 :
99 : E_LPC_f_isp_a_conversion( lsp_new, Aq_tmp, M );
100 : enr_new = Enr_1_Az_fx( Aq_tmp, 2 * L_SUBFR );
101 :
102 : IF( ( shr( enr_new, 14 ) > 0 ) )
103 : {
104 : /* Use old LSP vector */
105 : Copy( st_fx->lsp_old_fx, lsp_new, M ); /* Q15 */
106 : Copy( st_fx->lsf_old_fx, lsf_new, M ); /* Q2.56 */
107 : }
108 : }
109 : ELSE
110 : {
111 : lsf_dec_fx( st_fx, 0, Aq, &LSF_Q_prediction, lsf_new, lsp_new, 0, 0,
112 : NULL );
113 : /* check IF LSPs may trigger too much synthesis energy */
114 :
115 : E_LPC_f_lsp_a_conversion( lsp_new, Aq_tmp, M );
116 : enr_new = Enr_1_Az_fx( Aq_tmp, 2 * L_SUBFR );
117 :
118 : IF( shr( enr_new, 14 ) > 0 )
119 : {
120 : /* Use old LSP vector */
121 : Copy( st_fx->lsp_old_fx, lsp_new, M ); /* Q15 */
122 : Copy( st_fx->lsf_old_fx, lsf_new, M ); /* Q2.56 */
123 : }
124 : }
125 : }
126 : ELSE
127 : {
128 : /* Use old LSP vector */
129 : Copy( st_fx->lsp_old_fx, lsp_new, M ); /* Q15 */
130 : Copy( st_fx->lsf_old_fx, lsf_new, M ); /* Q2.56 */
131 : }
132 :
133 : /* Initialize the CNG spectral envelope in case of the very first CNG frame */
134 : IF( st_fx->first_CNG == 0 )
135 : {
136 : Copy( st_fx->lsp_old_fx, st_fx->lspCNG_fx, M ); /* Q15 */
137 : }
138 :
139 : /*-----------------------------------------------------------------*
140 : * Decode residual signal energy
141 : *-----------------------------------------------------------------*/
142 :
143 : *allow_cn_step = 0;
144 : move16();
145 : test();
146 : IF( EQ_32( st_fx->core_brate, SID_1k75 ) || EQ_32( st_fx->core_brate, SID_2k40 ) )
147 : {
148 : istep = ISTEP_AMR_WB_SID_FX; /* Q15 */
149 : move16();
150 : if ( EQ_32( st_fx->core_brate, SID_2k40 ) )
151 : {
152 : istep = ISTEP_SID_FX; /* Q15 */
153 : move16();
154 : }
155 :
156 : /* initialize the energy quantization parameters */
157 : num_bits = 6;
158 : move16();
159 : if ( st_fx->Opt_AMR_WB == 0 )
160 : {
161 : num_bits = 7;
162 : move16();
163 : }
164 :
165 : /* decode the energy index */
166 : L_enr_index = get_next_indice_fx( st_fx, num_bits );
167 :
168 : IF( LE_32( st_fx->last_core_brate, SID_2k40 ) || EQ_16( st_fx->prev_bfi, 1 ) )
169 : {
170 : tmp1 = add( hTdCngDec->old_enr_index, 20 );
171 : }
172 : ELSE
173 : {
174 : tmp1 = add( hTdCngDec->old_enr_index, 40 );
175 : }
176 : IF( GT_16( L_enr_index, tmp1 ) && hTdCngDec->old_enr_index >= 0 ) /* Likely bit error and not startup */
177 : {
178 : L_enr_index = tmp1;
179 : move16();
180 : L_enr_index = s_min( L_enr_index, 127 ); /* Q0 */
181 : IF( st_fx->Opt_AMR_WB )
182 : {
183 : L_enr_index = s_min( L_enr_index, 63 ); /* Q0 */
184 : }
185 : }
186 :
187 : test();
188 : test();
189 : test();
190 : IF( GT_32( st_fx->last_core_brate, SID_1k75 ) &&
191 : NE_16( st_fx->first_CNG, 0 ) &&
192 : GE_16( hTdCngDec->old_enr_index, 0 ) &&
193 : GT_16( L_enr_index, add( hTdCngDec->old_enr_index, 1 ) ) )
194 : {
195 : *allow_cn_step = 1;
196 : move16();
197 : }
198 :
199 : hTdCngDec->old_enr_index = L_enr_index;
200 : move16();
201 : if ( !L_enr_index )
202 : {
203 : L_enr_index = -5;
204 : move16();
205 : }
206 : /* st_fx->Enew = L_enr_index / step - 2.0f;*/
207 : L_ener = L_mult( L_enr_index, istep ); /* Q16 (0+15) */
208 : /* subtract by 2 not done to leave Energy in Q2 */
209 :
210 : /* extract integral and fractional parts */
211 : ener_fra = L_Extract_lc( L_ener, &ener_int );
212 : ener_int = add( ener_int, 4 ); /* Q2 to Q6 */
213 :
214 : /* find the new energy value */
215 : hTdCngDec->Enew_fx = Pow2( ener_int, ener_fra );
216 : move32();
217 :
218 : IF( EQ_32( st_fx->core_brate, SID_2k40 ) )
219 : {
220 : burst_ho_cnt = get_next_indice_fx( st_fx, 3 ); /* 3bit */
221 :
222 : *sid_bw = get_next_indice_fx( st_fx, 1 );
223 : move16();
224 : IF( *sid_bw == 0 )
225 : {
226 : env_idx[0] = get_next_indice_fx( st_fx, 6 );
227 : move16();
228 :
229 : /* get quantized res_env_details */
230 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
231 : {
232 : q_env[i] = L_deposit_l( CNG_details_codebook_fx[env_idx[0]][i] );
233 : move32();
234 : }
235 : }
236 : }
237 : /* Reset CNG history IF CNG frame length is changed */
238 : test();
239 : test();
240 : IF( EQ_16( st_fx->bwidth, WB ) && NE_16( st_fx->first_CNG, 0 ) && NE_16( st_fx->L_frame, st_fx->last_CNG_L_frame ) )
241 : {
242 : hTdCngDec->ho_hist_size = 0;
243 : move16();
244 : }
245 : }
246 :
247 : /*---------------------------------------------------------------------*
248 : * CNG spectral envelope update
249 : * Find A(z) coefficients
250 : *---------------------------------------------------------------------*/
251 : test();
252 : test();
253 : test();
254 : IF( LE_32( st_fx->last_core_brate, SID_2k40 ) )
255 : {
256 : /* Reset hangover counter if not first SID period */
257 : if ( GT_32( st_fx->core_brate, FRAME_NO_DATA ) )
258 : {
259 : hTdCngDec->num_ho = 0;
260 : move16();
261 : }
262 : /* Update LSPs IF last SID energy not outliers or insufficient number of hangover frames */
263 : test();
264 : IF( LT_16( hTdCngDec->num_ho, 3 ) || LT_32( Mult_32_16( hTdCngDec->Enew_fx, 21845 /*1/1.5f, Q15*/ ), st_fx->lp_ener_fx ) )
265 : {
266 : FOR( i = 0; i < M; i++ )
267 : {
268 : /* AR low-pass filter */
269 : st_fx->lspCNG_fx[i] = mac_r( L_mult( CNG_ISF_FACT_FX, st_fx->lspCNG_fx[i] ), 32768 - CNG_ISF_FACT_FX, lsp_new[i] );
270 : move16(); /* Q15 (15+15+1-16) */
271 : }
272 : }
273 : }
274 : ELSE
275 : {
276 : /* Update CNG_mode IF allowed */
277 : test();
278 : test();
279 : test();
280 : IF( ( st_fx->Opt_AMR_WB || EQ_16( st_fx->bwidth, WB ) ) && ( !st_fx->first_CNG || GE_16( hTdCngDec->act_cnt2, MIN_ACT_CNG_UPD ) ) )
281 : {
282 : IF( GT_32( st_fx->last_active_brate, ACELP_16k40 ) )
283 : {
284 : st_fx->CNG_mode = -1;
285 : move16();
286 : }
287 : ELSE
288 : {
289 : st_fx->CNG_mode = get_cng_mode( st_fx->last_active_brate );
290 : move16();
291 : }
292 : }
293 :
294 : /* If first sid after active burst update LSF history from circ buffer */
295 : burst_ho_cnt = s_min( burst_ho_cnt, hTdCngDec->ho_circ_size ); /* MODE1_DTX_IN_CODEC_B_FIX Q0*/
296 : hTdCngDec->act_cnt = 0;
297 : move16();
298 : s_ptr = add( sub( hTdCngDec->ho_circ_ptr, burst_ho_cnt ), 1 );
299 : IF( s_ptr < 0 )
300 : {
301 : s_ptr = add( s_ptr, hTdCngDec->ho_circ_size );
302 : }
303 :
304 : FOR( ll = burst_ho_cnt; ll > 0; ll-- )
305 : {
306 : hTdCngDec->ho_hist_ptr = add( hTdCngDec->ho_hist_ptr, 1 ); /* Q0 */
307 : move16();
308 : if ( EQ_16( hTdCngDec->ho_hist_ptr, HO_HIST_SIZE ) )
309 : {
310 : hTdCngDec->ho_hist_ptr = 0;
311 : move16();
312 : }
313 :
314 : /* Conversion between 12.8k and 16k LSPs */
315 : test();
316 : test();
317 : test();
318 : IF( ( EQ_16( st_fx->L_frame, L_FRAME16k ) && hTdCngDec->ho_16k_lsp[s_ptr] == 0 ) || ( EQ_16( st_fx->L_frame, L_FRAME ) && EQ_16( hTdCngDec->ho_16k_lsp[s_ptr], 1 ) ) )
319 : {
320 : /* Conversion from 16k LPSs to 12k8 */
321 : lsp_convert_poly_fx( &( hTdCngDec->ho_lsp_circ_fx[s_ptr * M] ), st_fx->L_frame, 0 );
322 : }
323 : /* update the circular buffers */
324 : Copy( &( hTdCngDec->ho_lsp_circ_fx[s_ptr * M] ), &( hTdCngDec->ho_lsp_hist_fx[hTdCngDec->ho_hist_ptr * M] ), M ); /* Qx */
325 : Copy32( &( hTdCngDec->ho_ener_circ_fx[s_ptr] ), &( hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr] ), 1 ); /* Q6 */
326 : hTdCngDec->ho_sid_bw = L_shl( L_and( hTdCngDec->ho_sid_bw, (Word32) 0x3fffffffL ), 1 );
327 : move32();
328 : Copy32( &( hTdCngDec->ho_env_circ_fx[s_ptr * NUM_ENV_CNG] ), &( hTdCngDec->ho_env_hist_fx[hTdCngDec->ho_hist_ptr * NUM_ENV_CNG] ), NUM_ENV_CNG ); /* Qx */
329 :
330 : hTdCngDec->ho_hist_size = add( hTdCngDec->ho_hist_size, 1 );
331 : move16();
332 :
333 : if ( GT_16( hTdCngDec->ho_hist_size, HO_HIST_SIZE ) )
334 : {
335 : hTdCngDec->ho_hist_size = HO_HIST_SIZE;
336 : move16();
337 : }
338 :
339 : s_ptr = add( s_ptr, 1 );
340 : if ( EQ_16( s_ptr, hTdCngDec->ho_circ_size ) )
341 : {
342 : s_ptr = 0;
343 : move16();
344 : }
345 : }
346 :
347 : IF( hTdCngDec->ho_hist_size > 0 ) /* can be -1 at init MODE1_DTX_IN_CODEC_B_FIX */
348 : {
349 : /* *allow_cn_step |= ( st_fx->ho_ener_hist[st_fx->ho_hist_ptr] > 4.0f * st_fx->lp_ener );*/
350 : L_tmp1 = L_shr( hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr], 2 );
351 : L_tmp1 = L_sub( L_tmp1, st_fx->lp_ener_fx );
352 :
353 : test();
354 : test();
355 : IF( ( L_tmp1 > 0 && ( st_fx->first_CNG || st_fx->element_mode == EVS_MONO ) ) )
356 : {
357 : *allow_cn_step = s_or( *allow_cn_step, 1 );
358 : move16();
359 : }
360 : }
361 : IF( EQ_16( last_element_mode, IVAS_CPE_TD ) )
362 : {
363 : *allow_cn_step = 1;
364 : move16();
365 : }
366 : test();
367 : IF( EQ_16( *allow_cn_step, 0 ) && GT_16( hTdCngDec->ho_hist_size, 0 ) )
368 : {
369 : /* Use average of energies below last energy */
370 : ptr = hTdCngDec->ho_hist_ptr;
371 : move16();
372 : Copy( &( hTdCngDec->ho_lsp_hist_fx[ptr * M] ), tmp, M ); /* Qx */
373 : m1 = 0;
374 : move16();
375 : IF( L_and( hTdCngDec->ho_sid_bw, (Word32) 0x1 ) == 0 )
376 : {
377 : Copy32( &hTdCngDec->ho_env_hist_fx[ptr * NUM_ENV_CNG], tmp_env, NUM_ENV_CNG );
378 : m1 = 1;
379 : move16();
380 : }
381 : L_enr = Mult_32_16( hTdCngDec->ho_ener_hist_fx[ptr], W_DTX_HO_FX[0] ); /* Q6+15-15->Q6 */
382 :
383 : weights = W_DTX_HO_FX[0]; /* Q15 */
384 : move16();
385 :
386 : m = 1;
387 : move16();
388 : FOR( k = 1; k < hTdCngDec->ho_hist_size; k++ )
389 : {
390 : ptr--;
391 : if ( ptr < 0 )
392 : {
393 : ptr = HO_HIST_SIZE - 1;
394 : move16();
395 : }
396 :
397 : test();
398 : IF( LT_32( Mult_32_16( hTdCngDec->ho_ener_hist_fx[ptr], ONE_OVER_BUF_H_NRG_FX ), hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr] ) &&
399 : GT_32( hTdCngDec->ho_ener_hist_fx[ptr], Mult_32_16( hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr], BUF_L_NRG_FX ) ) )
400 : {
401 : /*enr += W_DTX_HO[k] * st_fx->ho_ener_hist[ptr];*/
402 : L_tmp1 = Mult_32_16( hTdCngDec->ho_ener_hist_fx[ptr], W_DTX_HO_FX[k] ); /* Q6+15-15->Q6 */
403 : L_enr = L_add( L_enr, L_tmp1 ); /* Q6 */
404 :
405 : /*weights += W_DTX_HO[k];*/
406 : weights = add( weights, W_DTX_HO_FX[k] ); /* Q15 */
407 :
408 : Copy( &hTdCngDec->ho_lsp_hist_fx[ptr * M], &tmp[m * M], M ); /* Qx */
409 : IF( EQ_32( L_and( hTdCngDec->ho_sid_bw, L_shl( (Word32) 0x1, k ) ), 0 ) )
410 : {
411 : Copy32( &hTdCngDec->ho_env_hist_fx[ptr * NUM_ENV_CNG], &tmp_env[m1 * NUM_ENV_CNG], NUM_ENV_CNG ); /* Qx */
412 : m1++;
413 : }
414 : m++;
415 : }
416 : }
417 :
418 : /*enr /= weights;*/
419 : exp = norm_s( weights );
420 : tmp1 = div_s( shl( 1, sub( 14, exp ) ), weights ); /* Q(15+14-exp-15) */
421 : L_tmp1 = Mult_32_16( L_enr, tmp1 ); /* Q(14-exp+6-15)->Q(5-exp) */
422 : L_enr = L_shl( L_tmp1, add( exp, 1 ) ); /* Q6 */
423 :
424 : st_fx->lp_ener_fx = L_enr; /* Q6 */
425 : move32();
426 : set32_fx( max_val, 0, 2 );
427 : set16_fx( max_idx, 0, 2 );
428 :
429 : FOR( i = 0; i < m; i++ )
430 : {
431 : IF( EQ_16( st_fx->L_frame, L_FRAME ) )
432 : {
433 : lsp2lsf_fx( &tmp[i * M], lsf_tmp, M, INT_FS_FX );
434 : ftmp_fx = 964;
435 : move16(); /*X2.56 */
436 : tmpv = sub( 16384, add( lsf_tmp[M - 1], ftmp_fx ) ); /*QX2.56*/
437 : L_tmp = L_mult0( tmpv, tmpv ); /*QX6.5536*/
438 : }
439 : ELSE
440 : {
441 : lsp2lsf_fx( &tmp[i * M], lsf_tmp, M, INT_FS_16k_FX );
442 : ftmp_fx = 1205;
443 : move16(); /*QX2.56*/
444 : tmpv = sub( 20480, add( lsf_tmp[M - 1], ftmp_fx ) ); /*QX2.56*/
445 : L_tmp = L_mult0( tmpv, tmpv ); /*QX6.5536*/
446 : }
447 :
448 : tmpv = sub( lsf_tmp[0], ftmp_fx ); /*QX2.56*/
449 : L_tmp = L_mac0( L_tmp, tmpv, tmpv ); /*QX6.5536*/
450 : FOR( j = 0; j < M - 1; j++ )
451 : {
452 : tmpv = sub( sub( lsf_tmp[j + 1], lsf_tmp[j] ), ftmp_fx ); /*QX2.56*/
453 : L_tmp = L_mac0( L_tmp, tmpv, tmpv ); /*QX6.5536*/
454 : }
455 :
456 : C[i] = Mpy_32_16_1( L_tmp, 1928 ); /*QX6.5536*/
457 : move32();
458 :
459 : IF( GT_32( C[i], max_val[0] ) )
460 : {
461 : max_val[1] = max_val[0];
462 : move32();
463 : max_idx[1] = max_idx[0];
464 : move16();
465 : max_val[0] = C[i];
466 : move32();
467 : max_idx[0] = i;
468 : move16();
469 : }
470 : ELSE IF( GT_32( C[i], max_val[1] ) )
471 : {
472 : max_val[1] = C[i];
473 : move32();
474 : max_idx[1] = i;
475 : move16();
476 : }
477 : }
478 :
479 : IF( EQ_16( m, 1 ) )
480 : {
481 : Copy( tmp, lsp_tmp, M ); /* Qx */
482 : }
483 : ELSE IF( LT_16( m, 4 ) )
484 : {
485 : FOR( i = 0; i < M; i++ )
486 : {
487 : L_tmp1 = 0;
488 : move32();
489 : FOR( j = 0; j < m; j++ )
490 : {
491 : L_tmp1 = L_add( L_tmp1, L_deposit_l( tmp[j * M + i] ) );
492 : }
493 :
494 : L_tmp1 = L_sub( L_tmp1, L_deposit_l( tmp[max_idx[0] * M + i] ) );
495 : tmpv = div_s( 1, sub( m, 1 ) ); /*Q15*/
496 : L_tmp1 = Mpy_32_16_1( L_tmp1, tmpv ); /*Q15*/
497 : lsp_tmp[i] = extract_l( L_tmp1 ); /*Q15*/
498 : move16();
499 : }
500 : }
501 : ELSE
502 : {
503 : FOR( i = 0; i < M; i++ )
504 : {
505 : L_tmp1 = 0;
506 : move32();
507 : FOR( j = 0; j < m; j++ )
508 : {
509 : L_tmp1 = L_add( L_tmp1, L_deposit_l( tmp[j * M + i] ) );
510 : }
511 :
512 : L_tmp1 = L_sub( L_tmp1, L_add( L_deposit_l( tmp[max_idx[0] * M + i] ), L_deposit_l( tmp[max_idx[1] * M + i] ) ) ); /*Q15*/
513 : tmpv = div_s( 1, sub( m, 2 ) ); /*Q15*/
514 : L_tmp1 = Mpy_32_16_1( L_tmp1, tmpv ); /*Q15*/
515 : lsp_tmp[i] = extract_l( L_tmp1 ); /*Q15*/
516 : move16();
517 : }
518 : }
519 :
520 : dist = 0;
521 : move16(); /*Q15*/
522 : max_dev = 0;
523 : move16(); /*Q15*/
524 : FOR( i = 0; i < M; i++ )
525 : {
526 : dev = abs_s( sub( lsp_tmp[i], lsp_new[i] ) ); /*Q15*/
527 : dist = add_o( dist, dev, &Overflow ); /*Q15*/
528 : if ( GT_16( dev, max_dev ) )
529 : {
530 : max_dev = dev;
531 : move16();
532 : }
533 : }
534 :
535 : test();
536 : IF( GT_16( dist, 13107 ) || GT_16( max_dev, 3277 ) ) /* 0.4 and 0.1 in Q15 */
537 : {
538 : FOR( i = 0; i < M; i++ )
539 : {
540 : st_fx->lspCNG_fx[i] = lsp_tmp[i];
541 : move16(); /*Q15*/
542 : }
543 : }
544 : ELSE
545 : {
546 : FOR( i = 0; i < M; i++ )
547 : {
548 : /* AR low-pass filter */
549 : st_fx->lspCNG_fx[i] = add( mult_r( 26214, lsp_tmp[i] ), mult_r( 6554, lsp_new[i] ) ); /* Q15 */
550 : move16();
551 : }
552 : }
553 : IF( m1 > 0 )
554 : {
555 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
556 : {
557 : L_tmp = L_deposit_l( 0 );
558 : FOR( j = 0; j < m1; j++ )
559 : {
560 : /* env[i] += tmp_env[j*NUM_ENV_CNG+i];*/
561 : L_tmp = L_add_sat( L_tmp, tmp_env[j * NUM_ENV_CNG + i] );
562 : }
563 : /* env[i] /= (float)m1; */
564 : /* env[i] = env[i] - 2*st_fx->lp_ener_fx; */
565 : IF( EQ_16( m1, 1 ) )
566 : {
567 : L_tmp = L_sub_sat( L_tmp, L_add_sat( st_fx->lp_ener_fx, st_fx->lp_ener_fx ) ); /* Q6 */
568 : }
569 : ELSE
570 : {
571 : tmp1 = div_s( 1, m1 );
572 : L_tmp = Mult_32_16( L_tmp, tmp1 ); /* Q6 */
573 : L_tmp = L_sub_sat( L_tmp, L_add_sat( st_fx->lp_ener_fx, st_fx->lp_ener_fx ) ); /* Q6 */
574 : }
575 : env[i] = L_tmp; /* Q6 */
576 : move32();
577 : }
578 :
579 : Copy32( env, hTdCngDec->lp_env_fx, NUM_ENV_CNG ); /* Q6 */
580 : }
581 : }
582 : ELSE
583 : {
584 : Copy( lsp_new, st_fx->lspCNG_fx, M ); /* use newly analyzed ISFs */ /* Q15 */
585 : }
586 : }
587 :
588 : test();
589 : IF( EQ_32( st_fx->core_brate, SID_1k75 ) || EQ_32( st_fx->core_brate, SID_2k40 ) )
590 : {
591 : /* Update hangover memory during CNG */
592 : test();
593 : IF( ( *allow_cn_step == 0 ) && LT_32( hTdCngDec->Enew_fx, L_add_sat( st_fx->lp_ener_fx, L_shr( st_fx->lp_ener_fx, 1 ) ) ) )
594 : {
595 : /* update the pointer to circular buffer of old LSP vectors */
596 : hTdCngDec->ho_hist_ptr++;
597 : move16();
598 : if ( EQ_16( hTdCngDec->ho_hist_ptr, HO_HIST_SIZE ) )
599 : {
600 : hTdCngDec->ho_hist_ptr = 0;
601 : move16();
602 : }
603 :
604 : /* update the circular buffer of old LSP vectors with the new LSP vector */
605 : Copy( lsp_new, &( hTdCngDec->ho_lsp_hist_fx[( hTdCngDec->ho_hist_ptr ) * M] ), M ); /* Q15 */
606 :
607 : /* update the hangover energy buffer */
608 : hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr] = hTdCngDec->Enew_fx; /* Q6 */
609 : move32();
610 : test();
611 : IF( EQ_32( st_fx->core_brate, SID_2k40 ) && ( *sid_bw == 0 ) )
612 : {
613 : /* enr1 = (float)log10( st->Enew*L_frame + 0.1f ) / (float)log10( 2.0f );*/
614 : exp = norm_l( hTdCngDec->Enew_fx );
615 : L_tmp = L_shl( hTdCngDec->Enew_fx, exp ); /*Q(exp+6)*/
616 : L_tmp = Mult_32_16( L_tmp, shl( st_fx->L_frame, 5 ) ); /*Q(exp+6+5-15=exp-4)*/
617 : L_tmp = L_shr_sat( L_tmp, sub( exp, 10 ) ); /*Q6*/
618 : exp = norm_l( L_tmp );
619 : fra = Log2_norm_lc( L_shl( L_tmp, exp ) );
620 : exp = sub( sub( 30, exp ), 6 );
621 : L_tmp = L_Comp( exp, fra );
622 : enr1 = L_shr( L_tmp, 10 ); /* Q6 */
623 :
624 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
625 : {
626 : /* get quantized envelope */
627 : /* env[i] = pow(2.0f,(enr1 - q_env[i])) + 2*st->Enew;*/
628 : L_tmp = L_sub( enr1, q_env[i] ); /* Q6 */
629 : L_tmp = L_shl( L_tmp, 10 ); /* 16 */
630 : temp_lo_fx = L_Extract_lc( L_tmp, &temp_hi_fx );
631 :
632 : exp_pow = sub( 14, temp_hi_fx );
633 : L_tmp = Pow2( 14, temp_lo_fx ); /* Qexp_pow */
634 : env[i] = L_shl( L_tmp, sub( 6, exp_pow ) ); /* Q6 */
635 : move32();
636 : L_tmp = L_add( hTdCngDec->Enew_fx, hTdCngDec->Enew_fx );
637 : env[i] = L_add( env[i], L_tmp ); /* Q6 */
638 : move32();
639 : }
640 : hTdCngDec->ho_sid_bw = L_shl( L_and( hTdCngDec->ho_sid_bw, (Word32) 0x3fffffffL ), 1 ); /* Q0 */
641 : move32();
642 : Copy32( env, &( hTdCngDec->ho_env_hist_fx[hTdCngDec->ho_hist_ptr * NUM_ENV_CNG] ), NUM_ENV_CNG ); /* Q6 */
643 : }
644 : ELSE IF( ( *sid_bw != 0 ) )
645 : {
646 : hTdCngDec->ho_sid_bw = L_shl( L_and( hTdCngDec->ho_sid_bw, (Word32) 0x3fffffffL ), 1 ); /* Q0 */
647 : move32();
648 : hTdCngDec->ho_sid_bw = L_or( hTdCngDec->ho_sid_bw, 0x1L ); /* Q0 */
649 : move32();
650 : }
651 :
652 : hTdCngDec->ho_hist_size = add( hTdCngDec->ho_hist_size, 1 );
653 : move16();
654 : if ( GT_16( hTdCngDec->ho_hist_size, HO_HIST_SIZE ) )
655 : {
656 : hTdCngDec->ho_hist_size = HO_HIST_SIZE;
657 : move16();
658 : }
659 : }
660 : /* Update the frame length memory */
661 : st_fx->last_CNG_L_frame = st_fx->L_frame;
662 : move16();
663 :
664 : if ( NE_32( st_fx->core_brate, SID_1k75 ) )
665 : {
666 : hTdCngDec->num_ho = m;
667 : move16();
668 : }
669 : }
670 :
671 : IF( st_fx->element_mode == EVS_MONO )
672 : {
673 : st_fx->last_CNG_L_frame = st_fx->L_frame;
674 : move16();
675 :
676 : IF( NE_32( st_fx->core_brate, SID_1k75 ) )
677 : {
678 : hTdCngDec->num_ho = m;
679 : move16();
680 : }
681 : }
682 : IF( st_fx->Opt_AMR_WB )
683 : {
684 : E_LPC_f_isp_a_conversion( st_fx->lspCNG_fx, Aq, M );
685 : }
686 : ELSE
687 : {
688 : E_LPC_f_lsp_a_conversion( st_fx->lspCNG_fx, Aq, M );
689 : }
690 :
691 : tmp_loop = shr( st_fx->L_frame, 6 );
692 : FOR( i = 1; i < tmp_loop; i++ ) /* L_frame/L_SUBFR */
693 : {
694 : Copy( Aq, &Aq[i * ( M + 1 )], add( M, 1 ) ); /* Q12 */
695 : }
696 :
697 : return;
698 : }
699 : #endif
700 2378 : void CNG_dec_ivas_fx(
701 : Decoder_State *st_fx, /* i/o: State structure */
702 : const Word16 last_element_mode, /* i : last element mode Q0 */
703 : Word16 Aq[], /* o : LP coefficients Q12 */
704 : Word16 *lsp_new, /* i/o: current frame LSPs Q15 */
705 : Word16 *lsf_new, /* i/o: current frame LSFs Qlog2(2.56) */
706 : Word16 *allow_cn_step, /* o : allow CN step Q0 */
707 : Word16 *sid_bw /* i : 0-NB/WB, 1-SWB SID Q0 */
708 : ,
709 : Word32 *q_env )
710 : {
711 : Word16 istep;
712 : Word16 i, L_enr_index;
713 : Word32 L_ener;
714 : Word16 ener_fra, ener_int;
715 : Word16 num_bits;
716 : Word16 weights, ptr, j, k;
717 : Word16 m1;
718 2378 : Word16 m = 0;
719 2378 : move16();
720 : Word16 tmp[HO_HIST_SIZE * M];
721 2378 : Word16 burst_ho_cnt = 0;
722 2378 : move16();
723 : Word16 ll, s_ptr;
724 : Word32 L_enr, L_tmp1;
725 : Word16 tmp1, exp;
726 : Word16 lsf_tmp[M];
727 : Word32 C[M];
728 : Word32 max_val[2];
729 : Word16 max_idx[2];
730 : Word16 ftmp_fx;
731 : Word16 lsp_tmp[M];
732 : Word16 dev;
733 : Word16 max_dev;
734 : Word16 dist;
735 : Word16 tmpv;
736 : Word16 env_idx[2];
737 : Word32 enr1;
738 : Word32 env[NUM_ENV_CNG];
739 : Word32 tmp_env[HO_HIST_SIZE * NUM_ENV_CNG];
740 : Word32 L_tmp;
741 : Word16 fra;
742 : Word16 temp_lo_fx, temp_hi_fx;
743 : Word16 exp_pow;
744 : Word16 tmp_loop;
745 : Word16 enr_new, Aq_tmp[M + 1];
746 :
747 : Word16 LSF_Q_prediction; /* o : LSF prediction mode - just temporary variable in CNG */
748 : TD_CNG_DEC_HANDLE hTdCngDec;
749 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
750 2378 : Flag Overflow = 0;
751 2378 : move32();
752 : #endif
753 2378 : hTdCngDec = st_fx->hTdCngDec;
754 :
755 2378 : m = 0;
756 2378 : move16();
757 : /*-----------------------------------------------------------------*
758 : * Decode CNG spectral envelope (only in SID frame)
759 : *-----------------------------------------------------------------*/
760 2378 : test();
761 2378 : IF( EQ_32( st_fx->core_brate, SID_1k75 ) || EQ_32( st_fx->core_brate, SID_2k40 ) )
762 : {
763 : /* de-quantize the LSF vector */
764 417 : IF( st_fx->Opt_AMR_WB != 0 )
765 : {
766 : /* Flt function */
767 0 : isf_dec_amr_wb_fx( st_fx, Aq, lsf_new, lsp_new );
768 : /* check IF ISPs may trigger too much synthesis energy */
769 :
770 0 : E_LPC_f_isp_a_conversion( lsp_new, Aq_tmp, M );
771 0 : enr_new = Enr_1_Az_fx( Aq_tmp, 2 * L_SUBFR );
772 :
773 0 : IF( ( shr( enr_new, 14 ) > 0 ) )
774 : {
775 : /* Use old LSP vector */
776 0 : Copy( st_fx->lsp_old_fx, lsp_new, M ); /* Q15 */
777 0 : Copy( st_fx->lsf_old_fx, lsf_new, M ); /* Q2.56 */
778 : }
779 : }
780 : ELSE
781 : {
782 417 : lsf_dec_ivas_fx( st_fx, 0, Aq, &LSF_Q_prediction, lsf_new, lsp_new, 0, 0,
783 : NULL );
784 : /* check IF LSPs may trigger too much synthesis energy */
785 :
786 417 : E_LPC_f_lsp_a_conversion( lsp_new, Aq_tmp, M );
787 417 : enr_new = Enr_1_Az_fx( Aq_tmp, 2 * L_SUBFR );
788 :
789 417 : IF( shr( enr_new, 14 ) > 0 )
790 : {
791 : /* Use old LSP vector */
792 0 : Copy( st_fx->lsp_old_fx, lsp_new, M ); /* Q15 */
793 0 : Copy( st_fx->lsf_old_fx, lsf_new, M ); /* Q2.56 */
794 : }
795 : }
796 : }
797 : ELSE
798 : {
799 : /* Use old LSP vector */
800 1961 : Copy( st_fx->lsp_old_fx, lsp_new, M ); /* Q15 */
801 1961 : Copy( st_fx->lsf_old_fx, lsf_new, M ); /* Q2.56 */
802 : }
803 :
804 : /* Initialize the CNG spectral envelope in case of the very first CNG frame */
805 2378 : IF( st_fx->first_CNG == 0 )
806 : {
807 28 : Copy( st_fx->lsp_old_fx, st_fx->lspCNG_fx, M ); /* Q15 */
808 : }
809 :
810 : /*-----------------------------------------------------------------*
811 : * Decode residual signal energy
812 : *-----------------------------------------------------------------*/
813 :
814 2378 : *allow_cn_step = 0;
815 2378 : move16();
816 2378 : test();
817 2378 : IF( EQ_32( st_fx->core_brate, SID_1k75 ) || EQ_32( st_fx->core_brate, SID_2k40 ) )
818 : {
819 417 : istep = ISTEP_AMR_WB_SID_FX; /* Q15 */
820 417 : move16();
821 417 : if ( EQ_32( st_fx->core_brate, SID_2k40 ) )
822 : {
823 417 : istep = ISTEP_SID_FX; /* Q15 */
824 417 : move16();
825 : }
826 :
827 : /* initialize the energy quantization parameters */
828 417 : num_bits = 6;
829 417 : move16();
830 417 : if ( st_fx->Opt_AMR_WB == 0 )
831 : {
832 417 : num_bits = 7;
833 417 : move16();
834 : }
835 :
836 : /* decode the energy index */
837 417 : L_enr_index = get_next_indice_fx( st_fx, num_bits );
838 :
839 417 : IF( LE_32( st_fx->last_core_brate, SID_2k40 ) || EQ_16( st_fx->prev_bfi, 1 ) )
840 : {
841 228 : tmp1 = add( hTdCngDec->old_enr_index, 20 );
842 : }
843 : ELSE
844 : {
845 189 : tmp1 = add( hTdCngDec->old_enr_index, 40 );
846 : }
847 417 : IF( GT_16( L_enr_index, tmp1 ) && hTdCngDec->old_enr_index >= 0 ) /* Likely bit error and not startup */
848 : {
849 0 : L_enr_index = tmp1;
850 0 : move16();
851 0 : L_enr_index = s_min( L_enr_index, 127 ); /* Q0 */
852 0 : IF( st_fx->Opt_AMR_WB )
853 : {
854 0 : L_enr_index = s_min( L_enr_index, 63 ); /* Q0 */
855 : }
856 : }
857 :
858 417 : test();
859 417 : test();
860 417 : test();
861 417 : IF( GT_32( st_fx->last_core_brate, SID_1k75 ) &&
862 : NE_16( st_fx->first_CNG, 0 ) &&
863 : GE_16( hTdCngDec->old_enr_index, 0 ) &&
864 : GT_16( L_enr_index, add( hTdCngDec->old_enr_index, 1 ) ) )
865 : {
866 0 : *allow_cn_step = 1;
867 0 : move16();
868 : }
869 :
870 417 : hTdCngDec->old_enr_index = L_enr_index;
871 417 : move16();
872 417 : if ( !L_enr_index )
873 : {
874 18 : L_enr_index = -5;
875 18 : move16();
876 : }
877 : /* st_fx->Enew = L_enr_index / step - 2.0f;*/
878 417 : L_ener = L_mult( L_enr_index, istep ); /* Q16 (0+15) */
879 : /* subtract by 2 not done to leave Energy in Q2 */
880 :
881 : /* extract integral and fractional parts */
882 417 : ener_fra = L_Extract_lc( L_ener, &ener_int );
883 417 : ener_int = add( ener_int, 4 ); /* Q2 to Q6 */
884 :
885 : /* find the new energy value */
886 417 : hTdCngDec->Enew_fx = Pow2( ener_int, ener_fra );
887 417 : move32();
888 :
889 417 : IF( EQ_32( st_fx->core_brate, SID_2k40 ) )
890 : {
891 417 : burst_ho_cnt = get_next_indice_fx( st_fx, 3 ); /* 3bit */
892 :
893 417 : *sid_bw = get_next_indice_fx( st_fx, 1 );
894 417 : move16();
895 417 : IF( *sid_bw == 0 )
896 : {
897 0 : env_idx[0] = get_next_indice_fx( st_fx, 6 );
898 0 : move16();
899 :
900 : /* get quantized res_env_details */
901 0 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
902 : {
903 0 : q_env[i] = L_deposit_l( CNG_details_codebook_fx[env_idx[0]][i] );
904 0 : move32();
905 : }
906 : }
907 : }
908 : /* Reset CNG history IF CNG frame length is changed */
909 417 : test();
910 417 : test();
911 417 : IF( EQ_16( st_fx->bwidth, WB ) && NE_16( st_fx->first_CNG, 0 ) && NE_16( st_fx->L_frame, st_fx->last_CNG_L_frame ) )
912 : {
913 1 : hTdCngDec->ho_hist_size = 0;
914 1 : move16();
915 : }
916 : }
917 :
918 : /*---------------------------------------------------------------------*
919 : * CNG spectral envelope update
920 : * Find A(z) coefficients
921 : *---------------------------------------------------------------------*/
922 2378 : test();
923 2378 : test();
924 2378 : test();
925 2378 : IF( LE_32( st_fx->last_core_brate, SID_2k40 ) )
926 : {
927 : /* Reset hangover counter if not first SID period */
928 2189 : if ( GT_32( st_fx->core_brate, FRAME_NO_DATA ) )
929 : {
930 228 : hTdCngDec->num_ho = 0;
931 228 : move16();
932 : }
933 : /* Update LSPs IF last SID energy not outliers or insufficient number of hangover frames */
934 2189 : test();
935 2189 : IF( LT_16( hTdCngDec->num_ho, 3 ) || LT_32( Mult_32_16( hTdCngDec->Enew_fx, 21845 /*1/1.5f, Q15*/ ), st_fx->lp_ener_fx ) )
936 : {
937 36669 : FOR( i = 0; i < M; i++ )
938 : {
939 : /* AR low-pass filter */
940 34512 : st_fx->lspCNG_fx[i] = mac_r( L_mult( CNG_ISF_FACT_FX, st_fx->lspCNG_fx[i] ), 32768 - CNG_ISF_FACT_FX, lsp_new[i] );
941 34512 : move16(); /* Q15 (15+15+1-16) */
942 : }
943 : }
944 : }
945 : ELSE
946 : {
947 : /* Update CNG_mode IF allowed */
948 189 : test();
949 189 : test();
950 189 : test();
951 189 : IF( ( st_fx->Opt_AMR_WB || EQ_16( st_fx->bwidth, WB ) ) && ( !st_fx->first_CNG || GE_16( hTdCngDec->act_cnt2, MIN_ACT_CNG_UPD ) ) )
952 : {
953 6 : IF( GT_32( st_fx->last_active_brate, ACELP_16k40 ) )
954 : {
955 3 : st_fx->CNG_mode = -1;
956 3 : move16();
957 : }
958 : ELSE
959 : {
960 3 : st_fx->CNG_mode = get_cng_mode( st_fx->last_active_brate );
961 3 : move16();
962 : }
963 : }
964 :
965 : /* If first sid after active burst update LSF history from circ buffer */
966 189 : burst_ho_cnt = s_min( burst_ho_cnt, hTdCngDec->ho_circ_size ); /* MODE1_DTX_IN_CODEC_B_FIX Q0*/
967 189 : hTdCngDec->act_cnt = 0;
968 189 : move16();
969 189 : s_ptr = add( sub( hTdCngDec->ho_circ_ptr, burst_ho_cnt ), 1 );
970 189 : IF( s_ptr < 0 )
971 : {
972 34 : s_ptr = add( s_ptr, hTdCngDec->ho_circ_size );
973 : }
974 :
975 478 : FOR( ll = burst_ho_cnt; ll > 0; ll-- )
976 : {
977 289 : hTdCngDec->ho_hist_ptr = add( hTdCngDec->ho_hist_ptr, 1 ); /* Q0 */
978 289 : move16();
979 289 : if ( EQ_16( hTdCngDec->ho_hist_ptr, HO_HIST_SIZE ) )
980 : {
981 25 : hTdCngDec->ho_hist_ptr = 0;
982 25 : move16();
983 : }
984 :
985 : /* Conversion between 12.8k and 16k LSPs */
986 289 : test();
987 289 : test();
988 289 : test();
989 289 : IF( ( EQ_16( st_fx->L_frame, L_FRAME16k ) && hTdCngDec->ho_16k_lsp[s_ptr] == 0 ) || ( EQ_16( st_fx->L_frame, L_FRAME ) && EQ_16( hTdCngDec->ho_16k_lsp[s_ptr], 1 ) ) )
990 : {
991 : /* Conversion from 16k LPSs to 12k8 */
992 61 : lsp_convert_poly_fx( &( hTdCngDec->ho_lsp_circ_fx[s_ptr * M] ), st_fx->L_frame, 0 );
993 : }
994 : /* update the circular buffers */
995 289 : Copy( &( hTdCngDec->ho_lsp_circ_fx[s_ptr * M] ), &( hTdCngDec->ho_lsp_hist_fx[hTdCngDec->ho_hist_ptr * M] ), M ); /* Qx */
996 289 : Copy32( &( hTdCngDec->ho_ener_circ_fx[s_ptr] ), &( hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr] ), 1 ); /* Q6 */
997 289 : hTdCngDec->ho_sid_bw = L_shl( L_and( hTdCngDec->ho_sid_bw, (Word32) 0x3fffffffL ), 1 );
998 289 : move32();
999 289 : Copy32( &( hTdCngDec->ho_env_circ_fx[s_ptr * NUM_ENV_CNG] ), &( hTdCngDec->ho_env_hist_fx[hTdCngDec->ho_hist_ptr * NUM_ENV_CNG] ), NUM_ENV_CNG ); /* Qx */
1000 :
1001 289 : hTdCngDec->ho_hist_size = add( hTdCngDec->ho_hist_size, 1 );
1002 289 : move16();
1003 :
1004 289 : if ( GT_16( hTdCngDec->ho_hist_size, HO_HIST_SIZE ) )
1005 : {
1006 32 : hTdCngDec->ho_hist_size = HO_HIST_SIZE;
1007 32 : move16();
1008 : }
1009 :
1010 289 : s_ptr = add( s_ptr, 1 );
1011 289 : if ( EQ_16( s_ptr, hTdCngDec->ho_circ_size ) )
1012 : {
1013 36 : s_ptr = 0;
1014 36 : move16();
1015 : }
1016 : }
1017 :
1018 189 : IF( hTdCngDec->ho_hist_size > 0 ) /* can be -1 at init MODE1_DTX_IN_CODEC_B_FIX */
1019 : {
1020 : /* *allow_cn_step |= ( st_fx->ho_ener_hist[st_fx->ho_hist_ptr] > 4.0f * st_fx->lp_ener );*/
1021 137 : L_tmp1 = L_shr( hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr], 2 );
1022 137 : L_tmp1 = L_sub( L_tmp1, st_fx->lp_ener_fx );
1023 :
1024 137 : test();
1025 137 : test();
1026 137 : IF( ( L_tmp1 > 0 && ( st_fx->first_CNG || st_fx->element_mode == EVS_MONO ) ) )
1027 : {
1028 8 : *allow_cn_step = s_or( *allow_cn_step, 1 );
1029 8 : move16();
1030 : }
1031 : }
1032 189 : IF( EQ_16( last_element_mode, IVAS_CPE_TD ) )
1033 : {
1034 15 : *allow_cn_step = 1;
1035 15 : move16();
1036 : }
1037 189 : test();
1038 189 : IF( EQ_16( *allow_cn_step, 0 ) && GT_16( hTdCngDec->ho_hist_size, 0 ) )
1039 : {
1040 : /* Use average of energies below last energy */
1041 122 : ptr = hTdCngDec->ho_hist_ptr;
1042 122 : move16();
1043 122 : Copy( &( hTdCngDec->ho_lsp_hist_fx[ptr * M] ), tmp, M ); /* Qx */
1044 122 : m1 = 0;
1045 122 : move16();
1046 122 : IF( L_and( hTdCngDec->ho_sid_bw, (Word32) 0x1 ) == 0 )
1047 : {
1048 77 : Copy32( &hTdCngDec->ho_env_hist_fx[ptr * NUM_ENV_CNG], tmp_env, NUM_ENV_CNG );
1049 77 : m1 = 1;
1050 77 : move16();
1051 : }
1052 122 : L_enr = Mult_32_16( hTdCngDec->ho_ener_hist_fx[ptr], W_DTX_HO_FX[0] ); /* Q6+15-15->Q6 */
1053 :
1054 122 : weights = W_DTX_HO_FX[0]; /* Q15 */
1055 122 : move16();
1056 :
1057 122 : m = 1;
1058 122 : move16();
1059 531 : FOR( k = 1; k < hTdCngDec->ho_hist_size; k++ )
1060 : {
1061 409 : ptr--;
1062 409 : if ( ptr < 0 )
1063 : {
1064 22 : ptr = HO_HIST_SIZE - 1;
1065 22 : move16();
1066 : }
1067 :
1068 409 : test();
1069 409 : IF( LT_32( Mult_32_16( hTdCngDec->ho_ener_hist_fx[ptr], ONE_OVER_BUF_H_NRG_FX ), hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr] ) &&
1070 : GT_32( hTdCngDec->ho_ener_hist_fx[ptr], Mult_32_16( hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr], BUF_L_NRG_FX ) ) )
1071 : {
1072 : /*enr += W_DTX_HO[k] * st_fx->ho_ener_hist[ptr];*/
1073 185 : L_tmp1 = Mult_32_16( hTdCngDec->ho_ener_hist_fx[ptr], W_DTX_HO_FX[k] ); /* Q6+15-15->Q6 */
1074 185 : L_enr = L_add( L_enr, L_tmp1 ); /* Q6 */
1075 :
1076 : /*weights += W_DTX_HO[k];*/
1077 185 : weights = add( weights, W_DTX_HO_FX[k] ); /* Q15 */
1078 :
1079 185 : Copy( &hTdCngDec->ho_lsp_hist_fx[ptr * M], &tmp[m * M], M ); /* Qx */
1080 185 : IF( EQ_32( L_and( hTdCngDec->ho_sid_bw, L_shl( (Word32) 0x1, k ) ), 0 ) )
1081 : {
1082 122 : Copy32( &hTdCngDec->ho_env_hist_fx[ptr * NUM_ENV_CNG], &tmp_env[m1 * NUM_ENV_CNG], NUM_ENV_CNG ); /* Qx */
1083 122 : m1++;
1084 : }
1085 185 : m++;
1086 : }
1087 : }
1088 :
1089 : /*enr /= weights;*/
1090 122 : exp = norm_s( weights );
1091 122 : tmp1 = div_s( shl( 1, sub( 14, exp ) ), weights ); /* Q(15+14-exp-15) */
1092 122 : L_tmp1 = Mult_32_16( L_enr, tmp1 ); /* Q(14-exp+6-15)->Q(5-exp) */
1093 122 : L_enr = L_shl( L_tmp1, add( exp, 1 ) ); /* Q6 */
1094 :
1095 122 : st_fx->lp_ener_fx = L_enr; /* Q6 */
1096 122 : move32();
1097 122 : set32_fx( max_val, 0, 2 );
1098 122 : set16_fx( max_idx, 0, 2 );
1099 :
1100 429 : FOR( i = 0; i < m; i++ )
1101 : {
1102 307 : IF( EQ_16( st_fx->L_frame, L_FRAME ) )
1103 : {
1104 201 : lsp2lsf_fx( &tmp[i * M], lsf_tmp, M, INT_FS_FX );
1105 201 : ftmp_fx = 964;
1106 201 : move16(); /*X2.56 */
1107 201 : tmpv = sub( 16384, add( lsf_tmp[M - 1], ftmp_fx ) ); /*QX2.56*/
1108 201 : L_tmp = L_mult0( tmpv, tmpv ); /*QX6.5536*/
1109 : }
1110 : ELSE
1111 : {
1112 106 : lsp2lsf_fx( &tmp[i * M], lsf_tmp, M, INT_FS_16k_FX );
1113 106 : ftmp_fx = 1205;
1114 106 : move16(); /*QX2.56*/
1115 106 : tmpv = sub( 20480, add( lsf_tmp[M - 1], ftmp_fx ) ); /*QX2.56*/
1116 106 : L_tmp = L_mult0( tmpv, tmpv ); /*QX6.5536*/
1117 : }
1118 :
1119 307 : tmpv = sub( lsf_tmp[0], ftmp_fx ); /*QX2.56*/
1120 307 : L_tmp = L_mac0( L_tmp, tmpv, tmpv ); /*QX6.5536*/
1121 4912 : FOR( j = 0; j < M - 1; j++ )
1122 : {
1123 4605 : tmpv = sub( sub( lsf_tmp[j + 1], lsf_tmp[j] ), ftmp_fx ); /*QX2.56*/
1124 4605 : L_tmp = L_mac0( L_tmp, tmpv, tmpv ); /*QX6.5536*/
1125 : }
1126 :
1127 307 : C[i] = Mpy_32_16_1( L_tmp, 1928 ); /*QX6.5536*/
1128 307 : move32();
1129 :
1130 307 : IF( GT_32( C[i], max_val[0] ) )
1131 : {
1132 220 : max_val[1] = max_val[0];
1133 220 : move32();
1134 220 : max_idx[1] = max_idx[0];
1135 220 : move16();
1136 220 : max_val[0] = C[i];
1137 220 : move32();
1138 220 : max_idx[0] = i;
1139 220 : move16();
1140 : }
1141 87 : ELSE IF( GT_32( C[i], max_val[1] ) )
1142 : {
1143 49 : max_val[1] = C[i];
1144 49 : move32();
1145 49 : max_idx[1] = i;
1146 49 : move16();
1147 : }
1148 : }
1149 :
1150 122 : IF( EQ_16( m, 1 ) )
1151 : {
1152 42 : Copy( tmp, lsp_tmp, M ); /* Qx */
1153 : }
1154 80 : ELSE IF( LT_16( m, 4 ) )
1155 : {
1156 1020 : FOR( i = 0; i < M; i++ )
1157 : {
1158 960 : L_tmp1 = 0;
1159 960 : move32();
1160 3504 : FOR( j = 0; j < m; j++ )
1161 : {
1162 2544 : L_tmp1 = L_add( L_tmp1, L_deposit_l( tmp[j * M + i] ) );
1163 : }
1164 :
1165 960 : L_tmp1 = L_sub( L_tmp1, L_deposit_l( tmp[max_idx[0] * M + i] ) );
1166 960 : tmpv = div_s( 1, sub( m, 1 ) ); /*Q15*/
1167 960 : L_tmp1 = Mpy_32_16_1( L_tmp1, tmpv ); /*Q15*/
1168 960 : lsp_tmp[i] = extract_l( L_tmp1 ); /*Q15*/
1169 960 : move16();
1170 : }
1171 : }
1172 : ELSE
1173 : {
1174 340 : FOR( i = 0; i < M; i++ )
1175 : {
1176 320 : L_tmp1 = 0;
1177 320 : move32();
1178 2016 : FOR( j = 0; j < m; j++ )
1179 : {
1180 1696 : L_tmp1 = L_add( L_tmp1, L_deposit_l( tmp[j * M + i] ) );
1181 : }
1182 :
1183 320 : L_tmp1 = L_sub( L_tmp1, L_add( L_deposit_l( tmp[max_idx[0] * M + i] ), L_deposit_l( tmp[max_idx[1] * M + i] ) ) ); /*Q15*/
1184 320 : tmpv = div_s( 1, sub( m, 2 ) ); /*Q15*/
1185 320 : L_tmp1 = Mpy_32_16_1( L_tmp1, tmpv ); /*Q15*/
1186 320 : lsp_tmp[i] = extract_l( L_tmp1 ); /*Q15*/
1187 320 : move16();
1188 : }
1189 : }
1190 :
1191 122 : dist = 0;
1192 122 : move16(); /*Q15*/
1193 122 : max_dev = 0;
1194 122 : move16(); /*Q15*/
1195 2074 : FOR( i = 0; i < M; i++ )
1196 : {
1197 1952 : dev = abs_s( sub( lsp_tmp[i], lsp_new[i] ) ); /*Q15*/
1198 1952 : dist = add_o( dist, dev, &Overflow ); /*Q15*/
1199 1952 : if ( GT_16( dev, max_dev ) )
1200 : {
1201 610 : max_dev = dev;
1202 610 : move16();
1203 : }
1204 : }
1205 :
1206 122 : test();
1207 122 : IF( GT_16( dist, 13107 ) || GT_16( max_dev, 3277 ) ) /* 0.4 and 0.1 in Q15 */
1208 : {
1209 34 : FOR( i = 0; i < M; i++ )
1210 : {
1211 32 : st_fx->lspCNG_fx[i] = lsp_tmp[i];
1212 32 : move16(); /*Q15*/
1213 : }
1214 : }
1215 : ELSE
1216 : {
1217 2040 : FOR( i = 0; i < M; i++ )
1218 : {
1219 : /* AR low-pass filter */
1220 1920 : st_fx->lspCNG_fx[i] = add( mult_r( 26214, lsp_tmp[i] ), mult_r( 6554, lsp_new[i] ) ); /* Q15 */
1221 1920 : move16();
1222 : }
1223 : }
1224 122 : IF( m1 > 0 )
1225 : {
1226 1953 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
1227 : {
1228 1860 : L_tmp = L_deposit_l( 0 );
1229 5840 : FOR( j = 0; j < m1; j++ )
1230 : {
1231 : /* env[i] += tmp_env[j*NUM_ENV_CNG+i];*/
1232 3980 : L_tmp = L_add_sat( L_tmp, tmp_env[j * NUM_ENV_CNG + i] );
1233 : }
1234 : /* env[i] /= (float)m1; */
1235 : /* env[i] = env[i] - 2*st_fx->lp_ener_fx; */
1236 1860 : IF( EQ_16( m1, 1 ) )
1237 : {
1238 680 : L_tmp = L_sub_sat( L_tmp, L_add_sat( st_fx->lp_ener_fx, st_fx->lp_ener_fx ) ); /* Q6 */
1239 : }
1240 : ELSE
1241 : {
1242 1180 : tmp1 = div_s( 1, m1 );
1243 1180 : L_tmp = Mult_32_16( L_tmp, tmp1 ); /* Q6 */
1244 1180 : L_tmp = L_sub_sat( L_tmp, L_add_sat( st_fx->lp_ener_fx, st_fx->lp_ener_fx ) ); /* Q6 */
1245 : }
1246 1860 : env[i] = L_tmp; /* Q6 */
1247 1860 : move32();
1248 : }
1249 :
1250 93 : Copy32( env, hTdCngDec->lp_env_fx, NUM_ENV_CNG ); /* Q6 */
1251 : }
1252 : }
1253 : ELSE
1254 : {
1255 67 : Copy( lsp_new, st_fx->lspCNG_fx, M ); /* use newly analyzed ISFs */ /* Q15 */
1256 : }
1257 : }
1258 :
1259 2378 : test();
1260 2378 : IF( EQ_32( st_fx->core_brate, SID_1k75 ) || EQ_32( st_fx->core_brate, SID_2k40 ) )
1261 : {
1262 : /* Update hangover memory during CNG */
1263 417 : test();
1264 417 : IF( ( *allow_cn_step == 0 ) && LT_32( hTdCngDec->Enew_fx, L_add_sat( st_fx->lp_ener_fx, L_shr( st_fx->lp_ener_fx, 1 ) ) ) )
1265 : {
1266 : /* update the pointer to circular buffer of old LSP vectors */
1267 285 : hTdCngDec->ho_hist_ptr++;
1268 285 : move16();
1269 285 : if ( EQ_16( hTdCngDec->ho_hist_ptr, HO_HIST_SIZE ) )
1270 : {
1271 34 : hTdCngDec->ho_hist_ptr = 0;
1272 34 : move16();
1273 : }
1274 :
1275 : /* update the circular buffer of old LSP vectors with the new LSP vector */
1276 285 : Copy( lsp_new, &( hTdCngDec->ho_lsp_hist_fx[( hTdCngDec->ho_hist_ptr ) * M] ), M ); /* Q15 */
1277 :
1278 : /* update the hangover energy buffer */
1279 285 : hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr] = hTdCngDec->Enew_fx; /* Q6 */
1280 285 : move32();
1281 285 : test();
1282 285 : IF( EQ_32( st_fx->core_brate, SID_2k40 ) && ( *sid_bw == 0 ) )
1283 : {
1284 : /* enr1 = (float)log10( st->Enew*L_frame + 0.1f ) / (float)log10( 2.0f );*/
1285 0 : exp = norm_l( hTdCngDec->Enew_fx );
1286 0 : L_tmp = L_shl( hTdCngDec->Enew_fx, exp ); /*Q(exp+6)*/
1287 0 : L_tmp = Mult_32_16( L_tmp, shl( st_fx->L_frame, 5 ) ); /*Q(exp+6+5-15=exp-4)*/
1288 0 : L_tmp = L_shr_sat( L_tmp, sub( exp, 10 ) ); /*Q6*/
1289 0 : exp = norm_l( L_tmp );
1290 0 : fra = Log2_norm_lc( L_shl( L_tmp, exp ) );
1291 0 : exp = sub( sub( 30, exp ), 6 );
1292 0 : L_tmp = L_Comp( exp, fra );
1293 0 : enr1 = L_shr( L_tmp, 10 ); /* Q6 */
1294 :
1295 0 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
1296 : {
1297 : /* get quantized envelope */
1298 : /* env[i] = pow(2.0f,(enr1 - q_env[i])) + 2*st->Enew;*/
1299 0 : L_tmp = L_sub( enr1, q_env[i] ); /* Q6 */
1300 0 : L_tmp = L_shl( L_tmp, 10 ); /* 16 */
1301 0 : temp_lo_fx = L_Extract_lc( L_tmp, &temp_hi_fx );
1302 :
1303 0 : exp_pow = sub( 14, temp_hi_fx );
1304 0 : L_tmp = Pow2( 14, temp_lo_fx ); /* Qexp_pow */
1305 0 : env[i] = L_shl( L_tmp, sub( 6, exp_pow ) ); /* Q6 */
1306 0 : move32();
1307 0 : L_tmp = L_add( hTdCngDec->Enew_fx, hTdCngDec->Enew_fx );
1308 0 : env[i] = L_add( env[i], L_tmp ); /* Q6 */
1309 0 : move32();
1310 : }
1311 0 : hTdCngDec->ho_sid_bw = L_shl( L_and( hTdCngDec->ho_sid_bw, (Word32) 0x3fffffffL ), 1 ); /* Q0 */
1312 0 : move32();
1313 0 : Copy32( env, &( hTdCngDec->ho_env_hist_fx[hTdCngDec->ho_hist_ptr * NUM_ENV_CNG] ), NUM_ENV_CNG ); /* Q6 */
1314 : }
1315 285 : ELSE IF( ( *sid_bw != 0 ) )
1316 : {
1317 285 : hTdCngDec->ho_sid_bw = L_shl( L_and( hTdCngDec->ho_sid_bw, (Word32) 0x3fffffffL ), 1 ); /* Q0 */
1318 285 : move32();
1319 285 : hTdCngDec->ho_sid_bw = L_or( hTdCngDec->ho_sid_bw, 0x1L ); /* Q0 */
1320 285 : move32();
1321 : }
1322 :
1323 285 : hTdCngDec->ho_hist_size = add( hTdCngDec->ho_hist_size, 1 );
1324 285 : move16();
1325 285 : if ( GT_16( hTdCngDec->ho_hist_size, HO_HIST_SIZE ) )
1326 : {
1327 169 : hTdCngDec->ho_hist_size = HO_HIST_SIZE;
1328 169 : move16();
1329 : }
1330 : }
1331 : /* Update the frame length memory */
1332 417 : st_fx->last_CNG_L_frame = st_fx->L_frame;
1333 417 : move16();
1334 :
1335 417 : if ( NE_32( st_fx->core_brate, SID_1k75 ) )
1336 : {
1337 417 : hTdCngDec->num_ho = m;
1338 417 : move16();
1339 : }
1340 : }
1341 :
1342 2378 : IF( st_fx->element_mode == EVS_MONO )
1343 : {
1344 0 : st_fx->last_CNG_L_frame = st_fx->L_frame;
1345 0 : move16();
1346 :
1347 0 : IF( NE_32( st_fx->core_brate, SID_1k75 ) )
1348 : {
1349 0 : hTdCngDec->num_ho = m;
1350 0 : move16();
1351 : }
1352 : }
1353 2378 : IF( st_fx->Opt_AMR_WB )
1354 : {
1355 0 : E_LPC_f_isp_a_conversion( st_fx->lspCNG_fx, Aq, M );
1356 : }
1357 : ELSE
1358 : {
1359 2378 : E_LPC_f_lsp_a_conversion( st_fx->lspCNG_fx, Aq, M );
1360 : }
1361 :
1362 2378 : tmp_loop = shr( st_fx->L_frame, 6 );
1363 11044 : FOR( i = 1; i < tmp_loop; i++ ) /* L_frame/L_SUBFR */
1364 : {
1365 8666 : Copy( Aq, &Aq[i * ( M + 1 )], add( M, 1 ) ); /* Q12 */
1366 : }
1367 :
1368 2378 : return;
1369 : }
1370 :
1371 : /*---------------------------------------------------------------------*
1372 : * swb_CNG_dec()
1373 : *
1374 : * Comfort noise generation for SHB signal
1375 : *---------------------------------------------------------------------*/
1376 :
1377 1852 : void swb_CNG_dec_fx(
1378 : Decoder_State *st_fx, /* i/o: State structure */
1379 : const Word16 *synth_fx, /* i : ACELP core synthesis at 32kHz Qsyn*/
1380 : Word16 *shb_synth_fx, /* o : high-band CNG synthesis Qx*/
1381 : const Word16 sid_bw, /* i : 0-NB/WB, 1-SWB SID Q0*/
1382 : const Word16 Qsyn /* i : Q value of ACELP core synthesis */
1383 : )
1384 : {
1385 1852 : test();
1386 1852 : IF( EQ_32( st_fx->core_brate, FRAME_NO_DATA ) || EQ_32( st_fx->core_brate, SID_2k40 ) )
1387 : {
1388 : /* SHB SID decoding and CNG */
1389 0 : test();
1390 0 : IF( EQ_16( st_fx->cng_type, LP_CNG ) && EQ_16( st_fx->extl, SWB_CNG ) )
1391 : {
1392 0 : shb_CNG_decod_fx( st_fx, synth_fx, shb_synth_fx, sid_bw, Qsyn );
1393 : }
1394 0 : st_fx->last_vad_fx = 0;
1395 0 : move16();
1396 0 : st_fx->hTdCngDec->burst_cnt_fx = 0;
1397 0 : move16();
1398 : }
1399 : ELSE
1400 : {
1401 1852 : st_fx->last_vad_fx = 1;
1402 1852 : move16();
1403 1852 : st_fx->hTdCngDec->burst_cnt_fx = add( st_fx->hTdCngDec->burst_cnt_fx, 1 );
1404 1852 : move16();
1405 1852 : if ( GT_16( st_fx->hTdCngDec->burst_cnt_fx, 10 ) )
1406 : {
1407 167 : st_fx->hTdCngDec->burst_cnt_fx = 0;
1408 167 : move16();
1409 : }
1410 : }
1411 :
1412 1852 : return;
1413 : }
1414 :
1415 213448 : void swb_CNG_dec_ivas_fx(
1416 : Decoder_State *st_fx, /* i/o: State structure */
1417 : const Word16 *synth_fx, /* i : ACELP core synthesis at 32kHz Qsyn*/
1418 : Word16 *shb_synth_fx, /* o : high-band CNG synthesis Qx*/
1419 : const Word16 sid_bw, /* i : 0-NB/WB, 1-SWB SID Q0*/
1420 : const Word16 Qsyn /* i : Q value of ACELP core synthesis */
1421 : )
1422 : {
1423 213448 : test();
1424 213448 : IF( EQ_32( st_fx->core_brate, FRAME_NO_DATA ) || EQ_32( st_fx->core_brate, SID_2k40 ) )
1425 : {
1426 : /* SHB SID decoding and CNG */
1427 12817 : test();
1428 12817 : IF( EQ_16( st_fx->cng_type, LP_CNG ) && EQ_16( st_fx->extl, SWB_CNG ) )
1429 : {
1430 1788 : shb_CNG_decod_ivas_fx( st_fx, synth_fx, shb_synth_fx, sid_bw, Qsyn );
1431 : }
1432 12817 : st_fx->last_vad_fx = 0;
1433 12817 : move16();
1434 12817 : st_fx->hTdCngDec->burst_cnt_fx = 0;
1435 12817 : move16();
1436 : }
1437 : ELSE
1438 : {
1439 200631 : st_fx->last_vad_fx = 1;
1440 200631 : move16();
1441 200631 : st_fx->hTdCngDec->burst_cnt_fx = add_sat( st_fx->hTdCngDec->burst_cnt_fx, 1 ); // saturation reached?
1442 200631 : move16();
1443 200631 : if ( GT_16( st_fx->hTdCngDec->burst_cnt_fx, 10 ) )
1444 : {
1445 17347 : st_fx->hTdCngDec->burst_cnt_fx = 0;
1446 17347 : move16();
1447 : }
1448 : }
1449 :
1450 213448 : return;
1451 : }
1452 :
1453 : /*---------------------------------------------------------------------*
1454 : * shb_CNG_decod()
1455 : *
1456 : * Main routine of SHB SID decoding and CNG
1457 : *---------------------------------------------------------------------*/
1458 :
1459 0 : static void shb_CNG_decod_fx(
1460 : Decoder_State *st_fx, /* i/o: State structure */
1461 : const Word16 *synth_fx, /* i : ACELP core synthesis at 32kHz Qsyn*/
1462 : Word16 *shb_synth_fx, /* o : high-band CNG synthesis Qx*/
1463 : const Word16 sid_bw, /* i : 0-NB/WB, 1-SWB SID Q0*/
1464 : const Word16 Qsyn /* i : Q value of ACELP core synthesis */
1465 : )
1466 : {
1467 : Word16 i;
1468 : Word16 idx_ener_fx;
1469 : TD_CNG_DEC_HANDLE hTdCngDec;
1470 : Word16 shb_lpcCNG_fx[LPC_SHB_ORDER + 1];
1471 : Word16 shb_lspCNG_fx[LPC_SHB_ORDER];
1472 : Word16 excTmp_fx[L_FRAME16k];
1473 : Word16 excSHB_fx[L_FRAME16k];
1474 : Word16 tmp_lsp[LPC_SHB_ORDER];
1475 : Word16 ener_excSHB_fx;
1476 : Word32 wb_ener_fx;
1477 : Word16 wb_ener16_fx;
1478 : Word32 L_gain_fx;
1479 : Word16 gain_fx;
1480 : Word16 shb_syn16k_fx[L_FRAME16k];
1481 : Word16 tmp;
1482 : Word16 step_fx;
1483 : Word16 interp_fx;
1484 : Word16 ener_fx;
1485 : Word16 exp, exp1;
1486 : Word16 fra;
1487 : Word32 L_tmp;
1488 : Word16 tmp2;
1489 0 : Word16 allow_cn_step_fx = 0;
1490 0 : move16();
1491 : Word16 q;
1492 : TD_BWE_DEC_HANDLE hBWE_TD;
1493 :
1494 0 : hBWE_TD = st_fx->hBWE_TD;
1495 0 : hTdCngDec = st_fx->hTdCngDec;
1496 :
1497 0 : IF( st_fx->bfi == 0 )
1498 : {
1499 0 : test();
1500 0 : IF( EQ_32( st_fx->core_brate, SID_2k40 ) && EQ_16( sid_bw, 1 ) )
1501 : {
1502 0 : idx_ener_fx = get_next_indice_fx( st_fx, 4 );
1503 :
1504 0 : if ( !idx_ener_fx )
1505 : {
1506 0 : idx_ener_fx = -15;
1507 0 : move16();
1508 : }
1509 0 : IF( st_fx->element_mode == EVS_MONO )
1510 : {
1511 : /* de-quantization of SHB CNG parameters */
1512 0 : L_tmp = L_mult( idx_ener_fx, 27400 ); /*Q14 */
1513 0 : hTdCngDec->last_shb_cng_ener_fx = extract_l( L_shr( L_sub( L_tmp, 295924 ), 6 ) ); /*Q8 */
1514 0 : move16();
1515 : }
1516 : ELSE
1517 : {
1518 : }
1519 : }
1520 : }
1521 :
1522 : /* SHB spectrum estimation */
1523 :
1524 :
1525 0 : interp_fx = s_min( hTdCngDec->shb_dtx_count_fx, 32 );
1526 0 : interp_fx = shl_sat( interp_fx, 10 ); /*Q15*/
1527 0 : FOR( i = 0; i < LPC_SHB_ORDER; i++ )
1528 : {
1529 0 : tmp2 = mult( interp_fx, hTdCngDec->lsp_shb_prev_fx[i] ); /*Q14*/
1530 0 : tmp = mult( sub( 32767, interp_fx ), hTdCngDec->lsp_shb_prev_prev_fx[i] ); /*Q14*/
1531 0 : shb_lspCNG_fx[i] = add( tmp2, tmp );
1532 0 : move16(); /*Q14*/
1533 : }
1534 :
1535 0 : IF( NE_16( st_fx->element_mode, IVAS_CPE_DFT ) )
1536 : {
1537 0 : if ( LT_16( hTdCngDec->shb_dtx_count_fx, 1000 ) )
1538 : {
1539 0 : hTdCngDec->shb_dtx_count_fx = add( hTdCngDec->shb_dtx_count_fx, 1 );
1540 0 : move16();
1541 : }
1542 : }
1543 0 : E_LPC_lsf_lsp_conversion( shb_lspCNG_fx, tmp_lsp, LPC_SHB_ORDER ); /*Q14*/
1544 0 : E_LPC_f_lsp_a_conversion( tmp_lsp, shb_lpcCNG_fx, LPC_SHB_ORDER );
1545 :
1546 0 : Copy_Scale_sig( shb_lpcCNG_fx, shb_lpcCNG_fx, LPC_SHB_ORDER + 1, sub( norm_s( shb_lpcCNG_fx[0] ), 2 ) ); /* Q12 */
1547 :
1548 : /* SHB energy estimation */
1549 0 : wb_ener_fx = L_deposit_l( 1 ); /*Q1 */
1550 0 : FOR( i = 0; i < L_FRAME32k; i++ )
1551 : {
1552 0 : wb_ener_fx = L_add( wb_ener_fx, Mpy_32_16_1( L_mult0( synth_fx[i], synth_fx[i] ), 51 ) ); /* 2*Qsyn */
1553 : }
1554 0 : exp = norm_l( wb_ener_fx );
1555 0 : fra = Log2_norm_lc( L_shl( wb_ener_fx, exp ) );
1556 0 : exp = sub( 30, add( exp, shl( Qsyn, 1 ) ) );
1557 0 : wb_ener_fx = Mpy_32_16( exp, fra, LG10 );
1558 0 : wb_ener16_fx = round_fx( L_shl( wb_ener_fx, 10 ) ); /*wb_ener_fx in Q8 */
1559 0 : if ( !st_fx->first_CNG )
1560 : {
1561 0 : hTdCngDec->wb_cng_ener_fx = wb_ener16_fx;
1562 0 : move16(); /*Q8 */
1563 : }
1564 0 : if ( GT_16( abs_s( sub( wb_ener16_fx, hTdCngDec->wb_cng_ener_fx ) ), 3072 ) )
1565 : {
1566 0 : allow_cn_step_fx = 1;
1567 0 : move16();
1568 : }
1569 :
1570 0 : IF( EQ_16( allow_cn_step_fx, 1 ) )
1571 : {
1572 0 : hTdCngDec->wb_cng_ener_fx = wb_ener16_fx;
1573 0 : move16(); /*Q8 */
1574 : }
1575 : ELSE
1576 : {
1577 0 : tmp = sub( wb_ener16_fx, hTdCngDec->wb_cng_ener_fx ); /*Q8 */
1578 0 : tmp = mult_r( tmp, 29491 ); /*Q8 */
1579 0 : hTdCngDec->wb_cng_ener_fx = add( hTdCngDec->wb_cng_ener_fx, tmp ); /*Q8 */
1580 0 : move16();
1581 : }
1582 0 : test();
1583 0 : test();
1584 0 : IF( EQ_32( st_fx->core_brate, SID_2k40 ) && EQ_16( sid_bw, 1 ) && ( st_fx->bfi == 0 ) )
1585 : {
1586 0 : hTdCngDec->last_wb_cng_ener_fx = hTdCngDec->wb_cng_ener_fx;
1587 0 : move16();
1588 :
1589 0 : if ( !st_fx->first_CNG )
1590 : {
1591 0 : hTdCngDec->shb_cng_ener_fx = hTdCngDec->last_shb_cng_ener_fx;
1592 0 : move16();
1593 : }
1594 : }
1595 :
1596 0 : gain_fx = sub( hTdCngDec->wb_cng_ener_fx, hTdCngDec->last_wb_cng_ener_fx ); /* Q8 */
1597 0 : if ( GT_16( gain_fx, 15 ) )
1598 : {
1599 0 : gain_fx = 15;
1600 0 : move16();
1601 : }
1602 0 : step_fx = sub( add( gain_fx, hTdCngDec->last_shb_cng_ener_fx ), hTdCngDec->shb_cng_ener_fx ); /*Q8 */
1603 0 : test();
1604 0 : IF( EQ_16( allow_cn_step_fx, 1 ) || GT_32( st_fx->last_core_brate, SID_2k40 ) )
1605 : {
1606 0 : hTdCngDec->shb_cng_ener_fx = add( hTdCngDec->shb_cng_ener_fx, step_fx ); /* Q8 */
1607 0 : move16();
1608 : }
1609 : ELSE
1610 : {
1611 0 : hTdCngDec->shb_cng_ener_fx = add( hTdCngDec->shb_cng_ener_fx, mult( 8192, step_fx ) ); /*Q8 */
1612 0 : move16();
1613 : }
1614 : /* generate white noise excitation */
1615 0 : FOR( i = 0; i < L_FRAME16k; i++ )
1616 : {
1617 0 : excTmp_fx[i] = shr_r( Random( &hTdCngDec->swb_cng_seed ), 8 );
1618 0 : move16(); /*Q-8*/
1619 : }
1620 :
1621 : /* synthesis filtering */
1622 0 : Syn_filt_s( 0, shb_lpcCNG_fx, LPC_SHB_ORDER, excTmp_fx, excSHB_fx, L_FRAME16k, hBWE_TD->state_lpc_syn_fx, 1 );
1623 :
1624 :
1625 : /* synthesis signal gain shaping */
1626 0 : L_tmp = 0;
1627 0 : move32();
1628 0 : FOR( i = 0; i < L_FRAME16k; i++ )
1629 : {
1630 0 : L_tmp = L_add( L_tmp, Mpy_32_16_1( L_mult0( excSHB_fx[i], excSHB_fx[i] ), 102 ) ); /*Q-16*/
1631 : }
1632 0 : q = norm_l( L_tmp );
1633 0 : L_tmp = L_shl( L_tmp, q );
1634 0 : q = sub( q, 32 );
1635 0 : ener_excSHB_fx = round_fx( L_tmp ); /*Qq */
1636 0 : IF( EQ_16( st_fx->last_vad_fx, 1 ) )
1637 : {
1638 0 : hTdCngDec->trans_cnt_fx = 0;
1639 0 : move16();
1640 0 : test();
1641 0 : IF( GT_16( hTdCngDec->burst_cnt_fx, 3 ) && NE_16( st_fx->last_core, HQ_CORE ) )
1642 : {
1643 0 : hTdCngDec->trans_cnt_fx = 5;
1644 0 : move16();
1645 : }
1646 : }
1647 :
1648 0 : ener_fx = hTdCngDec->shb_cng_ener_fx;
1649 0 : move16(); /*Q8 */
1650 0 : IF( hTdCngDec->trans_cnt_fx > 0 )
1651 : {
1652 0 : i = extract_l( L_mult0( hTdCngDec->trans_cnt_fx, 17 ) ); /*Q0 */
1653 0 : ener_fx = add_sat( hTdCngDec->shb_cng_ener_fx, mult( sin_table256_fx[i], sub_sat( hTdCngDec->last_shb_ener_fx, hTdCngDec->shb_cng_ener_fx ) ) ); /*Q8 */
1654 0 : hTdCngDec->trans_cnt_fx = sub( hTdCngDec->trans_cnt_fx, 1 );
1655 0 : move16();
1656 : }
1657 :
1658 0 : tmp = mult( 3277, ener_fx ); /*Q8 */
1659 0 : L_tmp = L_mult( 27213, tmp ); /*Q22, 27213=3.321928 in Q13 */
1660 0 : L_tmp = L_shr( L_tmp, 6 ); /*Q16 */
1661 0 : L_tmp = L_add( L_tmp, 10 << 16 );
1662 0 : if ( L_tmp < 0 )
1663 : {
1664 0 : L_tmp = 0;
1665 0 : move32();
1666 : }
1667 0 : fra = L_Extract_lc( L_tmp, &exp );
1668 0 : L_tmp = L_shl_sat( Pow2( exp, fra ), 5 ); /*Q5 */
1669 0 : L_tmp = L_shr( L_tmp, 10 );
1670 0 : if ( !L_tmp )
1671 : {
1672 0 : L_tmp = 1; /*Q5 */
1673 : }
1674 0 : exp = norm_l( L_tmp );
1675 0 : L_tmp = L_shl( L_tmp, exp ); /*Q31*/
1676 0 : tmp = extract_h( L_tmp ); /*Q15*/
1677 0 : exp = sub( exp, 16 );
1678 0 : exp1 = norm_s( ener_excSHB_fx );
1679 0 : fra = shl( ener_excSHB_fx, exp1 ); /*Q15*/
1680 :
1681 0 : IF( GT_16( fra, tmp ) )
1682 : {
1683 0 : fra = shr( fra, 1 ); /*Q15*/
1684 0 : exp1 = sub( exp1, 1 );
1685 : }
1686 0 : tmp = div_s( fra, tmp ); /*Q15*/
1687 :
1688 0 : L_tmp = L_deposit_h( tmp ); /*Q31 */
1689 0 : tmp = sub( add( 5, exp ), add( q, exp1 ) );
1690 0 : L_gain_fx = Isqrt_lc( L_tmp, &tmp ); /*Q31-Qtmp */
1691 :
1692 0 : FOR( i = 0; i < L_FRAME16k; i++ )
1693 : {
1694 0 : shb_syn16k_fx[i] = extract_l( L_shr( Mpy_32_16_1( L_gain_fx, excSHB_fx[i] ), sub( 5, tmp ) ) ); /*Q3 = 31-Qtmp-8-15-5+Qtmp */
1695 0 : move16();
1696 : }
1697 :
1698 0 : test();
1699 0 : IF( EQ_16( st_fx->last_extl, SWB_TBE ) || EQ_16( st_fx->last_extl, FB_TBE ) )
1700 : {
1701 : /* rescale the Hilbert memories to Q0 */
1702 0 : FOR( i = 0; i < HILBERT_MEM_SIZE; i++ )
1703 : {
1704 0 : hBWE_TD->genSHBsynth_Hilbert_Mem_fx[i] = L_shr( hBWE_TD->genSHBsynth_Hilbert_Mem_fx[i], hBWE_TD->prev_Q_bwe_syn2 ); /* hBWE_TD->prev_Q_bwe_syn2 */
1705 0 : move32();
1706 : }
1707 :
1708 0 : FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ )
1709 : {
1710 0 : hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx[i] = shr( hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx[i], hBWE_TD->prev_Q_bwe_syn2 ); /* hBWE_TD->prev_Q_bwe_syn2 */
1711 0 : move16();
1712 : }
1713 : }
1714 0 : GenSHBSynth_fx( shb_syn16k_fx, shb_synth_fx, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, st_fx->L_frame, &( hBWE_TD->syn_dm_phase ) );
1715 :
1716 0 : IF( EQ_32( st_fx->output_Fs, 48000 ) )
1717 : {
1718 0 : interpolate_3_over_2_allpass_fx( shb_synth_fx, L_FRAME32k, shb_synth_fx, hTdCngDec->interpol_3_2_cng_dec_fx, allpass_poles_3_ov_2 );
1719 : }
1720 :
1721 0 : ResetSHBbuffer_Dec_fx( st_fx->hBWE_TD, st_fx->extl );
1722 :
1723 0 : return;
1724 : }
1725 :
1726 1788 : static void shb_CNG_decod_ivas_fx(
1727 : Decoder_State *st, /* i/o: State structure */
1728 : const Word16 *synth_fx, /* i : ACELP core synthesis at 32kHz Qsyn*/
1729 : Word16 *shb_synth_fx, /* o : high-band CNG synthesis Qx*/
1730 : const Word16 sid_bw, /* i : 0-NB/WB, 1-SWB SID Q0*/
1731 : const Word16 Qsyn )
1732 : {
1733 : Word16 i;
1734 : Word16 idx_ener;
1735 : TD_CNG_DEC_HANDLE hTdCngDec;
1736 : Word16 shb_lpcCNG_fx[LPC_SHB_ORDER + 1];
1737 : Word16 shb_lspCNG_fx[LPC_SHB_ORDER];
1738 : Word16 excTmp_fx[L_FRAME16k];
1739 : Word16 excSHB_fx[L_FRAME16k];
1740 : Word16 tmp_lsp[LPC_SHB_ORDER];
1741 : Word16 ener_excSHB_fx;
1742 : Word32 wb_ener_fx;
1743 : Word16 wb_ener16_fx;
1744 : Word32 L_gain_fx;
1745 : Word32 gain_fx;
1746 : Word16 shb_syn16k_fx[L_FRAME16k];
1747 : Word32 tmp;
1748 : Word32 step_fx;
1749 : Word16 interp_fx;
1750 : Word32 ener_fx;
1751 : Word16 exp, exp1;
1752 : Word16 fra;
1753 : Word32 L_tmp;
1754 : Word16 allow_cn_step_fx;
1755 : Word16 q;
1756 : TD_BWE_DEC_HANDLE hBWE_TD;
1757 :
1758 1788 : hBWE_TD = st->hBWE_TD;
1759 1788 : hTdCngDec = st->hTdCngDec;
1760 1788 : allow_cn_step_fx = 0;
1761 1788 : move16();
1762 :
1763 1788 : IF( st->bfi == 0 )
1764 : {
1765 1788 : test();
1766 1788 : IF( EQ_32( st->core_brate, SID_2k40 ) && EQ_16( sid_bw, 1 ) )
1767 : {
1768 324 : idx_ener = get_next_indice_fx( st, 4 );
1769 :
1770 324 : IF( idx_ener == 0 )
1771 : {
1772 5 : idx_ener = -15;
1773 5 : move16();
1774 : }
1775 :
1776 : /* de-quantization of SHB CNG parameters */
1777 324 : IF( st->element_mode == EVS_MONO )
1778 : {
1779 0 : hTdCngDec->last_shb_cng_ener_fx_32 = L_sub( L_mult0( idx_ener, 6850 ), 36991 ); // Q11
1780 0 : move32();
1781 : }
1782 : ELSE
1783 : {
1784 324 : hTdCngDec->last_shb_cng_ener_fx_32 = L_sub( L_mult0( idx_ener, 8807 ), 36991 ); // Q11
1785 324 : move32();
1786 : }
1787 : }
1788 : }
1789 :
1790 : /* SHB spectrum estimation */
1791 1788 : interp_fx = s_min( hTdCngDec->shb_dtx_count_fx, 32 );
1792 1788 : interp_fx = shl_sat( interp_fx, 10 ); /*Q15*/
1793 :
1794 19668 : FOR( i = 0; i < LPC_SHB_ORDER; i++ )
1795 : {
1796 17880 : shb_lspCNG_fx[i] = add( mult_r( interp_fx, hTdCngDec->lsp_shb_prev_fx[i] ), mult_r( sub( 32767, interp_fx ), hTdCngDec->lsp_shb_prev_prev_fx[i] ) ); // Q14
1797 17880 : move16();
1798 : }
1799 :
1800 1788 : IF( LE_16( hTdCngDec->shb_dtx_count_fx, 1000 ) )
1801 : {
1802 1788 : hTdCngDec->shb_dtx_count_fx = add( hTdCngDec->shb_dtx_count_fx, 1 );
1803 1788 : move16();
1804 : }
1805 :
1806 1788 : E_LPC_lsf_lsp_conversion( shb_lspCNG_fx, tmp_lsp, LPC_SHB_ORDER ); /*Q14*/
1807 1788 : E_LPC_f_lsp_a_conversion( tmp_lsp, shb_lpcCNG_fx, LPC_SHB_ORDER );
1808 :
1809 1788 : Copy_Scale_sig( shb_lpcCNG_fx, hTdCngDec->shb_lpcCNG_fx, LPC_SHB_ORDER + 1, sub( norm_s( shb_lpcCNG_fx[0] ), -1 ) ); /* Q15 */
1810 :
1811 1788 : Copy_Scale_sig( shb_lpcCNG_fx, shb_lpcCNG_fx, LPC_SHB_ORDER + 1, sub( norm_s( shb_lpcCNG_fx[0] ), 2 ) ); /* Q12 */
1812 :
1813 : /* SHB energy estimation */
1814 1788 : wb_ener_fx = L_deposit_l( 1 ); /*Q1 */
1815 1788 : IF( NE_16( st->element_mode, IVAS_CPE_DFT ) )
1816 : {
1817 0 : FOR( i = 0; i < L_FRAME32k; i++ )
1818 : {
1819 0 : wb_ener_fx = L_add( wb_ener_fx, Mpy_32_16_1( L_mult0( synth_fx[i], synth_fx[i] ), 51 ) ); /* 2*Qsyn */
1820 : }
1821 : }
1822 1788 : exp = norm_l( wb_ener_fx );
1823 1788 : fra = Log2_norm_lc( L_shl( wb_ener_fx, exp ) );
1824 1788 : exp = sub( 30, add( exp, shl( Qsyn, 1 ) ) );
1825 1788 : wb_ener_fx = Mpy_32_16( exp, fra, LG10 );
1826 1788 : wb_ener16_fx = round_fx( L_shl( wb_ener_fx, 10 ) ); /*wb_ener_fx in Q8 */
1827 1788 : Word32 wb_ener32_fx = L_shl( wb_ener16_fx, 3 ); /*wb_ener_fx in Q11 */
1828 1788 : if ( EQ_16( st->first_CNG, 0 ) )
1829 : {
1830 19 : hTdCngDec->wb_cng_ener_fx_32 = wb_ener32_fx;
1831 19 : move32(); /*Q11 */
1832 : }
1833 1788 : if ( GT_32( L_abs( L_sub( wb_ener32_fx, hTdCngDec->wb_cng_ener_fx_32 ) ), 24576 ) ) /* 12.0f in Q11 */
1834 : {
1835 0 : allow_cn_step_fx = 1;
1836 0 : move16();
1837 : }
1838 :
1839 1788 : IF( EQ_16( allow_cn_step_fx, 1 ) )
1840 : {
1841 0 : hTdCngDec->wb_cng_ener_fx_32 = wb_ener32_fx;
1842 0 : move32(); /*Q11 */
1843 : }
1844 : ELSE
1845 : {
1846 1788 : tmp = L_sub( wb_ener32_fx, hTdCngDec->wb_cng_ener_fx_32 ); /*Q11 */
1847 1788 : tmp = Mpy_32_16_1( tmp, 29491 ); /*Q11 */
1848 1788 : hTdCngDec->wb_cng_ener_fx_32 = L_add( hTdCngDec->wb_cng_ener_fx_32, tmp ); /*Q11 */
1849 1788 : move32();
1850 : }
1851 1788 : test();
1852 1788 : test();
1853 1788 : IF( EQ_32( st->core_brate, SID_2k40 ) && EQ_16( sid_bw, 1 ) && EQ_16( st->bfi, 0 ) )
1854 : {
1855 324 : hTdCngDec->last_wb_cng_ener_fx_32 = hTdCngDec->wb_cng_ener_fx_32; /* Q11 */
1856 324 : move32();
1857 :
1858 324 : if ( !st->first_CNG )
1859 : {
1860 19 : hTdCngDec->shb_cng_ener_fx_32 = hTdCngDec->last_shb_cng_ener_fx_32; /* Q11 */
1861 19 : move32();
1862 : }
1863 : }
1864 :
1865 1788 : gain_fx = L_sub( hTdCngDec->wb_cng_ener_fx_32, hTdCngDec->last_wb_cng_ener_fx_32 ); /*Q11 */
1866 1788 : if ( GT_32( gain_fx, 30720 ) )
1867 : {
1868 0 : gain_fx = 30720;
1869 0 : move32();
1870 : }
1871 1788 : step_fx = L_sub( L_add( gain_fx, hTdCngDec->last_shb_cng_ener_fx_32 ), hTdCngDec->shb_cng_ener_fx_32 ); /*Q11 */
1872 1788 : test();
1873 1788 : IF( EQ_16( allow_cn_step_fx, 1 ) || GT_32( st->last_core_brate, SID_2k40 ) )
1874 : {
1875 151 : hTdCngDec->shb_cng_ener_fx_32 = L_add( hTdCngDec->shb_cng_ener_fx_32, step_fx ); /* Q11 */
1876 151 : move32();
1877 : }
1878 : ELSE
1879 : {
1880 1637 : hTdCngDec->shb_cng_ener_fx_32 = L_add( hTdCngDec->shb_cng_ener_fx_32, L_shr( step_fx, 2 ) ); /*Q11 */
1881 1637 : move32();
1882 : }
1883 : /* generate white noise excitation */
1884 573948 : FOR( i = 0; i < L_FRAME16k; i++ )
1885 : {
1886 572160 : excTmp_fx[i] = shr_r( Random( &hTdCngDec->swb_cng_seed ), 8 );
1887 572160 : move16(); /*Q-8*/
1888 : }
1889 :
1890 : /* synthesis filtering */
1891 1788 : Syn_filt_s( 0, shb_lpcCNG_fx, LPC_SHB_ORDER, excTmp_fx, excSHB_fx, L_FRAME16k, hBWE_TD->state_lpc_syn_fx, 1 );
1892 :
1893 :
1894 : /* synthesis signal gain shaping */
1895 1788 : L_tmp = 0;
1896 1788 : move32();
1897 573948 : FOR( i = 0; i < L_FRAME16k; i++ )
1898 : {
1899 572160 : L_tmp = L_add( L_tmp, Mpy_32_16_1( L_mult0( excSHB_fx[i], excSHB_fx[i] ), 102 ) ); /*Q-16*/
1900 : }
1901 1788 : q = norm_l( L_tmp );
1902 1788 : L_tmp = L_shl( L_tmp, q );
1903 1788 : q = sub( q, 32 );
1904 1788 : ener_excSHB_fx = round_fx( L_tmp ); /*Qq */
1905 :
1906 1788 : IF( EQ_16( st->last_vad_fx, 1 ) )
1907 : {
1908 151 : hTdCngDec->trans_cnt_fx = 0;
1909 151 : move16();
1910 151 : test();
1911 151 : if ( GT_16( hTdCngDec->burst_cnt_fx, 3 ) && NE_16( st->last_core, HQ_CORE ) )
1912 : {
1913 40 : hTdCngDec->trans_cnt_fx = 5;
1914 40 : move16();
1915 : }
1916 : }
1917 :
1918 1788 : ener_fx = hTdCngDec->shb_cng_ener_fx_32;
1919 1788 : move32(); /*Q11 */
1920 1788 : IF( GT_16( st->hTdCngDec->trans_cnt_fx, 0 ) )
1921 : {
1922 85 : i = extract_l( L_mult0( hTdCngDec->trans_cnt_fx, 17 ) ); /*Q0 */
1923 85 : ener_fx = L_add( hTdCngDec->shb_cng_ener_fx_32, Mpy_32_16_1( L_sub( hTdCngDec->last_shb_ener_fx_32, hTdCngDec->shb_cng_ener_fx_32 ), sin_table256_fx[i] ) ); /*Q11 */
1924 85 : hTdCngDec->trans_cnt_fx = sub( hTdCngDec->trans_cnt_fx, 1 );
1925 85 : move16();
1926 : }
1927 :
1928 1788 : tmp = L_shr( Mpy_32_16_1( ener_fx, 3277 ), 3 ); /*Q8 */
1929 1788 : IF( GT_32( tmp, 32767 ) )
1930 0 : abort();
1931 : Word16 tmp_16;
1932 1788 : tmp_16 = (Word16) tmp;
1933 1788 : move16();
1934 1788 : L_tmp = L_mult( 27213, tmp_16 ); /*Q22, 27213=3.321928 in Q13 */
1935 1788 : L_tmp = L_shr( L_tmp, 6 ); /*Q16 */
1936 1788 : L_tmp = L_add( L_tmp, L_shl( 10, 16 ) );
1937 1788 : if ( ( L_tmp < 0 ) )
1938 : {
1939 36 : L_tmp = 0;
1940 36 : move32();
1941 : }
1942 1788 : fra = L_Extract_lc( L_tmp, &exp );
1943 1788 : L_tmp = L_shr( Pow2( exp, fra ), 5 ); /*Q5 */
1944 1788 : if ( !L_tmp )
1945 : {
1946 40 : L_tmp = 1;
1947 40 : move32(); /*Q5 */
1948 : }
1949 1788 : exp = norm_l( L_tmp );
1950 1788 : L_tmp = L_shl( L_tmp, exp ); /*Q31*/
1951 1788 : tmp_16 = extract_h( L_tmp ); /*Q15*/
1952 1788 : exp = sub( exp, 16 );
1953 1788 : exp1 = norm_s( ener_excSHB_fx );
1954 1788 : fra = shl( ener_excSHB_fx, exp1 ); /*Q15*/
1955 :
1956 1788 : IF( GT_16( fra, tmp_16 ) )
1957 : {
1958 758 : fra = shr( fra, 1 ); /*Q15*/
1959 758 : exp1 = sub( exp1, 1 );
1960 : }
1961 1788 : tmp_16 = div_s( fra, tmp_16 ); /*Q15*/
1962 :
1963 1788 : L_tmp = L_deposit_h( tmp_16 ); /*Q31 */
1964 1788 : tmp_16 = sub( add( 5, exp ), add( q, exp1 ) );
1965 1788 : L_gain_fx = Isqrt_lc( L_tmp, &tmp_16 ); /*Q31-Qtmp */
1966 1788 : hTdCngDec->shb_cng_gain_fx_32 = ener_fx;
1967 1788 : move32();
1968 573948 : FOR( i = 0; i < L_FRAME16k; i++ )
1969 : {
1970 572160 : shb_syn16k_fx[i] = extract_l( L_shr( Mpy_32_16_1( L_gain_fx, excSHB_fx[i] ), sub( 5, tmp_16 ) ) ); /*Q3 = 31-Qtmp-8-15-5+Qtmp */
1971 572160 : move16();
1972 : }
1973 :
1974 1788 : test();
1975 1788 : IF( EQ_16( st->last_extl, SWB_TBE ) || EQ_16( st->last_extl, FB_TBE ) )
1976 : {
1977 : /* rescale the Hilbert memories to Q0 */
1978 528 : FOR( i = 0; i < HILBERT_MEM_SIZE; i++ )
1979 : {
1980 504 : hBWE_TD->genSHBsynth_Hilbert_Mem_fx[i] = L_shr( hBWE_TD->genSHBsynth_Hilbert_Mem_fx[i], hBWE_TD->prev_Q_bwe_syn2 ); /* hBWE_TD->prev_Q_bwe_syn2 */
1981 504 : move32();
1982 : }
1983 :
1984 168 : FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ )
1985 : {
1986 144 : hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx[i] = shr( hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx[i], hBWE_TD->prev_Q_bwe_syn2 ); /* hBWE_TD->prev_Q_bwe_syn2 */
1987 144 : move16();
1988 : }
1989 : }
1990 1788 : GenSHBSynth_fx( shb_syn16k_fx, shb_synth_fx, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, st->L_frame, &( hBWE_TD->syn_dm_phase ) );
1991 :
1992 1788 : IF( EQ_32( st->output_Fs, 48000 ) )
1993 : {
1994 970 : interpolate_3_over_2_allpass_fx( shb_synth_fx, L_FRAME32k, shb_synth_fx, hTdCngDec->interpol_3_2_cng_dec_fx, allpass_poles_3_ov_2 );
1995 : }
1996 :
1997 1788 : Scale_sig( shb_synth_fx, L_FRAME48k, -3 ); /* Qx - 3 */
1998 :
1999 1788 : ResetSHBbuffer_Dec_fx( st->hBWE_TD, st->extl );
2000 :
2001 1788 : return;
2002 : }
2003 :
2004 : /*-------------------------------------------------------------------*
2005 : * td_cng_dec_init_fx()
2006 : *
2007 : *
2008 : *-------------------------------------------------------------------*/
2009 :
2010 1340 : void td_cng_dec_init_fx(
2011 : DEC_CORE_HANDLE st /* i/o: decoder state structure */
2012 : )
2013 : {
2014 : Word16 i;
2015 : TD_CNG_DEC_HANDLE hTdCngDec;
2016 :
2017 1340 : hTdCngDec = st->hTdCngDec;
2018 :
2019 1340 : hTdCngDec->cng_seed = RANDOM_INITSEED;
2020 1340 : move16();
2021 1340 : hTdCngDec->cng_ener_seed = RANDOM_INITSEED;
2022 1340 : move16();
2023 1340 : hTdCngDec->cng_ener_seed1 = RANDOM_INITSEED;
2024 1340 : move16();
2025 1340 : hTdCngDec->old_enr_index = -1;
2026 1340 : move16();
2027 1340 : hTdCngDec->Enew_fx = 0;
2028 1340 : move32();
2029 1340 : Copy( st->lsp_old_fx, st->lspCNG_fx, M ); // Q(15)
2030 1340 : hTdCngDec->last_allow_cn_step = 0;
2031 1340 : move16();
2032 1340 : hTdCngDec->shb_cng_ener_fx = -1541; // Q8
2033 1340 : move16();
2034 1340 : hTdCngDec->shb_cng_ener_fx_32 = -12329; // -6.02 in Q(11)
2035 1340 : move32();
2036 1340 : IF( st->element_mode != EVS_MONO )
2037 : {
2038 1337 : set16_fx( hTdCngDec->shb_lpcCNG_fx, 0, LPC_SHB_ORDER + 1 );
2039 1337 : hTdCngDec->shb_lpcCNG_fx[0] = 32767; // 1 in Q(15)
2040 1337 : move16();
2041 1337 : hTdCngDec->shb_cng_gain_fx_32 = -167936; //-82.0 in Q(11) /* a dB value approximately corresponding to shb index 0(used as index -15) */
2042 1337 : move32();
2043 : }
2044 :
2045 1340 : hTdCngDec->wb_cng_ener_fx = -1541; // Q8
2046 1340 : move16();
2047 1340 : hTdCngDec->wb_cng_ener_fx_32 = -12329; // Q(11)
2048 1340 : move32();
2049 1340 : hTdCngDec->last_wb_cng_ener_fx = -1541; // Q8
2050 1340 : move16();
2051 1340 : hTdCngDec->last_wb_cng_ener_fx_32 = -12329; // Q(11)
2052 1340 : move32();
2053 1340 : hTdCngDec->last_shb_cng_ener_fx = -1541; // Q8
2054 1340 : move16();
2055 1340 : hTdCngDec->last_shb_cng_ener_fx_32 = -12329; // Q(11)
2056 1340 : move32();
2057 1340 : hTdCngDec->swb_cng_seed = RANDOM_INITSEED;
2058 1340 : move16();
2059 1340 : hTdCngDec->ho_hist_ptr = -1;
2060 1340 : move16();
2061 1340 : hTdCngDec->ho_sid_bw = 0;
2062 1340 : move16();
2063 1340 : set16_fx( hTdCngDec->ho_lsp_hist_fx, 0, HO_HIST_SIZE * M );
2064 1340 : set32_fx( hTdCngDec->ho_ener_hist_fx, 0, HO_HIST_SIZE );
2065 1340 : set32_fx( hTdCngDec->ho_env_hist_fx, 0, HO_HIST_SIZE * NUM_ENV_CNG );
2066 1340 : hTdCngDec->ho_hist_size = 0;
2067 1340 : move16();
2068 1340 : hTdCngDec->act_cnt = 0;
2069 1340 : move16();
2070 1340 : hTdCngDec->ho_circ_ptr = -1;
2071 1340 : move16();
2072 1340 : set16_fx( hTdCngDec->ho_lsp_circ_fx, 0, HO_HIST_SIZE * M );
2073 1340 : set32_fx( hTdCngDec->ho_ener_circ_fx, 0, HO_HIST_SIZE );
2074 1340 : set32_fx( hTdCngDec->ho_env_circ_fx, 0, HO_HIST_SIZE * NUM_ENV_CNG );
2075 1340 : hTdCngDec->ho_circ_size = 0;
2076 1340 : move16();
2077 :
2078 1340 : set16_fx( hTdCngDec->ho_16k_lsp, 0, HO_HIST_SIZE );
2079 1340 : st->CNG_mode = -1;
2080 1340 : move16();
2081 1340 : hTdCngDec->act_cnt2 = 0;
2082 1340 : move16();
2083 1340 : hTdCngDec->num_ho = 0;
2084 1340 : move16();
2085 1340 : set32_fx( hTdCngDec->lp_env_fx, 0, NUM_ENV_CNG );
2086 1340 : set16_fx( hTdCngDec->exc_mem_fx, 0, 24 );
2087 1340 : set16_fx( hTdCngDec->exc_mem1_fx, 0, 30 );
2088 1340 : set32_fx( hTdCngDec->old_env_fx, 0, NUM_ENV_CNG );
2089 :
2090 14740 : FOR( i = 0; i < LPC_SHB_ORDER; i++ )
2091 : {
2092 13400 : IF( st->element_mode != EVS_MONO )
2093 : {
2094 13370 : hTdCngDec->lsp_shb_prev_fx[i] = ivas_lsp_shb_prev_tbl_fx[i]; /* Q14 */
2095 13370 : move16();
2096 : }
2097 : ELSE
2098 : {
2099 30 : hTdCngDec->lsp_shb_prev_fx[i] = lsp_shb_prev_tbl_fx[i]; /* Q14 */
2100 30 : move16();
2101 : }
2102 13400 : hTdCngDec->lsp_shb_prev_prev_fx[i] = hTdCngDec->lsp_shb_prev_fx[i]; /* Q14 */
2103 13400 : move16();
2104 : }
2105 :
2106 1340 : hTdCngDec->shb_dtx_count_fx = 0;
2107 1340 : move16();
2108 1340 : hTdCngDec->trans_cnt_fx = 0;
2109 1340 : move16();
2110 1340 : hTdCngDec->burst_cnt_fx = 0;
2111 1340 : move16();
2112 :
2113 1340 : hTdCngDec->last_shb_ener_fx = 0; // Q8
2114 1340 : move16();
2115 1340 : hTdCngDec->last_shb_ener_fx_32 = 2; // 0.001 in Q11
2116 1340 : move32();
2117 :
2118 1340 : set16_fx( hTdCngDec->interpol_3_2_cng_dec_fx, 0, INTERP_3_2_MEM_LEN );
2119 :
2120 1340 : return;
2121 : }
|