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