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 2438 : 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 2438 : DTX_ENC_HANDLE hDtxEnc = st_fx->hDtxEnc;
1230 2438 : TD_CNG_ENC_HANDLE hTdCngEnc = st_fx->hTdCngEnc;
1231 2438 : 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 2438 : Flag Overflow = 0;
1238 2438 : move32();
1239 : #endif
1240 2438 : step_inv = 0;
1241 2438 : move16();
1242 2438 : maxl = 0;
1243 2438 : move16();
1244 2438 : num_bits = 0;
1245 2438 : move16();
1246 2438 : step = 0;
1247 2438 : move16();
1248 2438 : m = 0;
1249 2438 : move16();
1250 2438 : att = 1;
1251 2438 : move16();
1252 2438 : max_idx1[0] = 0;
1253 2438 : max_idx1[1] = 0;
1254 2438 : move16();
1255 2438 : move16();
1256 2438 : enr1 = 0;
1257 2438 : move32();
1258 2438 : force_cn_step = 0;
1259 2438 : move16();
1260 2438 : st_lp_sp_enr = hTdCngEnc->lp_sp_enr_fx;
1261 2438 : move16();
1262 : /* Temp variables for floating point functions */
1263 :
1264 2438 : lp_ener_thr_scale = 8; /* 4.0f*/ /* Q2 */
1265 2438 : move16();
1266 2438 : if ( st_fx->element_mode != EVS_MONO )
1267 : {
1268 2438 : lp_ener_thr_scale = 7; /* 3.5f;*/ /* Q2 */
1269 2438 : move16();
1270 : }
1271 :
1272 2438 : w_temp = 1;
1273 2438 : move64();
1274 :
1275 725062 : FOR( j = 0; j < st_fx->L_frame; j++ )
1276 : {
1277 722624 : w_temp = W_mac0_16_16( w_temp, speech[j], speech[j] );
1278 : }
1279 2438 : exp = W_norm( w_temp );
1280 :
1281 2438 : inv_frame_len = 0;
1282 2438 : move32();
1283 :
1284 2438 : 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 1539 : case L_FRAME16k:
1307 1539 : inv_frame_len = ONE_BY_L_FRAME16k_Q31;
1308 1539 : move16();
1309 1539 : 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 2438 : L_ener = W_extract_h( W_shl( w_temp, exp ) ); /* Q = 2*Q_new+exp-32 */
1322 2438 : L_ener = Mpy_32_32( L_ener, inv_frame_len ); /* Q = 2*Q_new+exp-32 */
1323 2438 : L_ener = L_shl( L_ener, sub( 33, exp ) ); /* Q = 2*Q_new+1 */
1324 :
1325 2438 : hi = norm_l( L_ener );
1326 2438 : lo = Log2_norm_lc( L_shl( L_ener, hi ) );
1327 2438 : hi = sub( 29, hi ); /* log2 exp in Q2*Q_new */
1328 2438 : hi = sub( hi, shl( Q_new, 1 ) ); /* Q0 */
1329 2438 : L_tmp = L_Comp( hi, lo ); /* Q16 */
1330 2438 : sp_enr = round_fx( L_shl( L_tmp, 8 ) ); /* Q8 (16+8-16) */
1331 :
1332 2438 : if ( sp_enr < 0 )
1333 : {
1334 156 : sp_enr = 0;
1335 156 : move16();
1336 : }
1337 2438 : test();
1338 2438 : IF( hDtxEnc->first_CNG == 0 || hTdCngEnc->old_enr_index < 0 )
1339 : {
1340 28 : hTdCngEnc->lp_sp_enr_fx = sp_enr;
1341 28 : move16(); /* Q8 */
1342 : }
1343 : ELSE
1344 : {
1345 2410 : test();
1346 2410 : test();
1347 2410 : test();
1348 2410 : test();
1349 2410 : test();
1350 2410 : IF( GT_32( st_fx->last_core_brate, SID_2k40 ) && ( EQ_16( st_fx->last_core, HQ_CORE ) || st_fx->hTdCngEnc->burst_ho_cnt > 0 ) && LT_16( hTdCngEnc->lp_sp_enr_fx, 1536 /*6.0f in Q8*/ ) &&
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 2410 : hTdCngEnc->lp_sp_enr_fx = round_fx( L_mac( L_mult( 29491 /* 0.9, Q15 */, hTdCngEnc->lp_sp_enr_fx ), 3277 /* 0.1, Q15 */, sp_enr ) ); /* Q8 (8+15+1-16) */
1361 2410 : move16();
1362 : }
1363 : }
1364 : /* update the pointer to circular buffer of old LSP vectors */
1365 2438 : hTdCngEnc->cng_hist_ptr = add( hTdCngEnc->cng_hist_ptr, 1 );
1366 2438 : move16();
1367 2438 : 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 2438 : 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 2438 : test();
1381 2438 : test();
1382 2438 : IF( ( EQ_32( st_fx->core_brate, SID_2k40 ) || EQ_32( st_fx->core_brate, SID_1k75 ) ) && GE_16( hDtxEnc->cng_cnt, sub( hDtxEnc->cng_hist_size, 1 ) ) )
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 617 : max_val[1] = max_val[0];
1420 617 : move32();
1421 617 : max_idx[1] = max_idx[0];
1422 617 : move16();
1423 617 : max_val[0] = C[i];
1424 617 : move32();
1425 617 : max_idx[0] = i;
1426 617 : move16();
1427 : }
1428 1239 : ELSE IF( GT_32( C[i], max_val[1] ) )
1429 : {
1430 387 : max_val[1] = C[i];
1431 387 : move32();
1432 387 : max_idx[1] = i;
1433 387 : 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 2438 : *allow_cn_step = 0;
1463 2438 : move16();
1464 2438 : test();
1465 2438 : test();
1466 2438 : test();
1467 2438 : test();
1468 2438 : test();
1469 2438 : test();
1470 2438 : 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 2438 : IF( hDtxEnc->first_CNG == 0 )
1484 : {
1485 28 : 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 28 : IF( st_fx->element_mode != EVS_MONO )
1489 : {
1490 476 : FOR( i = 0; i < M; i++ )
1491 : {
1492 : /*lsp_new[i] = 0.5f * (lsp_mid[i] + lsp_new[i]);*/
1493 448 : lsp_new[i] = mac_r( L_mult( lsp_mid[i], 16384 /*.5f Q15*/ ), lsp_new[i], 16384 /*.5f Q15*/ );
1494 448 : move16();
1495 : }
1496 : }
1497 : }
1498 :
1499 :
1500 2438 : test();
1501 2438 : IF( EQ_32( st_fx->core_brate, SID_2k40 ) || EQ_32( st_fx->core_brate, SID_1k75 ) )
1502 : {
1503 : /* LSF quantization */
1504 447 : 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 447 : 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 447 : test();
1514 447 : test();
1515 447 : 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 1991 : Copy( st_fx->lsp_old_fx, lsp_new, M );
1525 1991 : Copy( st_fx->lsf_old_fx, lsf_new, M );
1526 : }
1527 :
1528 : /*---------------------------------------------------------------------*
1529 : * CNG spectral envelope update
1530 : * Find A(z) coefficients
1531 : *---------------------------------------------------------------------*/
1532 2438 : test();
1533 2438 : test();
1534 2438 : IF( ( st_fx->last_core_brate == FRAME_NO_DATA ) || EQ_32( st_fx->last_core_brate, SID_1k75 ) || EQ_32( st_fx->last_core_brate, SID_2k40 ) )
1535 : {
1536 : /* Reset hangover counter if not first SID period */
1537 2223 : 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 2223 : test();
1544 2223 : IF( LT_16( hTdCngEnc->num_ho, 3 ) || LT_32( Mult_32_16( hTdCngEnc->Enew_fx, 21845 /*1/1.5f, Q15*/ ), hTdCngEnc->lp_ener_fx ) )
1545 : {
1546 37757 : FOR( i = 0; i < M; i++ )
1547 : {
1548 : /* AR low-pass filter */
1549 35536 : hDtxEnc->lspCNG_fx[i] = mac_r( L_mult( CNG_ISF_FACT_FX, hDtxEnc->lspCNG_fx[i] ), 32768 /*1f Q15*/ - CNG_ISF_FACT_FX, lsp_new[i] );
1550 35536 : move16(); /* Q15 (15+15+1-16) */
1551 : }
1552 : }
1553 : }
1554 : ELSE
1555 : {
1556 : /* Update CNG_mode if allowed */
1557 215 : test();
1558 215 : test();
1559 215 : test();
1560 215 : test();
1561 215 : IF( ( st_fx->element_mode == EVS_MONO ) && ( ( st_fx->Opt_AMR_WB || EQ_16( st_fx->bwidth, WB ) ) && ( !hDtxEnc->first_CNG || GE_16( hTdCngEnc->act_cnt2, MIN_ACT_CNG_UPD ) ) ) )
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 215 : hTdCngEnc->burst_ho_cnt = s_min( hTdCngEnc->burst_ho_cnt, hTdCngEnc->ho_circ_size );
1577 215 : move16();
1578 215 : hTdCngEnc->act_cnt = 0;
1579 215 : move16();
1580 215 : s_ptr = add( sub( hTdCngEnc->ho_circ_ptr, hTdCngEnc->burst_ho_cnt ), 1 );
1581 :
1582 215 : if ( s_ptr < 0 )
1583 : {
1584 27 : s_ptr = add( s_ptr, hTdCngEnc->ho_circ_size );
1585 : }
1586 :
1587 478 : FOR( ll = hTdCngEnc->burst_ho_cnt; ll > 0; ll-- )
1588 : {
1589 263 : hTdCngEnc->ho_hist_ptr = add( hTdCngEnc->ho_hist_ptr, 1 );
1590 263 : move16();
1591 263 : 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 263 : test();
1599 263 : test();
1600 263 : 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 263 : 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 62 : 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 263 : Copy( &( hTdCngEnc->ho_lsp_circ_fx[s_ptr * M] ), &( hTdCngEnc->ho_lsp_hist_fx[hTdCngEnc->ho_hist_ptr * M] ), M );
1612 263 : Copy32( &( hTdCngEnc->ho_ener_circ_fx[s_ptr] ), &( hTdCngEnc->ho_ener_hist_fx[hTdCngEnc->ho_hist_ptr] ), 1 );
1613 263 : hTdCngEnc->ho_sid_bw = L_shl( L_and( hTdCngEnc->ho_sid_bw, (Word32) 0x3fffffffL ), 1 );
1614 263 : move32();
1615 263 : Copy32( &( hTdCngEnc->ho_env_circ_fx[s_ptr * NUM_ENV_CNG] ), &( hTdCngEnc->ho_env_hist_fx[hTdCngEnc->ho_hist_ptr * NUM_ENV_CNG] ), NUM_ENV_CNG );
1616 :
1617 263 : hTdCngEnc->ho_hist_size = add( hTdCngEnc->ho_hist_size, 1 );
1618 263 : move16();
1619 263 : 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 263 : s_ptr = add( s_ptr, 1 );
1626 :
1627 263 : if ( EQ_16( s_ptr, hTdCngEnc->ho_circ_size ) )
1628 : {
1629 30 : s_ptr = 0;
1630 30 : move16();
1631 : }
1632 : }
1633 :
1634 215 : 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 53 : 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 53 : test();
1640 53 : test();
1641 53 : IF( ( hDtxEnc->first_CNG > 0 || ( st_fx->element_mode == EVS_MONO ) ) && w_temp > 0 )
1642 : {
1643 2 : *allow_cn_step = s_or( *allow_cn_step, 1 );
1644 2 : move16();
1645 : }
1646 : }
1647 215 : test();
1648 215 : IF( *allow_cn_step == 0 && hTdCngEnc->ho_hist_size > 0 )
1649 : {
1650 : /* Use average of energies below last energy */
1651 177 : ptr = hTdCngEnc->ho_hist_ptr;
1652 177 : move16();
1653 177 : Copy( &( hTdCngEnc->ho_lsp_hist_fx[ptr * M] ), tmp, M );
1654 177 : m1 = 0;
1655 177 : move16();
1656 177 : IF( L_and( hTdCngEnc->ho_sid_bw, 1 ) == 0 )
1657 : {
1658 51 : Copy32( &hTdCngEnc->ho_env_hist_fx[ptr * NUM_ENV_CNG], tmp_env, NUM_ENV_CNG );
1659 51 : m1 = 1;
1660 51 : move16();
1661 : }
1662 177 : L_ener = Mult_32_16( hTdCngEnc->ho_ener_hist_fx[ptr], W_DTX_HO_FX[0] ); /* Q6+15-15->Q6 */
1663 :
1664 177 : weights = W_DTX_HO_FX[0]; /* Q15 */
1665 177 : move16();
1666 177 : m = 1;
1667 177 : move16();
1668 839 : FOR( k = 1; k < hTdCngEnc->ho_hist_size; k++ )
1669 : {
1670 662 : ptr = sub( ptr, 1 );
1671 662 : if ( ptr < 0 )
1672 : {
1673 22 : ptr = HO_HIST_SIZE - 1;
1674 22 : move16();
1675 : }
1676 :
1677 662 : test();
1678 662 : 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 306 : L_tmp1 = Mult_32_16( hTdCngEnc->ho_ener_hist_fx[ptr], W_DTX_HO_FX[k] ); /* Q6+15-15->Q6 */
1683 306 : L_ener = L_add( L_ener, L_tmp1 ); /* Q6 */
1684 :
1685 : /*weights += W_DTX_HO[k]; */
1686 306 : weights = add( weights, W_DTX_HO_FX[k] ); /* Q15 */
1687 :
1688 306 : Copy( &hTdCngEnc->ho_lsp_hist_fx[ptr * M], &tmp[m * M], M );
1689 306 : IF( L_and( hTdCngEnc->ho_sid_bw, L_shl( 1, k ) ) == 0 )
1690 : {
1691 26 : Copy32( &hTdCngEnc->ho_env_hist_fx[ptr * NUM_ENV_CNG], &tmp_env[m1 * NUM_ENV_CNG], NUM_ENV_CNG );
1692 26 : m1 = add( m1, 1 );
1693 : }
1694 306 : m = add( m, 1 );
1695 : }
1696 : }
1697 :
1698 : /*enr /= weights; */
1699 177 : exp = norm_s( weights );
1700 177 : tmp1 = div_s( shl( 1, sub( 14, exp ) ), weights ); /* Q(15+14-exp-15) */
1701 177 : L_tmp1 = Mult_32_16( L_ener, tmp1 ); /* Q(14-exp+6-15)->Q(5-exp) */
1702 177 : L_ener = L_shl( L_tmp1, add( exp, 1 ) ); /* Q6 */
1703 :
1704 177 : hTdCngEnc->lp_ener_fx = L_ener;
1705 177 : move32(); /* Q6 */
1706 :
1707 177 : set32_fx( max_val, 0, 2 );
1708 177 : set16_fx( max_idx, 0, 2 );
1709 :
1710 660 : FOR( i = 0; i < m; i++ )
1711 : {
1712 483 : IF( EQ_16( st_fx->L_frame, L_FRAME ) )
1713 : {
1714 225 : lsp2lsf_fx( &tmp[i * M], lsf_tmp, M, INT_FS_FX );
1715 225 : ftmp_fx = 964; /*(6400/(M+1))X2.56*/
1716 225 : move16(); /*QX2.56 */
1717 225 : tmpv = sub( 16384, add( lsf_tmp[M - 1], ftmp_fx ) ); /*QX2.56 */
1718 225 : L_tmp = L_mult0( tmpv, tmpv ); /*QX6.5536 */
1719 : }
1720 : ELSE
1721 : {
1722 258 : lsp2lsf_fx( &tmp[i * M], lsf_tmp, M, INT_FS_16k );
1723 258 : ftmp_fx = 1205; /*(8000/(M+1))X2.56*/
1724 258 : move16(); /*QX2.56 */
1725 258 : tmpv = sub( 20480, add( lsf_tmp[M - 1], ftmp_fx ) ); /*QX2.56 */
1726 258 : L_tmp = L_mult0( tmpv, tmpv ); /*QX6.5536 */
1727 : }
1728 :
1729 483 : tmpv = sub( lsf_tmp[0], ftmp_fx ); /*QX2.56 */
1730 483 : L_tmp = L_mac0( L_tmp, tmpv, tmpv ); /*QX6.5536 */
1731 7728 : FOR( j = 0; j < M - 1; j++ )
1732 : {
1733 7245 : tmpv = sub( sub( lsf_tmp[j + 1], lsf_tmp[j] ), ftmp_fx ); /*QX2.56 */
1734 7245 : L_tmp = L_mac0( L_tmp, tmpv, tmpv ); /*QX6.5536 */
1735 : }
1736 :
1737 483 : C[i] = Mpy_32_16_1( L_tmp, 1928 );
1738 483 : move32(); /*QX6.5536 */
1739 :
1740 483 : IF( GT_32( C[i], max_val[0] ) )
1741 : {
1742 299 : max_val[1] = max_val[0];
1743 299 : move32();
1744 299 : max_idx[1] = max_idx[0];
1745 299 : move16();
1746 299 : max_val[0] = C[i];
1747 299 : move32();
1748 299 : max_idx[0] = i;
1749 299 : move16();
1750 : }
1751 184 : ELSE IF( GT_32( C[i], max_val[1] ) )
1752 : {
1753 98 : max_val[1] = C[i];
1754 98 : move32();
1755 98 : max_idx[1] = i;
1756 98 : move16();
1757 : }
1758 : }
1759 :
1760 177 : IF( EQ_16( m, 1 ) )
1761 : {
1762 62 : Copy( tmp, lsp_tmp, M );
1763 : }
1764 115 : ELSE IF( LT_16( m, 4 ) )
1765 : {
1766 1122 : FOR( i = 0; i < M; i++ )
1767 : {
1768 1056 : L_tmp = L_deposit_l( 0 );
1769 3664 : FOR( j = 0; j < m; j++ )
1770 : {
1771 2608 : L_tmp = L_add( L_tmp, L_deposit_l( tmp[j * M + i] ) );
1772 : }
1773 :
1774 1056 : L_tmp = L_sub( L_tmp, L_deposit_l( tmp[max_idx[0] * M + i] ) );
1775 1056 : tmpv = div_s( 1, sub( m, 1 ) ); /*Q15 */
1776 1056 : L_tmp = Mpy_32_16_1( L_tmp, tmpv ); /*Q15 */
1777 1056 : lsp_tmp[i] = extract_l( L_tmp ); /*Q15 */
1778 1056 : move16();
1779 : }
1780 : }
1781 : ELSE
1782 : {
1783 833 : FOR( i = 0; i < M; i++ )
1784 : {
1785 784 : L_tmp = L_deposit_l( 0 );
1786 4912 : FOR( j = 0; j < m; j++ )
1787 : {
1788 4128 : L_tmp = L_add( L_tmp, L_deposit_l( tmp[j * M + i] ) );
1789 : }
1790 :
1791 784 : L_tmp = L_sub( L_tmp, L_add( L_deposit_l( tmp[max_idx[0] * M + i] ), L_deposit_l( tmp[max_idx[1] * M + i] ) ) ); /*Q15 */
1792 784 : tmpv = div_s( 1, sub( m, 2 ) ); /*Q15 */ /*Q15 */
1793 784 : L_tmp = Mpy_32_16_1( L_tmp, tmpv ); /*Q15 */ /*Q15 */
1794 784 : lsp_tmp[i] = extract_l( L_tmp ); /*Q15 */ /*Q15 */
1795 784 : move16();
1796 : }
1797 : }
1798 :
1799 177 : dist = 0; /*Q15 */
1800 177 : move32();
1801 177 : max_dev = 0; /*Q15 */
1802 177 : move32();
1803 3009 : FOR( i = 0; i < M; i++ )
1804 : {
1805 2832 : dev = L_abs( L_sub( L_deposit_l( lsp_tmp[i] ), L_deposit_l( lsp_new[i] ) ) ); /*Q15 */
1806 2832 : dist = L_add( dist, dev ); /*Q15 */
1807 2832 : if ( GT_32( dev, max_dev ) )
1808 : {
1809 903 : max_dev = dev;
1810 903 : move32();
1811 : }
1812 : }
1813 :
1814 177 : test();
1815 177 : IF( GT_32( dist, 13107 ) || GT_32( max_dev, 3277 ) )
1816 : {
1817 187 : FOR( i = 0; i < M; i++ )
1818 : {
1819 176 : hDtxEnc->lspCNG_fx[i] = lsp_tmp[i];
1820 176 : move16(); /*Q15 */
1821 : }
1822 : }
1823 : ELSE
1824 : {
1825 2822 : FOR( i = 0; i < M; i++ )
1826 : {
1827 : /* AR low-pass filter */
1828 2656 : hDtxEnc->lspCNG_fx[i] = add( mult_r( 26214 /*.8f Q15*/, lsp_tmp[i] ), mult_r( 6554 /*.2f Q15*/, lsp_new[i] ) ); /* Q15 */
1829 2656 : move16();
1830 : }
1831 : }
1832 177 : IF( m1 > 0 )
1833 : {
1834 1071 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
1835 : {
1836 1020 : L_tmp = L_deposit_l( 0 );
1837 2560 : FOR( j = 0; j < m1; j++ )
1838 : {
1839 : /* env[i] += tmp_env[j*NUM_ENV_CNG+i]; */
1840 1540 : 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 1020 : IF( EQ_16( m1, 1 ) )
1845 : {
1846 780 : L_tmp = L_sub_sat( L_tmp, L_add_sat( hTdCngEnc->lp_ener_fx, hTdCngEnc->lp_ener_fx ) );
1847 : }
1848 : ELSE
1849 : {
1850 240 : tmp1 = div_s( 1, m1 );
1851 240 : L_tmp = Mult_32_16( L_tmp, tmp1 );
1852 240 : L_tmp = L_sub_sat( L_tmp, L_add_sat( hTdCngEnc->lp_ener_fx, hTdCngEnc->lp_ener_fx ) );
1853 : }
1854 :
1855 1020 : env[i] = L_tmp; /* Q6*/
1856 1020 : move32();
1857 : }
1858 51 : Copy32( env, hTdCngEnc->lp_env_fx, NUM_ENV_CNG ); /* Q6 */
1859 : }
1860 : }
1861 : ELSE
1862 : {
1863 38 : Copy( lsp_new, hDtxEnc->lspCNG_fx, M ); /* use newly analyzed ISFs */ /* Q15 */
1864 : }
1865 : }
1866 2438 : 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 2438 : E_LPC_f_lsp_a_conversion( hDtxEnc->lspCNG_fx, Aq, M );
1873 2438 : exp = sub( Q14, norm_s( Aq[0] ) );
1874 2438 : Scale_sig( Aq, M + 1, sub( Q12, exp ) ); // Q12
1875 : }
1876 :
1877 2438 : tmp_loop = shr( st_fx->L_frame, 6 );
1878 11291 : FOR( i = 1; i < tmp_loop; i++ )
1879 : {
1880 8853 : 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 2438 : Residu3_fx( Aq, speech, res, st_fx->L_frame, 0 );
1889 2438 : Copy( res, res1, st_fx->L_frame ); /* Q_new */
1890 2438 : test();
1891 2438 : IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) )
1892 : {
1893 2438 : L_tmp1 = L_mult0( hTdCngEnc->CNG_att_fx, 26214 /* 1/20.0f in Q19 */ ); // Q26 (7 + 19)
1894 2438 : L_tmp1 = BASOP_Util_fPow( 1342177280 /*10 in Q27 */, 4, L_tmp1, 5, &exp );
1895 2438 : att = extract_h( L_shl( L_sub( L_tmp1, EPSILON_FX ), exp ) ); // Q15 // Subtracting by EPSILON_FX to avoid assertion when L_tmp1 value is 1073741824 and exp =1
1896 2438 : 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 2438 : Copy( res1, fft_io, st_fx->L_frame ); /* Q_new */
1930 :
1931 2438 : IF( EQ_16( st_fx->L_frame, L_FRAME16k ) )
1932 : {
1933 1539 : modify_Fs_fx( fft_io, L_FRAME16k, 16000, fft_io, 12800, hTdCngEnc->exc_mem2_fx, 0 );
1934 : }
1935 :
1936 2438 : fft_rel_fx( fft_io, L_FFT, LOG2_L_FFT );
1937 2438 : ptR = &fft_io[1];
1938 2438 : ptI = &fft_io[L_FFT - 1];
1939 51198 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
1940 : {
1941 : /* env[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */
1942 48760 : L_tmp = L_mult_o( *ptR, *ptR, &Overflow ); /* 2*Q_new+1 */
1943 48760 : L_tmp = L_add_o( L_tmp, L_mult_o( *ptI, *ptI, &Overflow ), &Overflow ); /* 2*Q_new+1 */
1944 48760 : L_tmp = L_add_o( L_tmp, L_tmp, &Overflow ); /* 2*Q_new+1 */
1945 48760 : L_tmp = Mult_32_16( L_tmp, 128 ); /* 2*Q_new+1 */
1946 48760 : tmp1 = add( add( Q_new, Q_new ), 1 );
1947 48760 : env[i] = L_shr( L_tmp, sub( tmp1, 6 ) );
1948 48760 : move32(); /* Q6 */
1949 48760 : ptR++;
1950 48760 : ptI--;
1951 : }
1952 :
1953 2438 : 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 2438 : w_temp = 1;
1958 2438 : move64();
1959 725062 : FOR( j = 0; j < st_fx->L_frame; j++ )
1960 : {
1961 722624 : w_temp = W_mac0_16_16( w_temp, res[j], res[j] );
1962 : }
1963 2438 : exp = W_norm( w_temp );
1964 :
1965 2438 : 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 1539 : case L_FRAME16k:
1988 1539 : inv_frame_len = ONE_BY_L_FRAME16k_Q31;
1989 1539 : move16();
1990 1539 : 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 2438 : L_ener = W_extract_h( W_shl( w_temp, exp ) ); /* Q = 2*Q_new+exp-32 */
2003 2438 : L_ener = Mpy_32_32( L_ener, inv_frame_len ); /* Q = 2*Q_new+exp-32 */
2004 2438 : 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 2438 : IF( L_ener == 0 )
2010 : {
2011 0 : enr = -850; /*log(0.1) base 2 in Q8*/
2012 0 : move16();
2013 : }
2014 : ELSE
2015 : {
2016 2438 : hi = norm_l( L_ener );
2017 2438 : lo = Log2_norm_lc( L_shl( L_ener, hi ) );
2018 2438 : hi = sub( 29, hi ); /* log2 exp in Q2*Q_new */
2019 2438 : hi = sub( hi, shl( Q_new, 1 ) ); /* Q0 */
2020 2438 : L_tmp = L_Comp( hi, lo ); /* Q16 */
2021 2438 : enr = round_fx( L_shl( L_tmp, 8 ) ); /* Q8 (16+8-16) */
2022 : }
2023 : /* update the circular buffer of old energies */
2024 2438 : hTdCngEnc->cng_ener_hist_fx[hTdCngEnc->cng_hist_ptr] = enr;
2025 2438 : move16(); /* Q8 */
2026 :
2027 : /*-----------------------------------------------------------------*
2028 : * Quantize residual signal energy (only in SID frame)
2029 : *-----------------------------------------------------------------*/
2030 2438 : test();
2031 2438 : IF( EQ_32( st_fx->core_brate, SID_2k40 ) || EQ_32( st_fx->core_brate, SID_1k75 ) )
2032 : {
2033 447 : 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 447 : test();
2093 447 : IF( EQ_16( st_fx->element_mode, IVAS_SCE ) || EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) )
2094 : {
2095 447 : 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 447 : IF( st_fx->Opt_AMR_WB == 0 )
2123 : {
2124 447 : step = STEP_SID_FX; // Q12
2125 447 : move16();
2126 447 : step_inv = ISTEP_SID_FX;
2127 447 : move16();
2128 447 : maxl = 127;
2129 447 : move16();
2130 447 : num_bits = 7;
2131 447 : 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 447 : enr_index = add( enr, 512 /* Q8(2.0) */ ); /* enr + 2.0 */
2147 447 : 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 447 : enr_index = s_min( enr_index, maxl );
2151 447 : enr_index = s_max( enr_index, 0 );
2152 :
2153 : /* allow only slow energy increase */
2154 447 : test();
2155 447 : IF( hTdCngEnc->old_enr_index >= 0 && GT_16( enr_index, add( hTdCngEnc->old_enr_index, MAX_DELTA ) ) )
2156 : {
2157 75 : 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 75 : enr_index = add( hTdCngEnc->old_enr_index, MAX_DELTA );
2165 : }
2166 : }
2167 447 : hTdCngEnc->old_enr_index = enr_index;
2168 447 : move16();
2169 :
2170 447 : push_indice( hBstr, IND_ENERGY, enr_index, num_bits );
2171 447 : 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 447 : L_tmp = L_mult( enr_index, step_inv ); /* Q16(0+15+1) */
2180 : /* substract by 2 not done to leave Energy in Q2 */
2181 447 : lo = L_Extract_lc( L_tmp, &hi );
2182 447 : hTdCngEnc->Enew_fx = Pow2( add( hi, 4 ), lo ); /* Q6 */
2183 447 : move32();
2184 447 : 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 447 : exp = norm_l( hTdCngEnc->Enew_fx );
2188 447 : L_tmp = L_shl( hTdCngEnc->Enew_fx, exp ); /*Q(exp+6) */
2189 447 : L_tmp = Mult_32_16( L_tmp, shl( st_fx->L_frame, 5 ) ); /* Q(exp+6+5-15=exp-4) */
2190 :
2191 447 : L_tmp = L_shr_sat( L_tmp, sub( exp, 10 ) ); /* Q6 */
2192 :
2193 447 : exp = norm_l( L_tmp );
2194 447 : fra = Log2_norm_lc( L_shl( L_tmp, exp ) );
2195 447 : exp = sub( sub( 30, exp ), 6 );
2196 447 : L_tmp = L_Comp( exp, fra );
2197 447 : enr1 = L_shr( L_tmp, 10 ); /* Q6 */
2198 :
2199 9387 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
2200 : {
2201 : /* env[i] -= 2 * st->Enew;*/
2202 8940 : L_tmp1 = L_add( env[i], 0 );
2203 8940 : L_tmp = L_add( hTdCngEnc->Enew_fx, hTdCngEnc->Enew_fx );
2204 8940 : L_tmp1 = L_sub( L_tmp1, L_tmp ); /*Q6*/
2205 :
2206 8940 : IF( L_tmp1 < 0 )
2207 : {
2208 7151 : L_tmp1 = L_deposit_l( 6 ); /* (0.1)Q6 */
2209 : }
2210 : /* env[i] = (float)log10( env[i] + 0.1f ) / (float)log10( 2.0f ); */
2211 8940 : exp = norm_l( L_tmp1 );
2212 8940 : fra = Log2_norm_lc( L_shl( L_tmp1, exp ) );
2213 8940 : exp = sub( sub( 30, exp ), 6 );
2214 8940 : L_tmp = L_Comp( exp, fra );
2215 8940 : L_tmp1 = L_shr( L_tmp, 10 ); /* Q6 */
2216 :
2217 8940 : L_tmp = L_shr( L_deposit_l( att ), 2 ); /* Q6 */
2218 8940 : L_tmp1 = L_sub( L_tmp1, L_tmp );
2219 :
2220 8940 : IF( L_tmp1 < 0 )
2221 : {
2222 8940 : L_tmp1 = L_deposit_l( 0 );
2223 : }
2224 :
2225 8940 : L_tmp1 = L_sub( enr1, L_tmp1 );
2226 :
2227 8940 : env[i] = L_tmp1;
2228 8940 : move32();
2229 : }
2230 :
2231 : /* codebook search */
2232 447 : min1 = 1310588928; /* 9999.0f Q17 */
2233 447 : move32();
2234 447 : min1_idx = 0;
2235 447 : move16();
2236 :
2237 29055 : FOR( i = 0; i < 64; i++ )
2238 : {
2239 28608 : d = L_deposit_l( 0 );
2240 600768 : 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 572160 : L_tmp = L_sub( env[j], L_deposit_l( CNG_details_codebook_fx[i][j] ) ); /* Q6 */
2244 572160 : exp = norm_l( L_tmp );
2245 572160 : L_tmp = L_shl( L_tmp, exp ); /*Q(exp+6)*/
2246 572160 : tmp1 = extract_h( L_tmp ); /*Q(exp+6-16)=exp-10*/
2247 572160 : L_tmp = L_mult_o( tmp1, tmp1, &Overflow ); /*Q(2*exp - 19)*/
2248 572160 : L_tmp = L_shr( L_tmp, sub( add( exp, exp ), 36 ) ); /* Q17 */
2249 572160 : d = L_add( d, L_tmp ); /* Q17 */
2250 : }
2251 :
2252 28608 : IF( LT_32( d, min1 ) )
2253 : {
2254 4085 : min1 = d;
2255 4085 : move32();
2256 4085 : min1_idx = i;
2257 4085 : move16();
2258 : }
2259 : }
2260 447 : push_indice( hBstr, IND_CNG_ENV1, min1_idx, 6 );
2261 : /* get quantized res_env_details */
2262 9387 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
2263 : {
2264 8940 : q_env[i] = L_deposit_l( CNG_details_codebook_fx[min1_idx][i] );
2265 8940 : move32();
2266 : }
2267 : }
2268 : /* Update hangover memory during CNG */
2269 447 : test();
2270 447 : 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 385 : hTdCngEnc->ho_hist_ptr = add( hTdCngEnc->ho_hist_ptr, 1 );
2274 385 : move16();
2275 385 : 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 385 : Copy( lsp_new, &( hTdCngEnc->ho_lsp_hist_fx[( hTdCngEnc->ho_hist_ptr ) * M] ), M );
2283 :
2284 : /* update the hangover energy buffer */
2285 385 : hTdCngEnc->ho_ener_hist_fx[hTdCngEnc->ho_hist_ptr] = hTdCngEnc->Enew_fx;
2286 385 : move32();
2287 385 : IF( EQ_32( st_fx->core_brate, SID_2k40 ) )
2288 : {
2289 8085 : 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 7700 : L_tmp = L_sub( enr1, q_env[i] ); /* Q6 */
2294 7700 : L_tmp = L_shl( L_tmp, 10 ); /* 16 */
2295 7700 : temp_lo_fx = L_Extract_lc( L_tmp, &temp_hi_fx );
2296 :
2297 7700 : exp_pow = sub( 14, temp_hi_fx );
2298 7700 : L_tmp = Pow2( 14, temp_lo_fx ); /* Qexp_pow */
2299 7700 : env[i] = L_shl( L_tmp, sub( 6, exp_pow ) );
2300 7700 : move32(); /* Q6 */
2301 7700 : L_tmp = L_add( hTdCngEnc->Enew_fx, hTdCngEnc->Enew_fx );
2302 7700 : env[i] = L_add( env[i], L_tmp );
2303 7700 : move32(); /* Q6 */
2304 : }
2305 385 : Copy32( env, &( hTdCngEnc->ho_env_hist_fx[( hTdCngEnc->ho_hist_ptr ) * NUM_ENV_CNG] ), NUM_ENV_CNG );
2306 : }
2307 385 : hTdCngEnc->ho_hist_size = add( hTdCngEnc->ho_hist_size, 1 );
2308 385 : move16();
2309 385 : if ( GT_16( hTdCngEnc->ho_hist_size, HO_HIST_SIZE ) )
2310 : {
2311 231 : hTdCngEnc->ho_hist_size = HO_HIST_SIZE;
2312 231 : move16();
2313 : }
2314 : }
2315 : }
2316 : /* dithering bit for AMR-WB IO mode is always set to 0 */
2317 2438 : IF( EQ_32( st_fx->core_brate, SID_1k75 ) )
2318 : {
2319 0 : push_indice( hBstr, IND_DITHERING, 0, 1 );
2320 : }
2321 2438 : IF( EQ_32( st_fx->core_brate, SID_2k40 ) )
2322 : {
2323 447 : IF( EQ_16( st_fx->L_frame, L_FRAME16k ) )
2324 : {
2325 277 : 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 447 : push_indice( hBstr, IND_CNG_HO, s_min( hTdCngEnc->burst_ho_cnt, HO_HIST_SIZE - 1 ), 3 );
2333 447 : hTdCngEnc->num_ho = m;
2334 447 : move16();
2335 447 : push_indice( hBstr, IND_SID_TYPE, 0, 1 );
2336 :
2337 447 : test();
2338 447 : 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 2438 : test();
2351 2438 : IF( EQ_32( st_fx->core_brate, SID_2k40 ) || EQ_32( st_fx->core_brate, SID_1k75 ) )
2352 : {
2353 447 : hDtxEnc->cng_cnt = 0;
2354 447 : move16();
2355 447 : hTdCngEnc->cng_hist_ptr = -1;
2356 447 : move16();
2357 : /* update frame length memory */
2358 447 : hDtxEnc->last_CNG_L_frame = st_fx->L_frame;
2359 447 : move16();
2360 : }
2361 : ELSE
2362 : {
2363 1991 : hDtxEnc->cng_cnt = add( hDtxEnc->cng_cnt, 1 );
2364 1991 : move16();
2365 : }
2366 :
2367 2438 : 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 0 : delete_indice( hBstr, IND_CNG_ENV1 );
2459 0 : move16();
2460 0 : move16();
2461 :
2462 0 : if ( st_fx->element_mode == IVAS_CPE_DFT )
2463 : {
2464 : }
2465 : else
2466 : {
2467 0 : push_indice( hBstr, IND_UNUSED, 0, 2 );
2468 : }
2469 0 : hTdCngEnc->ho_sid_bw = L_shl( L_and( hTdCngEnc->ho_sid_bw, (Word32) 0x3fffffffL ), 1 );
2470 0 : hTdCngEnc->ho_sid_bw = L_or( hTdCngEnc->ho_sid_bw, 0x1L );
2471 0 : move32();
2472 0 : move32();
2473 : }
2474 : ELSE
2475 : {
2476 0 : IF( EQ_32( st_fx->core_brate, SID_2k40 ) )
2477 : {
2478 0 : hTdCngEnc->ho_sid_bw = L_shl( L_and( hTdCngEnc->ho_sid_bw, (Word32) 0x3fffffffL ), 1 );
2479 0 : push_indice( hBstr, IND_SID_BW, 0, 1 );
2480 : }
2481 : }
2482 :
2483 0 : return;
2484 : }
2485 :
2486 : /*---------------------------------------------------------------------*
2487 : * shb_DTX()
2488 : *
2489 : * Decide if encoding SHB SID or not
2490 : *---------------------------------------------------------------------*/
2491 0 : static Word16 shb_DTX_fx(
2492 : Encoder_State *st_fx, /* i/o: State structure */
2493 : const Word16 *shb_speech_fx, /* i : SHB target signal (6-14kHz) at 16kHz (Q0) */
2494 : const Word16 *syn_12k8_16k /* i : ACELP core synthesis at 12.8kHz or 16kHz (st_fx->Q_syn = 0) */
2495 : )
2496 : {
2497 : Word16 i;
2498 : Word16 update_fx;
2499 : Word16 shb_old_speech_fx[( ACELP_LOOK_12k8 + L_SUBFR + L_FRAME ) * 5 / 4];
2500 : Word16 *shb_new_speech_fx;
2501 : Word32 wb_ener_fx;
2502 : Word32 shb_ener_fx;
2503 : Word16 log_wb_ener_fx;
2504 : Word16 log_shb_ener_fx;
2505 : Word16 tmp;
2506 : Word16 exp;
2507 : Word16 fra;
2508 : Word16 att; /*Q8*/
2509 0 : Word16 allow_cn_step_fx = 0;
2510 0 : move16();
2511 0 : DTX_ENC_HANDLE hDtxEnc = st_fx->hDtxEnc;
2512 0 : TD_CNG_ENC_HANDLE hTdCngEnc = st_fx->hTdCngEnc;
2513 0 : TD_BWE_ENC_HANDLE hBWE_TD = st_fx->hBWE_TD;
2514 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
2515 0 : Flag Overflow = 0;
2516 0 : move32();
2517 : #endif
2518 0 : shb_new_speech_fx = shb_old_speech_fx + ( ACELP_LOOK_12k8 + L_SUBFR ) * 5 / 4;
2519 0 : Copy( hBWE_TD->old_speech_shb_fx, shb_old_speech_fx, ( ACELP_LOOK_12k8 + L_SUBFR ) * 5 / 4 );
2520 0 : Copy( shb_speech_fx, shb_new_speech_fx, L_FRAME16k );
2521 0 : Copy( shb_old_speech_fx + L_FRAME16k, hBWE_TD->old_speech_shb_fx, ( ACELP_LOOK_12k8 + L_SUBFR ) * 5 / 4 );
2522 :
2523 0 : shb_ener_fx = L_deposit_l( 0 );
2524 0 : FOR( i = 0; i < L_FRAME16k; i++ )
2525 : {
2526 0 : shb_ener_fx = L_mac_sat( shb_ener_fx, shb_old_speech_fx[i], shb_old_speech_fx[i] );
2527 : }
2528 :
2529 0 : shb_ener_fx = L_add( Mpy_32_16_1( shb_ener_fx, 102 ), 1 ); /* 102 in Q15, shb_ener_fx in Q1 */
2530 :
2531 0 : wb_ener_fx = L_deposit_l( 0 );
2532 0 : FOR( i = 0; i < st_fx->L_frame; i++ )
2533 : {
2534 0 : wb_ener_fx = L_mac_o( wb_ener_fx, syn_12k8_16k[i], syn_12k8_16k[i], &Overflow );
2535 : }
2536 :
2537 0 : wb_ener_fx = L_add( Mpy_32_16_1( wb_ener_fx, 128 ), 1 ); /* 128 in Q15, wb_ener_fx in Q1 */
2538 :
2539 0 : exp = norm_l( wb_ener_fx );
2540 0 : fra = Log2_norm_lc( L_shl( wb_ener_fx, exp ) );
2541 0 : exp = sub( 30 - 1, exp );
2542 0 : wb_ener_fx = Mpy_32_16( exp, fra, LG10 );
2543 0 : log_wb_ener_fx = round_fx_o( L_shl_o( wb_ener_fx, 10, &Overflow ), &Overflow ); /* log_wb_ener_fx in Q8 */
2544 0 : exp = norm_l( shb_ener_fx );
2545 0 : fra = Log2_norm_lc( L_shl( shb_ener_fx, exp ) );
2546 0 : exp = sub( 30 - 1, exp );
2547 0 : shb_ener_fx = Mpy_32_16( exp, fra, LG10 );
2548 :
2549 0 : test();
2550 0 : IF( EQ_16( st_fx->element_mode, IVAS_SCE ) || EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) )
2551 : {
2552 0 : att = 0;
2553 0 : move16();
2554 : // PMT("apply_scale is not implemented")
2555 : }
2556 : ELSE
2557 : {
2558 0 : att = 1664; /*6.5 in Q8*/
2559 0 : move16();
2560 : }
2561 :
2562 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 */
2563 0 : IF( hDtxEnc->first_CNG == 0 )
2564 : {
2565 0 : hTdCngEnc->mov_wb_cng_ener_fx = log_wb_ener_fx;
2566 0 : move16();
2567 0 : hTdCngEnc->mov_shb_cng_ener_fx = log_shb_ener_fx;
2568 0 : move16();
2569 0 : hTdCngEnc->last_wb_cng_ener_fx = log_wb_ener_fx;
2570 0 : move16();
2571 0 : hTdCngEnc->last_shb_cng_ener_fx = log_shb_ener_fx;
2572 0 : move16();
2573 : }
2574 :
2575 0 : if ( GT_16( abs_s( sub( log_wb_ener_fx, hTdCngEnc->mov_wb_cng_ener_fx ) ), 3072 /*12.0f Q8*/ ) )
2576 : {
2577 0 : allow_cn_step_fx = 1;
2578 0 : move16();
2579 : }
2580 :
2581 0 : IF( EQ_16( allow_cn_step_fx, 1 ) )
2582 : {
2583 0 : hTdCngEnc->mov_wb_cng_ener_fx = log_wb_ener_fx;
2584 0 : move16();
2585 0 : hTdCngEnc->mov_shb_cng_ener_fx = log_shb_ener_fx;
2586 0 : move16();
2587 : }
2588 : ELSE
2589 : {
2590 0 : tmp = sub( log_wb_ener_fx, hTdCngEnc->mov_wb_cng_ener_fx ); /* Q8 */
2591 0 : tmp = mult( tmp, 29491 /*.9f in Q15*/ ); /* Q8 */
2592 0 : hTdCngEnc->mov_wb_cng_ener_fx = add( hTdCngEnc->mov_wb_cng_ener_fx, tmp ); /* Q8 */
2593 0 : move16();
2594 0 : tmp = sub( log_shb_ener_fx, hTdCngEnc->mov_shb_cng_ener_fx );
2595 0 : tmp = mult( tmp, 8192 /*.25f in Q15*/ ); /* Q8 */
2596 0 : hTdCngEnc->mov_shb_cng_ener_fx = add( hTdCngEnc->mov_shb_cng_ener_fx, tmp ); /* Q8 */
2597 0 : move16();
2598 : }
2599 0 : hTdCngEnc->shb_NO_DATA_cnt = add( hTdCngEnc->shb_NO_DATA_cnt, 1 );
2600 0 : move16();
2601 0 : update_fx = 0;
2602 0 : move16();
2603 0 : IF( EQ_32( st_fx->core_brate, SID_2k40 ) )
2604 : {
2605 0 : test();
2606 0 : test();
2607 0 : IF( hDtxEnc->first_CNG == 0 || EQ_16( hTdCngEnc->last_vad, 1 ) || GE_16( hTdCngEnc->shb_NO_DATA_cnt, 100 ) )
2608 : {
2609 0 : update_fx = 1;
2610 0 : move16();
2611 : }
2612 : ELSE
2613 : {
2614 0 : IF( hTdCngEnc->shb_cng_ini_cnt > 0 )
2615 : {
2616 0 : update_fx = 1;
2617 0 : move16();
2618 0 : hTdCngEnc->shb_cng_ini_cnt = sub( hTdCngEnc->shb_cng_ini_cnt, 1 );
2619 0 : move16();
2620 : }
2621 : ELSE
2622 : {
2623 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*/ ) )
2624 : {
2625 0 : update_fx = 1;
2626 0 : move16();
2627 : }
2628 : ELSE
2629 : {
2630 0 : test();
2631 0 : IF( GE_16( st_fx->bwidth, SWB ) && LT_16( hTdCngEnc->last_SID_bwidth, SWB ) )
2632 : {
2633 0 : update_fx = 1;
2634 0 : move16();
2635 : }
2636 : ELSE
2637 : {
2638 0 : test();
2639 0 : IF( LT_16( st_fx->bwidth, SWB ) && GE_16( hTdCngEnc->last_SID_bwidth, SWB ) )
2640 : {
2641 0 : update_fx = 1;
2642 0 : move16();
2643 : }
2644 : }
2645 : }
2646 : }
2647 : }
2648 :
2649 0 : hTdCngEnc->last_SID_bwidth = st_fx->bwidth;
2650 0 : move16();
2651 : }
2652 : /* LF-boost not yet implemented in decoder which means that the specific wb_sid information is not used */
2653 0 : test();
2654 0 : test();
2655 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 ) )
2656 : {
2657 0 : update_fx = 1;
2658 0 : move16();
2659 : }
2660 :
2661 0 : IF( EQ_16( update_fx, 1 ) )
2662 : {
2663 0 : hTdCngEnc->last_wb_cng_ener_fx = hTdCngEnc->mov_wb_cng_ener_fx;
2664 0 : move16();
2665 0 : hTdCngEnc->last_shb_cng_ener_fx = hTdCngEnc->mov_shb_cng_ener_fx;
2666 0 : move16();
2667 0 : hTdCngEnc->shb_NO_DATA_cnt = 0;
2668 0 : move16();
2669 : }
2670 :
2671 :
2672 0 : return ( update_fx );
2673 : }
2674 :
2675 : /*---------------------------------------------------------------------*
2676 : * calculate_hangover_attenuation_gain_fx()
2677 : *
2678 : *
2679 : *---------------------------------------------------------------------*/
2680 1427 : void calculate_hangover_attenuation_gain_fx(
2681 : Encoder_State *st, /* i : encoder state structure */
2682 : Word16 *att, /* o : attenuation factor Q15 */
2683 : const Word16 vad_hover_flag /* i : VAD hangover flag */
2684 : )
2685 : {
2686 : Word16 offset;
2687 1427 : TD_CNG_ENC_HANDLE hTdCngEnc = st->hTdCngEnc;
2688 :
2689 1427 : *att = 32767; // 1.0f in Q15
2690 :
2691 1427 : move16();
2692 : /* smoothing in case of CNG */
2693 1427 : IF( hTdCngEnc != NULL )
2694 : {
2695 1427 : test();
2696 1427 : test();
2697 1427 : test();
2698 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 */
2699 : {
2700 0 : if ( st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD )
2701 : {
2702 : }
2703 : else
2704 : {
2705 0 : offset = 5;
2706 0 : move16();
2707 0 : test();
2708 0 : if ( EQ_16( st->bwidth, WB ) && st->hDtxEnc->CNG_mode >= 0 )
2709 : {
2710 0 : offset = st->hDtxEnc->CNG_mode;
2711 0 : move16();
2712 : }
2713 0 : assert( hTdCngEnc->burst_ho_cnt > 0 );
2714 0 : *att = CNG_burst_att_fx[offset][hTdCngEnc->burst_ho_cnt - 1]; /*Q15*/
2715 0 : move16();
2716 : }
2717 : }
2718 : }
2719 1427 : return;
2720 : }
2721 :
2722 184298 : void calculate_hangover_attenuation_gain_ivas_fx(
2723 : Encoder_State *st, /* i : encoder state structure */
2724 : Word16 *att, /* o : attenuation factor Q15 */
2725 : const Word16 vad_hover_flag /* i : VAD hangover flag */
2726 : )
2727 : {
2728 : Word16 lim, result_e;
2729 :
2730 184298 : *att = 32767; // 1.0f in Q15
2731 184298 : move16();
2732 :
2733 184298 : test();
2734 184298 : test();
2735 184298 : test();
2736 184298 : test();
2737 184298 : 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 ) )
2738 : {
2739 2654 : test();
2740 2654 : IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) )
2741 2232 : {
2742 2232 : Word32 exp = Mpy_32_16_1( L_mult( 26214 /*26214 = 1 / 160.f in Q22*/, st->hTdCngEnc->burst_ho_cnt ), st->hTdCngEnc->CNG_att_fx ); /* Q15 (22 + 1 + 7 - 15) */
2743 2232 : Word32 L_tmp = BASOP_Util_fPow( 1342177280 /* 10 in Q27 */, 4, exp, 16, &result_e );
2744 2232 : *att = extract_h( L_shl_sat( L_tmp, result_e ) );
2745 2232 : move16();
2746 : }
2747 : ELSE
2748 : {
2749 422 : test();
2750 422 : IF( EQ_16( st->bwidth, WB ) && st->hDtxEnc->CNG_mode >= 0 )
2751 : {
2752 0 : lim = HO_ATT_FX[st->hDtxEnc->CNG_mode];
2753 : }
2754 : ELSE
2755 : {
2756 422 : lim = 19660; /* 0.6 in Q15*/
2757 : }
2758 422 : move16();
2759 :
2760 422 : *att = mult_r( lim, 5461 ); /* 1/6.f in Q15*/
2761 422 : move16();
2762 422 : *att = divide1616( 32767, add( 2048, imult1616( *att, st->hTdCngEnc->burst_ho_cnt ) ) ); /* 2048 = 1 in Q11*/
2763 422 : move16();
2764 :
2765 422 : if ( LT_16( *att, lim ) )
2766 : {
2767 0 : *att = lim;
2768 0 : move16();
2769 : }
2770 : }
2771 : }
2772 :
2773 184298 : return;
2774 : }
2775 :
2776 44242 : void swb_CNG_enc_ivas_fx(
2777 : Encoder_State *st, /* i/o: State structure */
2778 : const Word16 *shb_speech_fx, /* i : SHB target signal (6-14kHz) at 16kHz Q0 */
2779 : const Word16 *syn_12k8_16k_fx /* i : ACELP core synthesis at 12.8kHz or 16kHz Q0 */
2780 : )
2781 : {
2782 : Word16 shb_SID_updt;
2783 :
2784 44242 : test();
2785 44242 : IF( EQ_32( st->core_brate, SID_2k40 ) || st->core_brate == FRAME_NO_DATA )
2786 : {
2787 11699 : IF( st->cng_type == LP_CNG )
2788 : {
2789 2438 : test();
2790 2438 : IF( GE_32( st->input_Fs, L_FRAME32k * FRAMES_PER_SEC ) )
2791 : {
2792 : /* decide if SHB SID encoding or not */
2793 2084 : shb_SID_updt = shb_DTX_ivas_fx( st, shb_speech_fx, syn_12k8_16k_fx );
2794 :
2795 : /* SHB CNG encoding */
2796 2084 : shb_CNG_encod_ivas_fx( st, shb_SID_updt );
2797 : }
2798 354 : ELSE IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) && EQ_32( st->core_brate, SID_2k40 ) )
2799 : {
2800 : /* LF-boost not used in DFT-stereo, instead the bandwidth is transmitted */
2801 48 : delete_indice( st->hBstr, IND_CNG_ENV1 );
2802 48 : push_indice( st->hBstr, IND_BWIDTH, st->bwidth, 2 );
2803 48 : push_indice( st->hBstr, IND_UNUSED, 0, 4 );
2804 48 : push_indice( st->hBstr, IND_SID_BW, 1, 1 );
2805 : }
2806 : }
2807 11699 : st->hTdCngEnc->last_vad = 0;
2808 11699 : move16();
2809 : }
2810 : ELSE
2811 : {
2812 32543 : st->hTdCngEnc->last_vad = 1;
2813 32543 : move16();
2814 : }
2815 :
2816 44242 : return;
2817 : }
2818 :
2819 :
2820 : /*---------------------------------------------------------------------*
2821 : * shb_CNG_encod()
2822 : *
2823 : * SID parameters encoding for SHB signal
2824 : *---------------------------------------------------------------------*/
2825 :
2826 2084 : static void shb_CNG_encod_ivas_fx(
2827 : Encoder_State *st, /* i/o: State structure */
2828 : const Word16 update /* i : SID update flag */
2829 : )
2830 : {
2831 2084 : Word16 idx_ener = 0;
2832 2084 : move16();
2833 2084 : BSTR_ENC_HANDLE hBstr = st->hBstr;
2834 :
2835 : Word16 ener_mid_dec_thr_fx;
2836 :
2837 2084 : IF( EQ_16( update, 1 ) )
2838 : {
2839 399 : IF( st->element_mode == EVS_MONO )
2840 : {
2841 : /* 6.0 in Q8 -> 1510 */
2842 : /* 0.9 in Q15 29491 */
2843 : /* ( 1 / log10(2.0) ) * 0.1 in Q15 ->10886 */
2844 0 : idx_ener = shr( mult( add( mult( st->hTdCngEnc->mov_shb_cng_ener_fx, 10886 ), 1510 ), 29491 ), 8 ); /* Q0 */
2845 : }
2846 : ELSE
2847 : {
2848 : /*idx_ener = (int16_t)(0.7f * (0.1f * st->hTdCngEnc->mov_shb_cng_ener / (float)log10(2.0f) + 6.0f) + 0.5f);*/
2849 : // PMT("shb_CNG_encod_fx quantization in missing")
2850 : /* 6.0 in Q8 -> 1510 */
2851 : /* 0.7 in Q15 22938 */
2852 : /* ( 1 / log10(2.0) ) * 0.1 in Q15 -> 10886 */
2853 399 : idx_ener = shr( mult( add( mult( st->hTdCngEnc->mov_shb_cng_ener_fx, 10886 ), 1510 ), 22938 ), 8 ); /* Q0 */
2854 : }
2855 :
2856 :
2857 399 : if ( LT_16( st->bwidth, SWB ) )
2858 : {
2859 2 : idx_ener = 0;
2860 2 : move16();
2861 : }
2862 :
2863 399 : IF( GT_16( idx_ener, 15 ) )
2864 : {
2865 0 : idx_ener = 15;
2866 0 : move16();
2867 : }
2868 399 : ELSE IF( idx_ener < 0 )
2869 : {
2870 0 : idx_ener = 0;
2871 0 : move16();
2872 : }
2873 :
2874 : /* prevent toggling of idx_ener by adding small dead-zone interval around decision thresholds */
2875 399 : IF( st->element_mode != EVS_MONO )
2876 : {
2877 399 : IF( EQ_16( abs_s( sub( idx_ener, st->hTdCngEnc->last_idx_ener ) ), 1 ) )
2878 : {
2879 :
2880 : Word16 tmp, tmp1, tmp2, scale, exp1, exp2, ener_mid_dec_thr_e;
2881 30 : tmp = BASOP_Util_Divide1616_Scale( st->hTdCngEnc->last_idx_ener, 22938, &scale ); // 0.7 in Q15 ->exp 0
2882 30 : scale = add( scale, ( 15 - 0 ) );
2883 30 : tmp = sub( tmp, shl( 6, sub( Q15, scale ) ) );
2884 30 : tmp1 = BASOP_Util_Divide1616_Scale( tmp, 3277, &exp1 );
2885 30 : exp1 = add( exp1, ( scale - 0 ) );
2886 :
2887 30 : ener_mid_dec_thr_fx = shr( mult( tmp1, 9864 ), 1 ); // exp = exp
2888 :
2889 30 : tmp = BASOP_Util_Divide1616_Scale( idx_ener, 22938, &scale ); // 0.7 in Q15 ->exp 0
2890 30 : scale = add( scale, ( 15 - 0 ) );
2891 30 : tmp = sub( tmp, shl( 6, sub( Q15, scale ) ) );
2892 30 : tmp1 = BASOP_Util_Divide1616_Scale( tmp, 3277, &exp2 );
2893 30 : exp2 = add( exp2, ( scale - 0 ) );
2894 :
2895 30 : tmp2 = shr( mult( tmp1, 9864 ), 1 ); // exp = exp
2896 :
2897 30 : ener_mid_dec_thr_e = BASOP_Util_Add_MantExp( tmp2, exp2, ener_mid_dec_thr_fx, exp1, &ener_mid_dec_thr_fx );
2898 :
2899 :
2900 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 );
2901 30 : tmp1 = BASOP_Util_Divide1616_Scale( tmp, ener_mid_dec_thr_fx, &exp1 );
2902 30 : exp1 = add( exp1, sub( scale, ener_mid_dec_thr_e ) );
2903 30 : IF( LT_16( abs_s( tmp1 ), shr( 328, sub( 15, exp1 ) ) ) )
2904 : {
2905 0 : idx_ener = st->hTdCngEnc->last_idx_ener;
2906 0 : move16();
2907 : }
2908 : }
2909 : }
2910 :
2911 399 : st->hTdCngEnc->last_idx_ener = idx_ener;
2912 399 : move16();
2913 :
2914 399 : push_indice( hBstr, IND_SHB_CNG_GAIN, idx_ener, 4 );
2915 399 : push_indice( hBstr, IND_SID_BW, 1, 1 );
2916 399 : delete_indice( hBstr, IND_CNG_ENV1 );
2917 399 : IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) )
2918 : {
2919 399 : push_indice( st->hBstr, IND_BWIDTH, st->bwidth, 2 );
2920 : }
2921 : ELSE
2922 : {
2923 0 : push_indice( hBstr, IND_UNUSED, 0, 2 );
2924 : }
2925 399 : st->hTdCngEnc->ho_sid_bw = L_shl( L_and( st->hTdCngEnc->ho_sid_bw, (Word32) 0x3fffffffL ), 1 );
2926 399 : st->hTdCngEnc->ho_sid_bw = L_or( st->hTdCngEnc->ho_sid_bw, 0x1L );
2927 399 : move32();
2928 399 : move32();
2929 : }
2930 1685 : ELSE IF( EQ_32( st->core_brate, SID_2k40 ) )
2931 : {
2932 0 : st->hTdCngEnc->ho_sid_bw = L_shl( L_and( st->hTdCngEnc->ho_sid_bw, (Word32) 0x3fffffffL ), 1 );
2933 0 : move32();
2934 0 : push_indice( hBstr, IND_SID_BW, 0, 1 );
2935 : }
2936 :
2937 2084 : return;
2938 : }
2939 :
2940 : /*---------------------------------------------------------------------*
2941 : * shb_DTX()
2942 : *
2943 : * Decide if encoding SHB SID or not
2944 : *---------------------------------------------------------------------*/
2945 :
2946 2084 : static Word16 shb_DTX_ivas_fx(
2947 : Encoder_State *st, /* i/o: State structure */
2948 : const Word16 *shb_speech_fx, /* i : SHB target signal (6-14kHz) at 16kHz Q0 */
2949 : const Word16 *syn_12k8_16k_fx /* i : ACELP core synthesis at 12.8kHz or 16kHz Q0 */
2950 : )
2951 : {
2952 : Word16 i;
2953 : Word16 update;
2954 :
2955 2084 : Word16 allow_cn_step = 0;
2956 2084 : move16();
2957 : Word16 shb_old_speech_fx[( ACELP_LOOK_12k8 + L_SUBFR + L_FRAME ) * 5 / 4];
2958 : Word16 *shb_new_speech_fx;
2959 : Word32 wb_ener_fx;
2960 : Word32 shb_ener_fx;
2961 : Word16 log_wb_ener_fx;
2962 : Word16 log_shb_ener_fx;
2963 : Word16 tmp;
2964 : Word16 exp;
2965 : Word16 fra;
2966 : Word16 att_fx; /*Q8*/
2967 :
2968 2084 : TD_CNG_ENC_HANDLE hTdCngEnc = st->hTdCngEnc;
2969 2084 : TD_BWE_ENC_HANDLE hBWE_TD = st->hBWE_TD;
2970 :
2971 :
2972 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
2973 2084 : Flag Overflow = 0;
2974 2084 : move16();
2975 : #endif
2976 :
2977 2084 : shb_new_speech_fx = shb_old_speech_fx + ( ACELP_LOOK_12k8 + L_SUBFR ) * 5 / 4;
2978 2084 : Copy( hBWE_TD->old_speech_shb_fx, shb_old_speech_fx, ( ACELP_LOOK_12k8 + L_SUBFR ) * 5 / 4 ); // old_speech_shb_fx -> Q0
2979 2084 : Copy( shb_speech_fx, shb_new_speech_fx, L_FRAME16k ); // Q0
2980 2084 : Copy( shb_old_speech_fx + L_FRAME16k, hBWE_TD->old_speech_shb_fx, ( ACELP_LOOK_12k8 + L_SUBFR ) * 5 / 4 ); // Q0
2981 :
2982 2084 : shb_ener_fx = L_deposit_l( 0 );
2983 668964 : FOR( i = 0; i < L_FRAME16k; i++ )
2984 : {
2985 666880 : shb_ener_fx = L_mac_sat( shb_ener_fx, shb_old_speech_fx[i], shb_old_speech_fx[i] ); // ( Q0 + Q0 + Q1 ) --> Q1 due to left shift in L_mac
2986 : }
2987 :
2988 2084 : shb_ener_fx = L_add( Mpy_32_16_1( shb_ener_fx, 102 ), 1 ); /* ( 1 / L_FRAME16K ) -> 102 in Q15, shb_ener_fx in Q1 */
2989 :
2990 2084 : wb_ener_fx = L_deposit_l( 0 );
2991 611428 : FOR( i = 0; i < st->L_frame; i++ )
2992 : {
2993 609344 : 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
2994 : }
2995 :
2996 2084 : wb_ener_fx = L_add( Mpy_32_16_1( wb_ener_fx, 128 ), 1 ); /* 128 in Q15, wb_ener_fx in Q1 */
2997 :
2998 2084 : exp = norm_l( wb_ener_fx );
2999 2084 : fra = Log2_norm_lc( L_shl( wb_ener_fx, exp ) );
3000 2084 : exp = sub( 30 - 1, exp );
3001 2084 : wb_ener_fx = Mpy_32_16( exp, fra, LG10 );
3002 :
3003 2084 : log_wb_ener_fx = round_fx_o( L_shl_o( wb_ener_fx, 10, &Overflow ), &Overflow ); /* log_wb_ener_fx in Q8 */
3004 2084 : exp = norm_l( shb_ener_fx );
3005 2084 : fra = Log2_norm_lc( L_shl( shb_ener_fx, exp ) );
3006 2084 : exp = sub( 30 - 1, exp );
3007 2084 : shb_ener_fx = Mpy_32_16( exp, fra, LG10 );
3008 :
3009 :
3010 2084 : test();
3011 2084 : IF( EQ_16( st->element_mode, IVAS_SCE ) || EQ_16( st->element_mode, IVAS_CPE_DFT ) )
3012 2084 : {
3013 2084 : Word32 att_fx32 = 0;
3014 2084 : move32();
3015 : Word16 index;
3016 :
3017 2084 : apply_scale_ivas_fx( &att_fx32, st->hFdCngEnc->hFdCngCom->CngBandwidth, st->hFdCngEnc->hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO, &index ); // Q23;
3018 :
3019 2084 : att_fx = extract_l( L_shr( att_fx32, 15 ) ); // Q8
3020 : }
3021 : ELSE
3022 : {
3023 0 : att_fx = -1664; // Q8
3024 0 : move16();
3025 : }
3026 :
3027 :
3028 2084 : 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 */
3029 :
3030 2084 : IF( st->hDtxEnc->first_CNG == 0 )
3031 : {
3032 :
3033 :
3034 22 : hTdCngEnc->mov_wb_cng_ener_fx = log_wb_ener_fx; // Q8
3035 22 : hTdCngEnc->mov_shb_cng_ener_fx = log_shb_ener_fx; // Q8
3036 22 : hTdCngEnc->last_wb_cng_ener_fx = log_wb_ener_fx; // Q8
3037 22 : hTdCngEnc->last_shb_cng_ener_fx = log_shb_ener_fx; // Q8
3038 22 : move16();
3039 22 : move16();
3040 22 : move16();
3041 22 : move16();
3042 : }
3043 2084 : IF( GT_16( abs_s( sub( log_wb_ener_fx, hTdCngEnc->mov_wb_cng_ener_fx ) ), 3072 /*12 in Q8*/ ) )
3044 : {
3045 20 : allow_cn_step = 1;
3046 20 : move16();
3047 : }
3048 :
3049 : /* Also allow step if shb energy has dropped 12 dB */
3050 2084 : test();
3051 2084 : test();
3052 2084 : IF( ( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) && GT_16( sub( hTdCngEnc->mov_shb_cng_ener_fx, log_shb_ener_fx ), 3072 /*12 in Q8*/ ) )
3053 : {
3054 21 : allow_cn_step = 1;
3055 21 : move16();
3056 : }
3057 :
3058 2084 : IF( EQ_16( allow_cn_step, 1 ) )
3059 : {
3060 22 : hTdCngEnc->mov_wb_cng_ener_fx = log_wb_ener_fx;
3061 22 : hTdCngEnc->mov_shb_cng_ener_fx = log_shb_ener_fx;
3062 22 : move16();
3063 22 : move16();
3064 : }
3065 : ELSE
3066 : {
3067 2062 : tmp = sub( log_wb_ener_fx, hTdCngEnc->mov_wb_cng_ener_fx ); /* Q8 */
3068 2062 : tmp = mult( tmp, 29491 /* .9f in Q15*/ ); /* Q8 */
3069 2062 : hTdCngEnc->mov_wb_cng_ener_fx = add( hTdCngEnc->mov_wb_cng_ener_fx, tmp ); /* Q8 */
3070 2062 : move16();
3071 :
3072 2062 : tmp = sub( log_shb_ener_fx, hTdCngEnc->mov_shb_cng_ener_fx );
3073 2062 : tmp = mult( tmp, 8192 /* .25f in Q15*/ ); /* Q8 */
3074 2062 : hTdCngEnc->mov_shb_cng_ener_fx = add( hTdCngEnc->mov_shb_cng_ener_fx, tmp ); /* Q8 */
3075 2062 : move16();
3076 : }
3077 :
3078 2084 : hTdCngEnc->shb_NO_DATA_cnt = add( hTdCngEnc->shb_NO_DATA_cnt, 1 );
3079 2084 : update = 0;
3080 :
3081 2084 : move16();
3082 2084 : move16();
3083 :
3084 2084 : IF( EQ_32( st->core_brate, SID_2k40 ) )
3085 : {
3086 399 : test();
3087 399 : test();
3088 399 : test();
3089 399 : IF( st->hDtxEnc->first_CNG == 0 )
3090 : {
3091 22 : update = 1;
3092 22 : move16();
3093 : }
3094 377 : ELSE IF( hTdCngEnc->shb_cng_ini_cnt > 0 )
3095 : {
3096 22 : hTdCngEnc->shb_cng_ini_cnt = sub( hTdCngEnc->shb_cng_ini_cnt, 1 );
3097 22 : update = 1;
3098 22 : move16();
3099 22 : move16();
3100 : }
3101 355 : ELSE IF( EQ_16( hTdCngEnc->last_vad, 1 ) )
3102 : {
3103 163 : update = 1;
3104 163 : move16();
3105 : }
3106 192 : ELSE IF( GE_16( hTdCngEnc->shb_NO_DATA_cnt, 100 ) )
3107 : {
3108 0 : update = 1;
3109 0 : move16();
3110 : }
3111 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 ) )
3112 : {
3113 47 : update = 1;
3114 47 : move16();
3115 : }
3116 145 : ELSE IF( ( GE_16( st->bwidth, SWB ) && LT_16( hTdCngEnc->last_SID_bwidth, SWB ) ) || ( LT_16( st->bwidth, SWB ) && GE_16( hTdCngEnc->last_SID_bwidth, SWB ) ) )
3117 : {
3118 0 : update = 1;
3119 0 : move16();
3120 : }
3121 :
3122 399 : hTdCngEnc->last_SID_bwidth = st->bwidth;
3123 399 : move16();
3124 : }
3125 :
3126 : /* LF-boost not yet implemented in decoder which means that the specific wb_sid information is not used */
3127 2084 : test();
3128 2084 : test();
3129 2084 : if ( ( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) && EQ_32( st->core_brate, SID_2k40 ) )
3130 : {
3131 399 : update = 1;
3132 399 : move16();
3133 : }
3134 :
3135 2084 : IF( EQ_16( update, 1 ) )
3136 : {
3137 399 : hTdCngEnc->last_wb_cng_ener_fx = hTdCngEnc->mov_wb_cng_ener_fx;
3138 399 : hTdCngEnc->last_shb_cng_ener_fx = hTdCngEnc->mov_shb_cng_ener_fx;
3139 399 : hTdCngEnc->shb_NO_DATA_cnt = 0;
3140 399 : move16();
3141 399 : move16();
3142 399 : move16();
3143 : }
3144 :
3145 2084 : return ( update );
3146 : }
|