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