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 "prot_fx.h" /* Function prototypes */
8 : #include "rom_com.h"
9 : #include "ivas_rom_com_fx.h"
10 :
11 : /*---------------------------------------------------------------------*
12 : * Local constants
13 : *---------------------------------------------------------------------*/
14 : #define A2 6554
15 : #define OmA2 ( 32768 - A2 )
16 : #define GAIN_VAR 11811 /* in Q31 divided by 2 (Q30) */
17 : const Word16 att_pow_tbl[SIZE_SCALE_TABLE_STEREO + 1] = { 9234, 10361, 13044, 16422, 22669, 31292, 32767, 26634, 28212, 20674, 16422, 27254, 30934, 32767 };
18 : /*-------------------------------------------------------*
19 : * CNG_exc()
20 : *
21 : * Comfort noise generation routine
22 : *-------------------------------------------------------*/
23 :
24 2378 : void CNG_exc_fx(
25 : const Word32 core_brate, /* i : core bitrate */
26 : const Word16 L_frame, /* i : length of the frame */
27 : Word32 *Enew, /* i/o: decoded SID energy Q6 */
28 : Word16 *seed, /* i/o: random generator seed */
29 : Word16 exc[], /* o : current non-enhanced excitation Q_new */
30 : Word16 exc2[], /* o : current enhanced excitation Q_new */
31 : Word32 *lp_ener, /* i/o: LP filtered E Q6 */
32 : const Word32 last_core_brate, /* i : previous frame core bitrate */
33 : Word16 *first_CNG, /* i/o: first CNG frame flag for energy init. */
34 : Word16 *cng_ener_seed, /* i/o: random generator seed for CNG energy */
35 : Word16 bwe_exc[], /* o : excitation for SWB TBE Q_syn */
36 : const Word16 allow_cn_step, /* i : allow CN step */
37 : Word16 *last_allow_cn_step, /* i/o: last allow step */
38 : const Word16 OldQ_exc, /* i : Old excitation scaling */
39 : const Word16 Q_exc, /* i : excitation scaling */
40 : const Word16 num_ho, /* i : number of selected hangover frames */
41 : Word32 q_env[], /*Q6*/
42 : Word32 *lp_env, /*Q6*/
43 : Word32 *old_env, /*Q6*/
44 : Word16 *exc_mem, /*Q0*/
45 : Word16 *exc_mem1, /*Q0*/
46 : Word16 *sid_bw,
47 : Word16 *cng_ener_seed1,
48 : Word16 exc3[], /*Q_exc*/
49 : Word16 Opt_AMR_WB,
50 : const Word16 element_mode /* i : IVAS Element mode */
51 : )
52 : {
53 : Word16 i, tmp, tmp2, exp, exp2, Q_ener;
54 : Word32 L_tmp_ener, L_tmp;
55 : Word16 i_subfr;
56 : Word16 pit_max;
57 : Word16 ftmp, j;
58 : Word16 *ptR, *ptI;
59 : Word16 fft_io[L_FRAME16k];
60 : Word32 itmp[129];
61 : Word32 env[NUM_ENV_CNG];
62 : Word32 enr1;
63 : Word32 denv[NUM_ENV_CNG];
64 : Word16 fra;
65 : Word16 temp_lo_fx, temp_hi_fx;
66 : Word16 exp_pow;
67 : Word32 L_tmp2;
68 : Word16 *pt_fft_io;
69 :
70 : /*------------------------------------------------------------------*
71 : * Initializations
72 : *------------------------------------------------------------------*/
73 :
74 2378 : pit_max = PIT16k_MAX;
75 2378 : move16();
76 2378 : if ( EQ_16( L_frame, L_FRAME ) )
77 : {
78 846 : pit_max = PIT_MAX;
79 846 : move16();
80 : }
81 :
82 : /*---------------------------------------------------------------------*
83 : * Initialization of CNG energy for the first CNG frame
84 : *---------------------------------------------------------------------*/
85 :
86 2378 : IF( *first_CNG == 0 )
87 : {
88 28 : IF( core_brate == FRAME_NO_DATA )
89 : {
90 : /* needed only in decoder when the very first SID frame was erased and this frame is FRAME_NO_DATA frame */
91 : /*fenew = dotp( fexc, fexc, pit_max )/pit_max;*/
92 0 : L_tmp_ener = Calc_Energy_Autoscaled( exc - pit_max, OldQ_exc, pit_max, &Q_ener );
93 0 : L_tmp_ener = Mult_32_16( L_tmp_ener, 9079 ); /* divide by PIT_MAX (in Q15 + Q6 to get output in Q6)*/
94 0 : L_tmp_ener = L_shr( L_tmp_ener, Q_ener ); /* -> If we want ener in Q6 */
95 :
96 0 : IF( EQ_16( L_frame, L_FRAME16k ) )
97 : {
98 0 : L_tmp_ener = Mult_32_16( L_tmp_ener, 26214 /*.8f in Q15*/ ); /* Compensate for 16kHz */
99 : }
100 0 : *Enew = L_tmp_ener;
101 0 : move32();
102 : }
103 :
104 28 : if ( element_mode == EVS_MONO )
105 : {
106 0 : *lp_ener = *Enew;
107 0 : move32();
108 : }
109 : }
110 :
111 : /*---------------------------------------------------------------------*
112 : * Update CNG energy
113 : *---------------------------------------------------------------------*/
114 2378 : test();
115 2378 : test();
116 2378 : IF( NE_32( last_core_brate, SID_1k75 ) && ( last_core_brate != FRAME_NO_DATA ) && NE_32( last_core_brate, SID_2k40 ) )
117 : {
118 : /* Partially reset CNG energy after active speech period */
119 189 : test();
120 189 : IF( allow_cn_step == 0 && *last_allow_cn_step == 0 )
121 : {
122 174 : test();
123 174 : IF( LT_16( num_ho, 3 ) || LT_32( Mult_32_16( *Enew, 21845 /*1/1.5f, Q15*/ ), *lp_ener ) )
124 : {
125 : /**lp_ener = 0.8f * *lp_ener + 0.2f * *Enew;*/
126 145 : L_tmp_ener = Mult_32_16( *lp_ener, 26214 /*.8f in Q15*/ );
127 145 : L_tmp_ener = Madd_32_16( L_tmp_ener, *Enew, 6554 /*.2f in Q15*/ );
128 : }
129 : ELSE
130 : {
131 : /**lp_ener = 0.95f * *lp_ener + 0.05f * *Enew;*/
132 29 : L_tmp_ener = Mult_32_16( *lp_ener, 31130 /*.95f in Q15*/ );
133 29 : L_tmp_ener = Madd_32_16( L_tmp_ener, *Enew, 1638 /* .05f in Q15*/ );
134 : }
135 : }
136 : ELSE
137 : {
138 15 : L_tmp_ener = *Enew;
139 15 : move32();
140 15 : *last_allow_cn_step = 0;
141 15 : move16();
142 : }
143 : }
144 : ELSE{
145 : /* normal CNG update */
146 2189 : IF( *last_allow_cn_step == 0 ){
147 : /**lp_ener = (float)(A2 * *Enew + (1-A2) * *lp_ener);*/
148 2119 : L_tmp_ener = Mult_32_16( *Enew, A2 );
149 2119 : L_tmp_ener = Madd_32_16( L_tmp_ener, *lp_ener, OmA2 );
150 : }
151 : ELSE
152 : {
153 70 : test();
154 70 : if ( EQ_32( core_brate, SID_1k75 ) || EQ_32( core_brate, SID_2k40 ) )
155 : {
156 0 : *last_allow_cn_step = 0;
157 0 : move16();
158 : }
159 :
160 70 : L_tmp_ener = *Enew;
161 70 : move32();
162 : }
163 : }
164 2378 : *lp_ener = L_max( L_tmp_ener, 1 );
165 2378 : move32(); /*To avoid / per 0*/
166 :
167 2378 : if ( EQ_16( allow_cn_step, 1 ) )
168 : {
169 15 : *last_allow_cn_step = 1;
170 15 : move16();
171 : }
172 : /* If not mono, skip CNG here */
173 2378 : IF( GT_16( element_mode, IVAS_SCE ) )
174 : {
175 1237 : return;
176 : }
177 : /*---------------------------------------------------------------------*
178 : * Generate white noise vector
179 : *---------------------------------------------------------------------*/
180 :
181 : /*for ( i=0; i<L_frame; i++ )exc2[i] = (float)own_random( seed );*/
182 1141 : Random_Fill( seed, L_frame, exc2, 4 );
183 : /*------------------------------------------------------------*
184 : * Insert random variation for excitation energy
185 : * (random variation is scaled according to *lp_ener value)
186 : *------------------------------------------------------------*/
187 :
188 6355 : FOR( i_subfr = 0; i_subfr < L_frame; i_subfr += L_SUBFR )
189 : {
190 : /* ener_lp = own_random(cng_ener_seed) * *lp_ener * GAIN_VAR + *lp_ener */
191 : /*------------------------------------------------------------*
192 : * Insert random variation for excitation energy
193 : * (random variation is scaled according to *lp_ener value)
194 : *------------------------------------------------------------*/
195 5214 : L_tmp = Mult_32_16( *lp_ener, Random( cng_ener_seed ) ); // Q6
196 5214 : L_tmp = Mult_32_16( L_tmp, GAIN_VAR ); // Q6
197 5214 : L_tmp = L_add_sat( L_tmp, *lp_ener );
198 5214 : L_tmp = L_max( L_tmp, 1 );
199 :
200 : /* enr = dot_product( exc2, exc2, L_SUBFR ) + 0.01f */
201 5214 : tmp = extract_h( Dot_product12( &exc2[i_subfr], &exc2[i_subfr], L_SUBFR, &exp ) );
202 5214 : exp = add( exp, 8 - 6 ); /* 8 from Q-4, -6 from L_SUBFR */
203 :
204 : /* enr = (float)sqrt(*lp_ener * L_SUBFR / enr) */
205 5214 : exp2 = norm_l( L_tmp );
206 5214 : tmp2 = extract_h( L_shl( L_tmp, exp2 ) );
207 5214 : exp2 = sub( 31 - 6, exp2 ); /* in Q15 (L_tmp in Q6)*/
208 :
209 5214 : exp = sub( exp, exp2 );
210 :
211 5214 : IF( GT_16( tmp, tmp2 ) )
212 : {
213 2193 : exp = add( exp, 1 );
214 : }
215 5214 : IF( GT_16( tmp, tmp2 ) )
216 : {
217 2193 : tmp = shr( tmp, 1 );
218 : }
219 5214 : tmp = div_s( tmp, tmp2 );
220 :
221 5214 : L_tmp = L_deposit_h( tmp );
222 :
223 5214 : L_tmp = Isqrt_lc( L_tmp, &exp );
224 5214 : tmp = extract_h( L_tmp );
225 :
226 5214 : exp = add( exp, 4 ); /* From Q15 to Q19 */
227 5214 : exp = add( exp, Q_exc ); /* Q_exc+ Q19 */
228 :
229 338910 : FOR( i = 0; i < L_SUBFR; i++ )
230 : {
231 : /* exc2[i] *= enr */
232 333696 : L_tmp = L_mult( exc2[i_subfr + i], tmp ); /* Q-4 * Q_exc+19 -> Q_exc +16 */
233 333696 : exc2[i_subfr + i] = round_fx_sat( L_shl_sat( L_tmp, exp ) );
234 333696 : move16();
235 : }
236 : }
237 1141 : IF( NE_16( Opt_AMR_WB, 1 ) )
238 : {
239 1141 : Copy( exc2, exc3, L_FRAME16k );
240 :
241 : /* enr1 = (float)log10( *Enew*L_frame + 0.1f ) / (float)log10( 2.0f ); */
242 1141 : exp = norm_l( *Enew );
243 1141 : L_tmp = L_shl( *Enew, exp ); /* Q(exp+6) */
244 1141 : L_tmp = Mult_32_16( L_tmp, shl( L_frame, 5 ) ); /* Q(exp+6+5-15=exp-4) */
245 1141 : L_tmp = L_shr_sat( L_tmp, sub( exp, 10 ) ); /* Q6 */
246 1141 : exp = norm_l( L_tmp );
247 1141 : fra = Log2_norm_lc( L_shl( L_tmp, exp ) );
248 1141 : exp = sub( sub( 30, exp ), 6 );
249 1141 : L_tmp = L_Comp( exp, fra );
250 : /* enr1 = round_fx(L_shl(L_tmp,8)); */ /*Q8 */
251 1141 : enr1 = L_shr( L_tmp, 10 ); /* Q6 */
252 :
253 :
254 1141 : IF( EQ_32( core_brate, SID_2k40 ) )
255 : {
256 202 : IF( *sid_bw == 0 )
257 : {
258 0 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
259 : {
260 : /* get quantized envelope */
261 : /* env[i] = pow(2.0f,(enr1 - q_env[i])); */
262 0 : L_tmp = L_sub( enr1, q_env[i] ); /* Q6 */
263 0 : L_tmp = L_shl( L_tmp, 10 ); /* 16 */
264 0 : temp_lo_fx = L_Extract_lc( L_tmp, &temp_hi_fx );
265 :
266 0 : exp_pow = sub( 14, temp_hi_fx );
267 0 : L_tmp = Pow2( 14, temp_lo_fx ); /* Qexp_pow */
268 0 : env[i] = L_shl( L_tmp, sub( 6, exp_pow ) );
269 0 : move32(); /* Q6 */
270 : }
271 : }
272 :
273 : /* initialize CNG envelope */
274 202 : test();
275 202 : IF( *first_CNG == 0 && *sid_bw == 0 )
276 : {
277 0 : Copy32( env, lp_env, NUM_ENV_CNG );
278 : }
279 :
280 202 : IF( *sid_bw == 0 )
281 : {
282 0 : Copy32( env, old_env, NUM_ENV_CNG );
283 : }
284 : }
285 :
286 23961 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
287 : {
288 : /* get AR low-passed envelope */
289 : /* lp_env[i] = 0.9f*lp_env[i] + (1-0.9f)*old_env[i]; */
290 22820 : L_tmp = Mult_32_16( lp_env[i], 29491 /*.9f in Q15*/ );
291 22820 : lp_env[i] = L_add( L_tmp, Mult_32_16( old_env[i], 3277 /*.1f in Q15*/ ) );
292 22820 : move32(); /* Q6 */
293 : }
294 :
295 : /* calculate the spectrum of random excitation signal */
296 1141 : Copy( exc2, fft_io, L_frame );
297 :
298 1141 : IF( EQ_16( L_frame, L_FRAME16k ) )
299 : {
300 650 : modify_Fs_fx( fft_io, L_FRAME16k, 16000, fft_io, 12800, exc_mem1, 0 );
301 : }
302 :
303 : /* fft_rel(fft_io, L_FFT, LOG2_L_FFT); */
304 1141 : fft_rel_fx( fft_io, L_FFT, LOG2_L_FFT ); /* ??????? */
305 1141 : ptR = &fft_io[1];
306 1141 : ptI = &fft_io[L_FFT - 1];
307 23961 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
308 : {
309 : /* env[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */
310 22820 : L_tmp = L_mult0( *ptR, *ptR ); /* 2*Q_exc */
311 22820 : L_tmp = L_mac0_sat( L_tmp, *ptI, *ptI ); /* 2*Q_exc */
312 22820 : L_tmp = L_shr( L_tmp, 1 ); /* 2*Q_exc+6 */
313 22820 : tmp = add( Q_exc, Q_exc );
314 22820 : env[i] = L_shr_sat( L_tmp, tmp );
315 22820 : move32(); /* Q6 */
316 22820 : ptR++;
317 22820 : ptI--;
318 : }
319 :
320 23961 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
321 : {
322 : /* denv[i] = lp_env[i] + 2*(*lp_ener) - env[i]; */
323 22820 : L_tmp = L_add_sat( *lp_ener, *lp_ener );
324 22820 : denv[i] = L_sub_sat( L_add_sat( lp_env[i], L_tmp ), env[i] );
325 22820 : move32(); /* Q6 */
326 :
327 22820 : if ( denv[i] < 0 )
328 : {
329 3845 : denv[i] = 0;
330 3845 : move32();
331 : }
332 : }
333 1141 : set32_fx( itmp, 0, NUM_ENV_CNG );
334 :
335 1141 : set16_fx( fft_io, 0, L_FFT );
336 1141 : ptR = &fft_io[1];
337 1141 : ptI = &fft_io[L_FFT - 1];
338 23961 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
339 : {
340 : /* *ptR = own_random( cng_ener_seed1 ); */
341 : /* *ptI = own_random( cng_ener_seed1 ); */
342 22820 : *ptR = Random( cng_ener_seed1 );
343 22820 : move16();
344 22820 : *ptI = Random( cng_ener_seed1 );
345 22820 : move16();
346 :
347 : /* env[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */
348 22820 : L_tmp = L_mult0( *ptR, *ptR ); /* Q0 */
349 22820 : L_tmp = L_mac0( L_tmp, *ptI, *ptI ); /* Q0 */
350 22820 : env[i] = L_shr( L_tmp, 1 );
351 22820 : move32(); /* Q6 */
352 22820 : ptR++;
353 22820 : ptI--;
354 : }
355 :
356 23961 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
357 : {
358 : /* itmp[i] += own_random( cng_ener_seed1 )*denv[i]*0.000011f + denv[i]; */
359 22820 : L_tmp = Mult_32_16( denv[i], Random( cng_ener_seed1 ) ); // Q6
360 22820 : L_tmp = Mult_32_16( L_tmp, GAIN_VAR ); // Q6
361 22820 : L_tmp = L_add_sat( L_tmp, denv[i] );
362 22820 : itmp[i] = L_add_sat( L_tmp, itmp[i] );
363 22820 : move32(); /* Q6 */
364 :
365 22820 : if ( itmp[i] < 0 )
366 : {
367 0 : itmp[i] = 0;
368 0 : move32();
369 : }
370 : }
371 1141 : ptR = &fft_io[1];
372 1141 : ptI = &fft_io[L_FFT - 1];
373 23961 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
374 : {
375 : /* *ptR *= sqrt(itmp[i]/env[i]); */
376 : /* *ptI *= sqrt(itmp[i]/env[i]); */
377 22820 : L_tmp = L_max( 1, itmp[i] ); /*Q6*/
378 22820 : exp = norm_l( L_tmp );
379 22820 : tmp = extract_h( L_shl( L_tmp, exp ) );
380 22820 : exp = sub( 31 - 6, exp ); /* in Q15 (L_tmp in Q6)*/
381 :
382 22820 : exp2 = norm_l( env[i] );
383 22820 : tmp2 = extract_h( L_shl( env[i], exp2 ) );
384 22820 : exp2 = sub( 31 - 6, exp2 ); /* in Q15 (L_tmp in Q6)*/
385 :
386 22820 : exp = sub( exp2, exp ); /* Denormalize and substract */
387 22820 : IF( GT_16( tmp2, tmp ) )
388 : {
389 13563 : exp = add( exp, 1 );
390 : }
391 22820 : IF( GT_16( tmp2, tmp ) )
392 : {
393 13563 : tmp2 = shr( tmp2, 1 );
394 : }
395 22820 : tmp = div_s( tmp2, tmp );
396 22820 : L_tmp = L_deposit_h( tmp );
397 22820 : L_tmp = Isqrt_lc( L_tmp, &exp ); /*Q(31-exp)*/
398 :
399 22820 : L_tmp2 = Mult_32_16( L_tmp, *ptR ); /*Q(16-exp)*/
400 22820 : *ptR = extract_h( L_shl_sat( L_tmp2, add( exp, Q_exc ) ) ); /*Q_exc*/
401 22820 : move16();
402 22820 : L_tmp2 = Mult_32_16( L_tmp, *ptI ); /*Q(16-exp)*/
403 22820 : *ptI = extract_h( L_shl_sat( L_tmp2, add( exp, Q_exc ) ) ); /*Q_exc*/
404 22820 : move16();
405 22820 : ptR++;
406 22820 : ptI--;
407 : }
408 :
409 1141 : ifft_rel_fx( fft_io, L_FFT, LOG2_L_FFT );
410 :
411 1141 : IF( EQ_16( L_frame, L_FRAME16k ) )
412 : {
413 650 : modify_Fs_fx( fft_io, L_FFT, 12800, fft_io, 16000, exc_mem, 0 );
414 : }
415 :
416 : /* enr1 = dotp( fft_io, fft_io, L_frame ) / L_frame; */
417 :
418 1141 : enr1 = 1;
419 1141 : move32();
420 1141 : pt_fft_io = fft_io;
421 1141 : IF( EQ_16( L_frame, L_FRAME ) )
422 : {
423 63339 : FOR( j = 0; j < 128; j++ )
424 : {
425 62848 : L_tmp = L_mult0( *pt_fft_io, *pt_fft_io );
426 62848 : pt_fft_io++;
427 62848 : L_tmp = L_mac0( L_tmp, *pt_fft_io, *pt_fft_io ); /* 2*(Q_exc) */
428 62848 : pt_fft_io++;
429 62848 : enr1 = L_add( enr1, L_shr( L_tmp, 7 ) ); /* 2*(Q_exc)+1, divide by L_frame done here */
430 : }
431 : }
432 : ELSE /* L_FRAME16k */
433 : {
434 104650 : FOR( j = 0; j < 160; j++ )
435 : {
436 104000 : L_tmp = L_mult0( *pt_fft_io, *pt_fft_io );
437 104000 : pt_fft_io++;
438 104000 : L_tmp = L_mac0( L_tmp, *pt_fft_io, *pt_fft_io ); /* 2*(Q_exc) */
439 104000 : pt_fft_io++;
440 104000 : enr1 = L_add( enr1, L_shr( Mult_32_16( L_tmp, 26214 /* 256/320, Q15 */ ), 7 ) ); /* 2*(Q_exc)+15+1-16+1, divide by L_frame done here */
441 : }
442 : }
443 1141 : enr1 = L_shr( enr1, sub( add( Q_exc, Q_exc ), 5 ) ); /*Q6*/
444 :
445 : /* add time domain randomization */
446 6355 : FOR( i_subfr = 0; i_subfr < L_frame; i_subfr += L_SUBFR )
447 : {
448 :
449 5214 : L_tmp = Mult_32_16( enr1, Random( cng_ener_seed1 ) );
450 5214 : L_tmp = Mult_32_16( L_tmp, GAIN_VAR );
451 5214 : L_tmp = L_add( L_tmp, enr1 );
452 5214 : L_tmp = L_max( L_tmp, 1 );
453 :
454 : /* enr = dot_product( fft_io, fft_io, L_SUBFR ) + 0.01f */
455 5214 : tmp = extract_h( Dot_product12( &fft_io[i_subfr], &fft_io[i_subfr], L_SUBFR, &exp ) );
456 5214 : exp = add( exp, sub( -6, add( Q_exc, Q_exc ) ) ); /* -2*Q_exc from fft_io, -6 from L_SUBFR */
457 :
458 : /* enr = (float)sqrt( ener_lp*L_SUBFR / enr ) */
459 5214 : exp2 = norm_l( L_tmp );
460 5214 : tmp2 = extract_h( L_shl( L_tmp, exp2 ) );
461 5214 : exp2 = sub( 31 - 6, exp2 ); /* in Q15 (L_tmp in Q6)*/
462 :
463 5214 : exp = sub( exp, exp2 );
464 :
465 5214 : IF( GT_16( tmp, tmp2 ) )
466 : {
467 2718 : exp = add( exp, 1 );
468 : }
469 5214 : IF( GT_16( tmp, tmp2 ) )
470 : {
471 2718 : tmp = shr( tmp, 1 );
472 : }
473 5214 : tmp = div_s( tmp, tmp2 );
474 :
475 5214 : L_tmp = L_deposit_h( tmp );
476 5214 : L_tmp = Isqrt_lc( L_tmp, &exp ); /*Q(31-exp)*/
477 5214 : test();
478 5214 : test();
479 5214 : test();
480 5214 : IF( NE_32( last_core_brate, SID_2k40 ) && NE_32( last_core_brate, SID_1k75 ) && ( last_core_brate != FRAME_NO_DATA ) && EQ_32( core_brate, SID_2k40 ) )
481 : {
482 443 : IF( GT_32( L_tmp, L_shl_sat( 1, sub( 31, exp ) ) ) )
483 : {
484 251 : L_tmp = L_shl( 1, sub( 31, exp ) );
485 : }
486 : }
487 :
488 5214 : tmp = extract_h( L_tmp );
489 338910 : FOR( i = 0; i < L_SUBFR; i++ )
490 : {
491 : /* fft_io[i] *= enr */
492 333696 : L_tmp = L_mult( fft_io[i_subfr + i], tmp ); /* Q_exc + 16 - exp */
493 333696 : fft_io[i_subfr + i] = round_fx( L_shl( L_tmp, exp ) ); /*Q_exc*/
494 333696 : move16();
495 : }
496 : }
497 :
498 334837 : FOR( i = 0; i < L_frame; i++ )
499 : {
500 : /* fft_io[i] = 0.75f*fft_io[i] + exc2[i];*/
501 333696 : tmp = mult( fft_io[i], 24576 /*.75f in Q15*/ );
502 333696 : fft_io[i] = add_sat( tmp, exc2[i] );
503 333696 : move16(); /*Q_exc*/
504 : }
505 :
506 : /* enr = (dotp( fft_io, fft_io, L_frame ) / L_frame) + 0.01f */
507 :
508 1141 : L_tmp2 = 1;
509 1141 : move32();
510 1141 : pt_fft_io = fft_io;
511 1141 : IF( EQ_16( L_frame, L_FRAME ) )
512 : {
513 63339 : FOR( j = 0; j < 128; j++ )
514 : {
515 62848 : L_tmp = L_mult0( *pt_fft_io, *pt_fft_io );
516 62848 : pt_fft_io++;
517 62848 : L_tmp = L_mac0_sat( L_tmp, *pt_fft_io, *pt_fft_io ); /* 2*(Q_exc) */
518 62848 : pt_fft_io++;
519 62848 : L_tmp2 = L_add_sat( L_tmp2, L_shr( L_tmp, 7 ) ); /* 2*(Q_exc)+1, divide by L_frame done here */
520 : }
521 : }
522 : ELSE /* L_FRAME16k */
523 : {
524 104650 : FOR( j = 0; j < 160; j++ )
525 : {
526 104000 : L_tmp = L_mult0( *pt_fft_io, *pt_fft_io );
527 104000 : pt_fft_io++;
528 104000 : L_tmp = L_mac0_sat( L_tmp, *pt_fft_io, *pt_fft_io ); /* 2*(Q_exc) */
529 104000 : pt_fft_io++;
530 104000 : L_tmp2 = L_add( L_tmp2, L_shr( Mult_32_16( L_tmp, 26214 /* 256/320, Q15 */ ), 7 ) ); /* 2*(Q_exc)+15+1-16+1, divide by L_frame done here */
531 : }
532 : }
533 1141 : L_tmp2 = L_shr( L_tmp2, sub( add( Q_exc, Q_exc ), 5 ) ); /*Q6*/
534 :
535 :
536 : /* enr = (*lp_ener)/enr; */
537 : /* ftmp = sqrt(enr); */
538 1141 : L_tmp = L_max( 1, *lp_ener ); /*Q6*/
539 1141 : exp = norm_l( L_tmp );
540 1141 : tmp = extract_h( L_shl( L_tmp, exp ) );
541 1141 : exp = sub( 31 - 6, exp ); /* in Q15 (L_tmp in Q6)*/
542 :
543 1141 : exp2 = norm_l( L_tmp2 );
544 1141 : tmp2 = extract_h( L_shl( L_tmp2, exp2 ) );
545 1141 : exp2 = sub( 31 - 6, exp2 ); /* in Q15 (L_tmp in Q6)*/
546 :
547 1141 : exp = sub( exp2, exp ); /* Denormalize and substract */
548 1141 : IF( GT_16( tmp2, tmp ) )
549 : {
550 596 : exp = add( exp, 1 );
551 : }
552 1141 : IF( GT_16( tmp2, tmp ) )
553 : {
554 596 : tmp2 = shr( tmp2, 1 );
555 : }
556 1141 : tmp = div_s( tmp2, tmp );
557 1141 : L_tmp = L_deposit_h( tmp );
558 1141 : L_tmp = Isqrt_lc( L_tmp, &exp ); /*Q(31-exp)*/
559 :
560 1141 : ftmp = extract_h( L_shl_sat( L_tmp, exp ) ); /* Q15 */
561 334837 : FOR( i = 0; i < L_frame; i++ )
562 : {
563 : /* fft_io[i] *= ftmp;*/
564 333696 : fft_io[i] = mult( fft_io[i], ftmp );
565 333696 : move16(); /* Q_exc */
566 : }
567 1141 : Copy( fft_io, exc2, L_frame );
568 : }
569 1141 : IF( NE_16( Opt_AMR_WB, 1 ) )
570 : {
571 1141 : Copy( exc3, exc, L_frame );
572 : }
573 : ELSE
574 : {
575 0 : Copy( exc2, exc, L_frame );
576 : }
577 :
578 1141 : IF( EQ_16( L_frame, L_FRAME ) )
579 : {
580 491 : interp_code_5over2_fx( exc2, bwe_exc, L_FRAME );
581 : }
582 : ELSE
583 : {
584 650 : interp_code_4over2_fx( exc2, bwe_exc, L_frame );
585 : }
586 1141 : return;
587 : }
588 :
589 : /*-------------------------------------------------------*
590 : * cng_params_postupd_fx
591 : *
592 : * Post-update of CNG parameters
593 : *-------------------------------------------------------*/
594 0 : void cng_params_postupd_fx(
595 : const Word16 ho_circ_ptr, /* i : pointer for CNG averaging buffers Q0 */
596 : Word16 *cng_buf_cnt, /* i/o: counter for CNG store buffers Q0 */
597 : const Word16 *const cng_exc2_buf, /* i : Excitation buffer Q_exc */
598 : const Word16 *const cng_Qexc_buf, /* i : Q_exc buffer Q0 */
599 : const Word32 *const cng_brate_buf, /* i : bit rate buffer Q0 */
600 : Word32 ho_env_circ[] /* i/o: Envelope buffer Q6 */
601 : )
602 : {
603 : Word16 i, j;
604 : Word16 Q_exc;
605 : const Word16 *exc2;
606 : Word16 fft_io[L_FFT];
607 : Word32 sp[129];
608 : Word16 *ptR, *ptI;
609 : Word32 env[NUM_ENV_CNG];
610 : Word32 L_tmp;
611 : Word16 tmp;
612 : Word16 temp_lo_fx, temp_hi_fx;
613 : Word16 exp_pow;
614 : Word16 exp1;
615 : Word16 CNG_mode;
616 : Word16 ptr;
617 : Word32 last_active_brate;
618 : #ifndef ISSUE_1836_replace_overflow_libcom
619 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
620 : Flag Overflow = 0;
621 : move32();
622 : #endif
623 : #endif
624 :
625 0 : ptr = add( sub( ho_circ_ptr, *cng_buf_cnt ), 1 );
626 0 : IF( ptr < 0 )
627 : {
628 0 : ptr = add( ptr, HO_HIST_SIZE );
629 : }
630 :
631 0 : FOR( j = 0; j < *cng_buf_cnt; j++ )
632 : {
633 0 : exc2 = &cng_exc2_buf[ptr * L_FFT];
634 0 : Q_exc = cng_Qexc_buf[ptr];
635 0 : move16();
636 0 : last_active_brate = cng_brate_buf[ptr];
637 0 : move32();
638 :
639 : /* calculate the spectrum of residual signal */
640 0 : Copy( exc2, fft_io, L_FFT );
641 :
642 0 : fft_rel_fx( fft_io, L_FFT, LOG2_L_FFT );
643 :
644 0 : ptR = &fft_io[1];
645 0 : ptI = &fft_io[L_FFT - 1];
646 0 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
647 : {
648 : /* sp[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */
649 : #ifdef ISSUE_1836_replace_overflow_libcom
650 0 : L_tmp = L_mult_sat( *ptR, *ptR ); /* 2*Q_exc+1 */
651 0 : L_tmp = L_add_sat( L_tmp, L_mult_sat( *ptI, *ptI ) ); /* 2*Q_exc+1 */
652 0 : L_tmp = L_add_sat( L_tmp, L_tmp ); /* 2*Q_exc+1 */
653 : #else
654 : L_tmp = L_mult_o( *ptR, *ptR, &Overflow ); /* 2*Q_exc+1 */
655 : L_tmp = L_add_o( L_tmp, L_mult_o( *ptI, *ptI, &Overflow ), &Overflow ); /* 2*Q_exc+1 */
656 : L_tmp = L_add_o( L_tmp, L_tmp, &Overflow ); /* 2*Q_exc+1 */
657 : #endif
658 0 : L_tmp = Mult_32_16( L_tmp, 128 ); /* 2*Q_exc+1 */
659 0 : tmp = add( add( Q_exc, Q_exc ), 1 );
660 0 : sp[i] = L_shr( L_tmp, sub( tmp, 6 ) );
661 0 : move32(); /* Q6 */
662 :
663 0 : ptR++;
664 0 : ptI--;
665 : }
666 :
667 0 : Copy32( sp, env, NUM_ENV_CNG );
668 : {
669 :
670 0 : CNG_mode = get_cng_mode( last_active_brate );
671 :
672 : /* att = 1/pow(2,ENR_ATT_fx[CNG_mode]); */
673 0 : L_tmp = L_shl( L_deposit_l( ENR_ATT_fx[CNG_mode] ), 8 ); /* 16 */
674 0 : temp_lo_fx = L_Extract_lc( L_tmp, &temp_hi_fx );
675 :
676 0 : exp_pow = sub( 14, temp_hi_fx );
677 0 : L_tmp = Pow2( 14, temp_lo_fx ); /* Qexp_pow */
678 0 : L_tmp = L_shl( L_tmp, sub( 13, exp_pow ) ); /* Q13 */
679 0 : tmp = extract_l( L_tmp ); /* Q13 */
680 :
681 0 : exp1 = norm_s( tmp );
682 0 : tmp = shl( tmp, exp1 ); /*Q(exp1+13) */
683 0 : tmp = div_s( 16384, tmp ); /*Q(15+14-exp1-13) */
684 0 : tmp = shr( tmp, sub( 1, exp1 ) ); /* Q15 */
685 : }
686 :
687 0 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
688 : {
689 0 : env[i] = Mult_32_16( env[i], tmp );
690 0 : move32();
691 : }
692 :
693 : /* update the circular buffer of old residual envelope */
694 0 : Copy32( env, &( ho_env_circ[(ptr) *NUM_ENV_CNG] ), NUM_ENV_CNG );
695 :
696 0 : ptr = add( ptr, 1 );
697 0 : if ( EQ_16( ptr, HO_HIST_SIZE ) )
698 : {
699 0 : ptr = 0;
700 0 : move16();
701 : }
702 : }
703 :
704 0 : *cng_buf_cnt = 0;
705 0 : move16();
706 :
707 0 : return;
708 : }
709 :
710 0 : void cng_params_postupd_ivas_fx(
711 : const Word16 ho_circ_ptr, /* i : pointer for CNG averaging buffers Q0 */
712 : Word16 *cng_buf_cnt, /* i/o: counter for CNG store buffers Q0 */
713 : const Word16 *const cng_exc2_buf, /* i : Excitation buffer Q_exc */
714 : const Word16 *const cng_Qexc_buf, /* i : Q_exc buffer Q0 */
715 : const Word32 *const cng_brate_buf, /* i : bit rate buffer Q0 */
716 : Word32 ho_env_circ[], /* i/o: Envelope buffer Q6 */
717 : const Word16 element_mode, /* i : Element mode */
718 : const Word16 bwidth /* i : Audio bandwidth */
719 : )
720 : {
721 : Word16 i, j;
722 : Word16 Q_exc;
723 : const Word16 *exc2;
724 : Word16 fft_io[L_FFT];
725 : Word32 sp[129];
726 : Word16 *ptR, *ptI;
727 : Word32 env[NUM_ENV_CNG];
728 : Word32 L_tmp;
729 : Word16 tmp;
730 : Word16 temp_lo_fx, temp_hi_fx;
731 : Word16 exp_pow;
732 : Word16 exp1;
733 : Word16 CNG_mode;
734 : Word16 ptr;
735 : Word32 last_active_brate;
736 : #ifndef ISSUE_1836_replace_overflow_libcom
737 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
738 : Flag Overflow = 0;
739 : move32();
740 : #endif
741 : #endif
742 :
743 0 : ptr = add( sub( ho_circ_ptr, *cng_buf_cnt ), 1 );
744 0 : IF( ptr < 0 )
745 : {
746 0 : ptr = add( ptr, HO_HIST_SIZE );
747 : }
748 :
749 0 : FOR( j = 0; j < *cng_buf_cnt; j++ )
750 : {
751 0 : exc2 = &cng_exc2_buf[ptr * L_FFT];
752 0 : Q_exc = cng_Qexc_buf[ptr];
753 0 : move16();
754 0 : last_active_brate = cng_brate_buf[ptr];
755 0 : move32();
756 :
757 : /* calculate the spectrum of residual signal */
758 0 : Copy( exc2, fft_io, L_FFT );
759 :
760 0 : fft_rel_fx( fft_io, L_FFT, LOG2_L_FFT );
761 :
762 0 : ptR = &fft_io[1];
763 0 : ptI = &fft_io[L_FFT - 1];
764 0 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
765 : {
766 : /* sp[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */
767 : #ifdef ISSUE_1836_replace_overflow_libcom
768 0 : L_tmp = L_mult_sat( *ptR, *ptR ); /* 2*Q_exc+1 */
769 0 : L_tmp = L_add_sat( L_tmp, L_mult_sat( *ptI, *ptI ) ); /* 2*Q_exc+1 */
770 0 : L_tmp = L_add_sat( L_tmp, L_tmp ); /* 2*Q_exc+1 */
771 : #else
772 : L_tmp = L_mult_o( *ptR, *ptR, &Overflow ); /* 2*Q_exc+1 */
773 : L_tmp = L_add_o( L_tmp, L_mult_o( *ptI, *ptI, &Overflow ), &Overflow ); /* 2*Q_exc+1 */
774 : L_tmp = L_add_o( L_tmp, L_tmp, &Overflow ); /* 2*Q_exc+1 */
775 : #endif
776 0 : L_tmp = Mult_32_16( L_tmp, 128 ); /* 2*Q_exc+1 */
777 0 : tmp = add( add( Q_exc, Q_exc ), 1 );
778 : // To do : Saturation to be re-validated.
779 0 : sp[i] = L_shr_sat( L_tmp, sub( tmp, 6 ) );
780 0 : move32(); /* Q6 */
781 :
782 0 : ptR++;
783 0 : ptI--;
784 : }
785 :
786 0 : Copy32( sp, env, NUM_ENV_CNG );
787 :
788 0 : test();
789 0 : IF( EQ_16( element_mode, IVAS_SCE ) || EQ_16( element_mode, IVAS_CPE_DFT ) )
790 0 : {
791 0 : Word32 att_fx = 0;
792 0 : move32();
793 0 : tmp = 0;
794 0 : move16();
795 0 : apply_scale( &att_fx, bwidth, last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO );
796 0 : att_fx = L_shr( Mpy_32_16_1( att_fx, 26214 ), 3 ); /* 26214 = 0.1f in Q18 */
797 0 : att_fx = BASOP_Util_fPow( 1342177280 /* 10 in Q27 */, 4, att_fx, 8, &tmp );
798 0 : tmp = extract_h( L_shl_sat( att_fx, tmp ) ); // Fix for 3gpp #1080 (tmp set to 1.0)
799 : }
800 : ELSE
801 : {
802 :
803 0 : CNG_mode = get_cng_mode( last_active_brate );
804 :
805 : /* att = 1/pow(2,ENR_ATT_fx[CNG_mode]); */
806 0 : L_tmp = L_shl( L_deposit_l( ENR_ATT_fx[CNG_mode] ), 8 ); /* 16 */
807 0 : temp_lo_fx = L_Extract_lc( L_tmp, &temp_hi_fx );
808 :
809 0 : exp_pow = sub( 14, temp_hi_fx );
810 0 : L_tmp = Pow2( 14, temp_lo_fx ); /* Qexp_pow */
811 0 : L_tmp = L_shl( L_tmp, sub( 13, exp_pow ) ); /* Q13 */
812 0 : tmp = extract_l( L_tmp ); /* Q13 */
813 :
814 0 : exp1 = norm_s( tmp );
815 0 : tmp = shl( tmp, exp1 ); /*Q(exp1+13) */
816 0 : tmp = div_s( 16384, tmp ); /*Q(15+14-exp1-13) */
817 0 : tmp = shr( tmp, sub( 1, exp1 ) ); /* Q15 */
818 : }
819 :
820 0 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
821 : {
822 0 : env[i] = Mult_32_16( env[i], tmp );
823 0 : move32();
824 : }
825 :
826 : /* update the circular buffer of old residual envelope */
827 0 : Copy32( env, &( ho_env_circ[(ptr) *NUM_ENV_CNG] ), NUM_ENV_CNG );
828 :
829 0 : ptr = add( ptr, 1 );
830 0 : if ( EQ_16( ptr, HO_HIST_SIZE ) )
831 : {
832 0 : ptr = 0;
833 0 : move16();
834 : }
835 : }
836 :
837 0 : *cng_buf_cnt = 0;
838 0 : move16();
839 :
840 0 : return;
841 : }
842 :
843 :
844 : /*-------------------------------------------------------*
845 : * cng_params_upd_fx()
846 : *
847 : * update CNG parameters
848 : *-------------------------------------------------------*/
849 2660 : void cng_params_upd_fx(
850 : const Word16 lsp_new[], /* i : LSP aprameters Q15 */
851 : const Word16 exc2[], /* i : current enhanced excitation Q_exc */
852 : const Word16 L_frame, /* i : frame length Q0 */
853 : Word16 *ho_circ_ptr, /* i/o: pointer for CNG averaging buffers Q0 */
854 : Word32 ho_ener_circ[], /* o : energy buffer for CNG averaging Q6 */
855 : Word16 *ho_circ_size, /* i/o: size of DTX hangover history buffer for averaging Q0 */
856 : Word16 ho_lsp_circ[], /* o : old LSP buffer for CNG averaging Q15 */
857 : const Word16 Q_exc, /* i : Q value of excitation */
858 : const Word16 enc_dec_flag, /* i : Flag indicating encoder or decoder (ENC,DEC) */
859 : Word32 ho_env_circ[], /* i/o: Envelope buffer Q6 */
860 : Word16 *cng_buf_cnt, /* i/o: Counter of postponed FFT-processing instances */
861 : Word16 cng_exc2_buf[], /* i/o: Excitation buffer Q_exc */
862 : Word16 cng_Qexc_buf[], /* i/o: Q_exc buffer Q0 */
863 : Word32 cng_brate_buf[], /* i/o: last_active_brate buffer Q0 */
864 : const Word32 last_active_brate /* i : Last active bit rate Q0 */
865 : )
866 : {
867 : Word32 L_ener, L_tmp;
868 : Word16 i, j;
869 : const Word16 *pt_exc2;
870 : Word16 tmpv, maxv, scale;
871 : Word16 fft_io[L_FRAME16k];
872 : Word32 sp[129];
873 : Word16 *ptR, *ptI;
874 : Word32 env[NUM_ENV_CNG];
875 : Word16 exp1;
876 : Word16 CNG_mode;
877 : Word16 tmp;
878 : Word16 temp_lo_fx, temp_hi_fx;
879 : Word16 exp_pow;
880 : #ifndef ISSUE_1836_replace_overflow_libcom
881 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
882 : Flag Overflow = 0;
883 : move32();
884 : #endif
885 : #endif
886 :
887 :
888 : /* update the pointer to circular buffer of old LSP vectors */
889 2660 : *ho_circ_ptr = add( *ho_circ_ptr, 1 );
890 2660 : move16();
891 :
892 2660 : if ( EQ_16( *ho_circ_ptr, HO_HIST_SIZE ) )
893 : {
894 330 : *ho_circ_ptr = 0;
895 330 : move16();
896 : }
897 :
898 : /* update the circular buffer of old LSP vectors with the new LSP vector */
899 2660 : Copy( lsp_new, &( ho_lsp_circ[( *ho_circ_ptr ) * M] ), M );
900 :
901 : /* calculate the residual signal energy */
902 : /*enr = dotp( exc2, exc2, L_frame ) / L_frame; */
903 :
904 2660 : maxv = 0;
905 2660 : move16();
906 788836 : FOR( i = 0; i < L_frame; i++ )
907 : {
908 786176 : maxv = s_max( maxv, abs_s( exc2[i] ) );
909 : }
910 2660 : scale = norm_s( maxv );
911 :
912 2660 : pt_exc2 = exc2;
913 2660 : L_ener = 0;
914 2660 : move32();
915 2660 : IF( EQ_16( L_frame, L_FRAME ) )
916 : {
917 131064 : FOR( j = 0; j < 128; j++ )
918 : {
919 130048 : tmpv = shl( *pt_exc2, scale );
920 130048 : L_tmp = L_mult0( tmpv, tmpv ); /* 2*(Q_exc+scale) */
921 130048 : pt_exc2++;
922 130048 : tmpv = shl( *pt_exc2, scale );
923 : #ifdef ISSUE_1836_replace_overflow_libcom
924 130048 : L_tmp = L_mac0_sat( L_tmp, tmpv, tmpv );
925 130048 : pt_exc2++;
926 130048 : L_ener = L_add_sat( L_ener, L_shr_sat( L_tmp, 7 ) ); /* Q(2*(Q_exc+scale)+1) ,division by L_frame done here */
927 : #else
928 : L_tmp = L_mac0_o( L_tmp, tmpv, tmpv, &Overflow );
929 : pt_exc2++;
930 : L_ener = L_add_o( L_ener, L_shr_o( L_tmp, 7, &Overflow ), &Overflow ); /* Q(2*(Q_exc+scale)+1) ,division by L_frame done here */
931 : #endif
932 : }
933 : }
934 : ELSE /* L_FRAME16k */
935 : {
936 264684 : FOR( j = 0; j < 160; j++ )
937 : {
938 263040 : tmpv = shl( *pt_exc2, scale );
939 263040 : L_tmp = L_mult0( tmpv, tmpv ); /* 2*(Q_exc+scale) */
940 263040 : pt_exc2++;
941 263040 : tmpv = shl( *pt_exc2, scale );
942 : #ifdef ISSUE_1836_replace_overflow_libcom
943 263040 : L_tmp = L_mac0_sat( L_tmp, tmpv, tmpv );
944 263040 : pt_exc2++;
945 263040 : L_ener = L_add_sat( L_ener, L_shr_sat( Mult_32_16( L_tmp, 26214 /* 256/320, Q15 */ ), 7 ) ); /* Q(2*(Q_exc+scale)+15+1-16+1) ,division by L_frame done here */
946 : #else
947 : L_tmp = L_mac0_o( L_tmp, tmpv, tmpv, &Overflow );
948 : pt_exc2++;
949 : L_ener = L_add_o( L_ener, L_shr_o( Mult_32_16( L_tmp, 26214 /* 256/320, Q15 */ ), 7, &Overflow ), &Overflow ); /* Q(2*(Q_exc+scale)+15+1-16+1) ,division by L_frame done here */
950 : #endif
951 : }
952 : }
953 : #ifdef ISSUE_1836_replace_overflow_libcom
954 2660 : L_ener = L_shr_sat( L_ener, sub( shl( add( Q_exc, scale ), 1 ), 5 ) ); /* Q6 (2*(Q_exc+scale)+1-2*(Q_exc+scale)+5) */
955 : #else
956 : L_ener = L_shr_o( L_ener, sub( shl( add( Q_exc, scale ), 1 ), 5 ), &Overflow ); /* Q6 (2*(Q_exc+scale)+1-2*(Q_exc+scale)+5) */
957 : #endif
958 :
959 : /* update the circular buffer of old energies */
960 2660 : ho_ener_circ[*ho_circ_ptr] = L_ener;
961 2660 : move32();
962 :
963 2660 : IF( enc_dec_flag == ENC )
964 : {
965 : /* Store residual signal for postponed FFT-processing*/
966 0 : *cng_buf_cnt = add( *cng_buf_cnt, 1 );
967 0 : move16();
968 0 : if ( GT_16( *cng_buf_cnt, HO_HIST_SIZE ) )
969 : {
970 0 : *cng_buf_cnt = HO_HIST_SIZE;
971 0 : move16();
972 : }
973 0 : Copy( exc2, &( cng_exc2_buf[( *ho_circ_ptr ) * L_FFT] ), L_FFT );
974 0 : cng_Qexc_buf[*ho_circ_ptr] = Q_exc;
975 0 : move16();
976 0 : cng_brate_buf[*ho_circ_ptr] = last_active_brate;
977 0 : move32();
978 : }
979 : ELSE
980 : {
981 : /* calculate the spectrum of residual signal */
982 2660 : Copy( exc2, fft_io, L_frame );
983 :
984 2660 : fft_rel_fx( fft_io, L_FFT, LOG2_L_FFT );
985 :
986 2660 : ptR = &fft_io[1];
987 2660 : ptI = &fft_io[L_FFT - 1];
988 55860 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
989 : {
990 : /* sp[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */
991 : #ifdef ISSUE_1836_replace_overflow_libcom
992 53200 : L_tmp = L_mult_sat( *ptR, *ptR ); /* 2*Q_exc+1 */
993 53200 : L_tmp = L_add_sat( L_tmp, L_mult_sat( *ptI, *ptI ) ); /* 2*Q_exc+1 */
994 53200 : L_tmp = L_add_sat( L_tmp, L_tmp ); /* 2*Q_exc+1 */
995 : #else
996 : L_tmp = L_mult_o( *ptR, *ptR, &Overflow ); /* 2*Q_exc+1 */
997 : L_tmp = L_add_o( L_tmp, L_mult_o( *ptI, *ptI, &Overflow ), &Overflow ); /* 2*Q_exc+1 */
998 : L_tmp = L_add_o( L_tmp, L_tmp, &Overflow ); /* 2*Q_exc+1 */
999 : #endif
1000 53200 : L_tmp = Mult_32_16( L_tmp, 128 ); /* 2*Q_exc+1 */
1001 53200 : tmp = add( add( Q_exc, Q_exc ), 1 );
1002 53200 : sp[i] = L_shr( L_tmp, sub( tmp, 6 ) );
1003 53200 : move32(); /* Q6 */
1004 :
1005 53200 : ptR++;
1006 53200 : ptI--;
1007 : }
1008 :
1009 2660 : Copy32( sp, env, NUM_ENV_CNG );
1010 : {
1011 2660 : CNG_mode = get_cng_mode( last_active_brate );
1012 : /* att = 1/pow(2,ENR_ATT_fx[CNG_mode]); */
1013 2660 : L_tmp = L_shl( L_deposit_l( ENR_ATT_fx[CNG_mode] ), 8 ); /* 16 */
1014 2660 : temp_lo_fx = L_Extract_lc( L_tmp, &temp_hi_fx );
1015 :
1016 2660 : exp_pow = sub( 14, temp_hi_fx );
1017 2660 : L_tmp = Pow2( 14, temp_lo_fx ); /* Qexp_pow */
1018 2660 : L_tmp = L_shl( L_tmp, sub( 13, exp_pow ) ); /* Q13 */
1019 2660 : tmp = extract_l( L_tmp ); /* Q13 */
1020 :
1021 2660 : exp1 = norm_s( tmp );
1022 2660 : tmp = shl( tmp, exp1 ); /*Q(exp1+13) */
1023 2660 : tmp = div_s( 16384, tmp ); /*Q(15+14-exp1-13) */
1024 2660 : tmp = shr( tmp, sub( 1, exp1 ) ); /* Q15 */
1025 : }
1026 :
1027 55860 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
1028 : {
1029 53200 : env[i] = Mult_32_16( env[i], tmp );
1030 53200 : move32();
1031 : }
1032 :
1033 : /* update the circular buffer of old residual envelope */
1034 : /* Copy32( env, &(ho_env_circ[add(shl(*ho_circ_ptr,4),shl(*ho_circ_ptr,2))]), NUM_ENV_CNG ); */
1035 2660 : Copy32( env, &( ho_env_circ[( *ho_circ_ptr ) * NUM_ENV_CNG] ), NUM_ENV_CNG );
1036 : }
1037 2660 : *ho_circ_size = add( *ho_circ_size, 1 );
1038 2660 : move16();
1039 2660 : if ( GT_16( *ho_circ_size, HO_HIST_SIZE ) )
1040 : {
1041 2636 : *ho_circ_size = HO_HIST_SIZE;
1042 2636 : move16();
1043 : }
1044 :
1045 2660 : return;
1046 : }
1047 :
1048 173131 : void cng_params_upd_ivas_fx(
1049 : const Word16 lsp_new[], /* i : LSP aprameters Q15 */
1050 : const Word16 exc2[], /* i : current enhanced excitation Q_exc */
1051 : const Word16 L_frame, /* i : frame length Q0 */
1052 : Word16 *ho_circ_ptr, /* i/o: pointer for CNG averaging buffers Q0 */
1053 : Word32 ho_ener_circ[], /* o : energy buffer for CNG averaging Q6 */
1054 : Word16 *ho_circ_size, /* i/o: size of DTX hangover history buffer for averaging Q0 */
1055 : Word16 ho_lsp_circ[], /* o : old LSP buffer for CNG averaging Q15 */
1056 : const Word16 Q_exc, /* i : Q value of excitation */
1057 : const Word16 enc_dec_flag, /* i : Flag indicating encoder or decoder (ENC,DEC) */
1058 : Word32 ho_env_circ[], /* i/o: Envelope buffer Q(6+shift) */
1059 : Word16 *cng_buf_cnt, /* i/o: Counter of postponed FFT-processing instances */
1060 : Word16 cng_exc2_buf[], /* i/o: Excitation buffer Q_exc */
1061 : Word16 cng_Qexc_buf[], /* i/o: Q_exc buffer Q0 */
1062 : Word32 cng_brate_buf[], /* i/o: last_active_brate buffer Q0 */
1063 : const Word32 last_active_brate /* i : Last active bit rate Q0 */
1064 : ,
1065 : const Word16 element_mode, /* i : Element mode */
1066 : const Word16 bwidth /* i : Audio bandwidth */
1067 : )
1068 : {
1069 : Word32 L_ener, L_tmp;
1070 : Word16 i, j;
1071 : const Word16 *pt_exc2;
1072 : Word16 tmpv, maxv, scale;
1073 : Word16 fft_io[L_FRAME16k];
1074 : Word32 sp[129];
1075 : Word16 *ptR, *ptI;
1076 : Word32 env[NUM_ENV_CNG];
1077 : Word16 exp1;
1078 : Word16 CNG_mode;
1079 173131 : Word16 tmp = 0;
1080 173131 : move16();
1081 : Word16 temp_lo_fx, temp_hi_fx;
1082 : Word16 exp_pow;
1083 : #ifndef ISSUE_1836_replace_overflow_libcom
1084 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1085 : Flag Overflow = 0;
1086 : move32();
1087 : #endif
1088 : #endif
1089 :
1090 : /* update the pointer to circular buffer of old LSP vectors */
1091 173131 : *ho_circ_ptr = add( *ho_circ_ptr, 1 );
1092 173131 : move16();
1093 :
1094 173131 : if ( EQ_16( *ho_circ_ptr, HO_HIST_SIZE ) )
1095 : {
1096 21041 : *ho_circ_ptr = 0;
1097 21041 : move16();
1098 : }
1099 :
1100 : /* update the circular buffer of old LSP vectors with the new LSP vector */
1101 173131 : Copy( lsp_new, &( ho_lsp_circ[( *ho_circ_ptr ) * M] ), M );
1102 :
1103 : /* calculate the residual signal energy */
1104 : /*enr = dotp( exc2, exc2, L_frame ) / L_frame; */
1105 :
1106 173131 : maxv = 0;
1107 173131 : move16();
1108 50772875 : FOR( i = 0; i < L_frame; i++ )
1109 : {
1110 50599744 : maxv = s_max( maxv, abs_s( exc2[i] ) );
1111 : }
1112 173131 : scale = norm_s( maxv );
1113 :
1114 173131 : pt_exc2 = exc2;
1115 173131 : L_ener = 0;
1116 173131 : move32();
1117 173131 : IF( EQ_16( L_frame, L_FRAME ) )
1118 : {
1119 9679386 : FOR( j = 0; j < 128; j++ )
1120 : {
1121 9604352 : tmpv = shl( *pt_exc2, scale );
1122 9604352 : L_tmp = L_mult0( tmpv, tmpv ); /* 2*(Q_exc+scale) */
1123 9604352 : pt_exc2++;
1124 9604352 : tmpv = shl( *pt_exc2, scale );
1125 : #ifdef ISSUE_1836_replace_overflow_libcom
1126 9604352 : L_tmp = L_mac0_sat( L_tmp, tmpv, tmpv );
1127 9604352 : pt_exc2++;
1128 9604352 : L_ener = L_add_sat( L_ener, L_shr_sat( L_tmp, 7 ) ); /* Q(2*(Q_exc+scale)+1) ,division by L_frame done here */
1129 : #else
1130 : L_tmp = L_mac0_o( L_tmp, tmpv, tmpv, &Overflow );
1131 : pt_exc2++;
1132 : L_ener = L_add_o( L_ener, L_shr_o( L_tmp, 7, &Overflow ), &Overflow ); /* Q(2*(Q_exc+scale)+1) ,division by L_frame done here */
1133 : #endif
1134 : }
1135 : }
1136 : ELSE /* L_FRAME16k */
1137 : {
1138 15793617 : FOR( j = 0; j < 160; j++ )
1139 : {
1140 15695520 : tmpv = shl( *pt_exc2, scale );
1141 15695520 : L_tmp = L_mult0( tmpv, tmpv ); /* 2*(Q_exc+scale) */
1142 15695520 : pt_exc2++;
1143 15695520 : tmpv = shl( *pt_exc2, scale );
1144 : #ifdef ISSUE_1836_replace_overflow_libcom
1145 15695520 : L_tmp = L_mac0_sat( L_tmp, tmpv, tmpv );
1146 15695520 : pt_exc2++;
1147 15695520 : L_ener = L_add_sat( L_ener, L_shr_sat( Mult_32_16( L_tmp, 26214 /* 256/320, Q15 */ ), 7 ) ); /* Q(2*(Q_exc+scale)+15+1-16+1) ,division by L_frame done here */
1148 : #else
1149 : L_tmp = L_mac0_o( L_tmp, tmpv, tmpv, &Overflow );
1150 : pt_exc2++;
1151 : L_ener = L_add_o( L_ener, L_shr_o( Mult_32_16( L_tmp, 26214 /* 256/320, Q15 */ ), 7, &Overflow ), &Overflow ); /* Q(2*(Q_exc+scale)+15+1-16+1) ,division by L_frame done here */
1152 : #endif
1153 : }
1154 : }
1155 : #ifdef ISSUE_1836_replace_overflow_libcom
1156 173131 : L_ener = L_shr_sat( L_ener, sub( shl( add( Q_exc, scale ), 1 ), 5 ) ); /* Q6 (2*(Q_exc+scale)+1-2*(Q_exc+scale)+5) */
1157 : #else
1158 : L_ener = L_shr_o( L_ener, sub( shl( add( Q_exc, scale ), 1 ), 5 ), &Overflow ); /* Q6 (2*(Q_exc+scale)+1-2*(Q_exc+scale)+5) */
1159 : #endif
1160 :
1161 : /* update the circular buffer of old energies */
1162 173131 : ho_ener_circ[*ho_circ_ptr] = L_ener;
1163 173131 : move32();
1164 :
1165 173131 : IF( enc_dec_flag == ENC )
1166 : {
1167 : /* Store residual signal for postponed FFT-processing*/
1168 0 : *cng_buf_cnt = add( *cng_buf_cnt, 1 );
1169 0 : move16();
1170 0 : if ( GT_16( *cng_buf_cnt, HO_HIST_SIZE ) )
1171 : {
1172 0 : *cng_buf_cnt = HO_HIST_SIZE;
1173 0 : move16();
1174 : }
1175 0 : Copy( exc2, &( cng_exc2_buf[( *ho_circ_ptr ) * L_FFT] ), L_FFT );
1176 0 : cng_Qexc_buf[*ho_circ_ptr] = Q_exc;
1177 0 : move16();
1178 0 : cng_brate_buf[*ho_circ_ptr] = last_active_brate;
1179 0 : move32();
1180 : }
1181 : ELSE
1182 : {
1183 : /* calculate the spectrum of residual signal */
1184 173131 : Copy( exc2, fft_io, L_frame );
1185 :
1186 173131 : fft_rel_fx( fft_io, L_FFT, LOG2_L_FFT );
1187 :
1188 173131 : ptR = &fft_io[1];
1189 173131 : ptI = &fft_io[L_FFT - 1];
1190 3635751 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
1191 : {
1192 : /* sp[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */
1193 : #ifdef ISSUE_1836_replace_overflow_libcom
1194 3462620 : L_tmp = L_mult_sat( *ptR, *ptR ); /* 2*Q_exc+1 */
1195 3462620 : L_tmp = L_add_sat( L_tmp, L_mult_sat( *ptI, *ptI ) ); /* 2*Q_exc+1 */
1196 3462620 : L_tmp = L_add_sat( L_tmp, L_tmp ); /* 2*Q_exc+1 */
1197 3462620 : L_tmp = Mult_32_16( L_tmp, 128 ); /* 2*Q_exc+1 */
1198 3462620 : tmp = add( add( Q_exc, Q_exc ), 1 );
1199 3462620 : sp[i] = L_shr_sat( L_tmp, sub( tmp, 6 ) );
1200 : #else
1201 : L_tmp = L_mult_o( *ptR, *ptR, &Overflow ); /* 2*Q_exc+1 */
1202 : L_tmp = L_add_o( L_tmp, L_mult_o( *ptI, *ptI, &Overflow ), &Overflow ); /* 2*Q_exc+1 */
1203 : L_tmp = L_add_o( L_tmp, L_tmp, &Overflow ); /* 2*Q_exc+1 */
1204 : L_tmp = Mult_32_16( L_tmp, 128 ); /* 2*Q_exc+1 */
1205 : tmp = add( add( Q_exc, Q_exc ), 1 );
1206 : sp[i] = L_shr_o( L_tmp, sub( tmp, 6 ), &Overflow );
1207 : #endif
1208 3462620 : move32(); /* Q6 */
1209 3462620 : ptR++;
1210 3462620 : ptI--;
1211 : }
1212 :
1213 :
1214 173131 : Copy32( sp, env, NUM_ENV_CNG );
1215 173131 : Word16 shift = 0;
1216 173131 : move16();
1217 173131 : test();
1218 173131 : IF( EQ_16( element_mode, IVAS_SCE ) || EQ_16( element_mode, IVAS_CPE_DFT ) )
1219 169445 : {
1220 169445 : Word32 att_fx = 0;
1221 169445 : Word16 index = 0;
1222 169445 : move32();
1223 169445 : move16();
1224 169445 : apply_scale_ivas_fx( &att_fx, bwidth, last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO, &index );
1225 169445 : att_fx = pow_10_q23[index]; // Q23
1226 169445 : move32();
1227 169445 : tmp = extract_h( att_fx ); // Q7
1228 169445 : shift = 8;
1229 169445 : move16();
1230 : }
1231 : ELSE
1232 : {
1233 3686 : CNG_mode = get_cng_mode( last_active_brate );
1234 : /* att = 1/pow(2,ENR_ATT_fx[CNG_mode]); */
1235 3686 : L_tmp = L_shl( L_deposit_l( ENR_ATT_fx[CNG_mode] ), 8 ); /* 16 */
1236 3686 : temp_lo_fx = L_Extract_lc( L_tmp, &temp_hi_fx );
1237 :
1238 3686 : exp_pow = sub( 14, temp_hi_fx );
1239 3686 : L_tmp = Pow2( 14, temp_lo_fx ); /* Qexp_pow */
1240 3686 : L_tmp = L_shl( L_tmp, sub( 13, exp_pow ) ); /* Q13 */
1241 3686 : tmp = extract_l( L_tmp ); /* Q13 */
1242 :
1243 3686 : exp1 = norm_s( tmp );
1244 3686 : tmp = shl( tmp, exp1 ); /*Q(exp1+13) */
1245 3686 : tmp = div_s( 16384, tmp ); /*Q(15+14-exp1-13) */
1246 3686 : tmp = shr( tmp, sub( 1, exp1 ) ); /* Q15 */
1247 : }
1248 :
1249 3635751 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
1250 : {
1251 3462620 : env[i] = Mult_32_16( env[i], tmp );
1252 3462620 : move32();
1253 : }
1254 :
1255 : /* update the circular buffer of old residual envelope */
1256 : /* Copy32( env, &(ho_env_circ[add(shl(*ho_circ_ptr,4),shl(*ho_circ_ptr,2))]), NUM_ENV_CNG ); */
1257 173131 : Copy32( env, &( ho_env_circ[( *ho_circ_ptr ) * NUM_ENV_CNG] ), NUM_ENV_CNG );
1258 173131 : scale_sig32( &( ho_env_circ[( *ho_circ_ptr ) * NUM_ENV_CNG] ), NUM_ENV_CNG, shift ); // Q(6+shift)
1259 : }
1260 173131 : *ho_circ_size = add( *ho_circ_size, 1 );
1261 173131 : move16();
1262 173131 : if ( GT_16( *ho_circ_size, HO_HIST_SIZE ) )
1263 : {
1264 164204 : *ho_circ_size = HO_HIST_SIZE;
1265 164204 : move16();
1266 : }
1267 :
1268 173131 : return;
1269 : }
1270 :
1271 : /*---------------------------------------------------------------------*
1272 : * get_cng_mode()
1273 : *
1274 : *
1275 : *---------------------------------------------------------------------*/
1276 :
1277 6349 : Word16 get_cng_mode(
1278 : const Word32 last_active_brate /* i : last active bitrate */
1279 : )
1280 : {
1281 : Word16 CNG_mode;
1282 :
1283 6349 : IF( GT_32( last_active_brate, ACELP_13k20 ) )
1284 : {
1285 4065 : CNG_mode = 4;
1286 4065 : move16();
1287 : }
1288 2284 : ELSE IF( GT_32( last_active_brate, ACELP_9k60 ) )
1289 : {
1290 1720 : CNG_mode = 3;
1291 1720 : move16();
1292 : }
1293 564 : ELSE IF( GT_32( last_active_brate, ACELP_8k00 ) )
1294 : {
1295 405 : CNG_mode = 2;
1296 405 : move16();
1297 : }
1298 159 : ELSE IF( GT_32( last_active_brate, ACELP_7k20 ) )
1299 : {
1300 156 : CNG_mode = 1;
1301 156 : move16();
1302 : }
1303 : ELSE
1304 : {
1305 3 : CNG_mode = 0;
1306 3 : move16();
1307 : }
1308 :
1309 6349 : return ( CNG_mode );
1310 : }
|