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 4819 : 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 4819 : pit_max = PIT16k_MAX;
75 4819 : move16();
76 4819 : if ( EQ_16( L_frame, L_FRAME ) )
77 : {
78 1745 : pit_max = PIT_MAX;
79 1745 : move16();
80 : }
81 :
82 : /*---------------------------------------------------------------------*
83 : * Initialization of CNG energy for the first CNG frame
84 : *---------------------------------------------------------------------*/
85 :
86 4819 : IF( *first_CNG == 0 )
87 : {
88 57 : 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 57 : if ( element_mode == EVS_MONO )
105 : {
106 29 : *lp_ener = *Enew;
107 29 : move32();
108 : }
109 : }
110 :
111 : /*---------------------------------------------------------------------*
112 : * Update CNG energy
113 : *---------------------------------------------------------------------*/
114 4819 : test();
115 4819 : test();
116 4819 : 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 405 : test();
120 405 : IF( allow_cn_step == 0 && *last_allow_cn_step == 0 )
121 : {
122 390 : test();
123 390 : 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 358 : L_tmp_ener = Mult_32_16( *lp_ener, 26214 /*.8f in Q15*/ );
127 358 : 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 32 : L_tmp_ener = Mult_32_16( *lp_ener, 31130 /*.95f in Q15*/ );
133 32 : 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 4414 : IF( *last_allow_cn_step == 0 ){
147 : /**lp_ener = (float)(A2 * *Enew + (1-A2) * *lp_ener);*/
148 4344 : L_tmp_ener = Mult_32_16( *Enew, A2 );
149 4344 : 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 4819 : *lp_ener = L_max( L_tmp_ener, 1 );
165 4819 : move32(); /*To avoid / per 0*/
166 :
167 4819 : 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 4819 : 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 3582 : 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 20102 : 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 16520 : L_tmp = Mult_32_16( *lp_ener, Random( cng_ener_seed ) ); // Q6
196 16520 : L_tmp = Mult_32_16( L_tmp, GAIN_VAR ); // Q6
197 16520 : L_tmp = L_add_sat( L_tmp, *lp_ener );
198 16520 : L_tmp = L_max( L_tmp, 1 );
199 :
200 : /* enr = dot_product( exc2, exc2, L_SUBFR ) + 0.01f */
201 16520 : tmp = extract_h( Dot_product12( &exc2[i_subfr], &exc2[i_subfr], L_SUBFR, &exp ) );
202 16520 : exp = add( exp, 8 - 6 ); /* 8 from Q-4, -6 from L_SUBFR */
203 :
204 : /* enr = (float)sqrt(*lp_ener * L_SUBFR / enr) */
205 16520 : exp2 = norm_l( L_tmp );
206 16520 : tmp2 = extract_h( L_shl( L_tmp, exp2 ) );
207 16520 : exp2 = sub( 31 - 6, exp2 ); /* in Q15 (L_tmp in Q6)*/
208 :
209 16520 : exp = sub( exp, exp2 );
210 :
211 16520 : IF( GT_16( tmp, tmp2 ) )
212 : {
213 7036 : exp = add( exp, 1 );
214 : }
215 16520 : IF( GT_16( tmp, tmp2 ) )
216 : {
217 7036 : tmp = shr( tmp, 1 );
218 : }
219 16520 : tmp = div_s( tmp, tmp2 );
220 :
221 16520 : L_tmp = L_deposit_h( tmp );
222 :
223 16520 : L_tmp = Isqrt_lc( L_tmp, &exp );
224 16520 : tmp = extract_h( L_tmp );
225 :
226 16520 : exp = add( exp, 4 ); /* From Q15 to Q19 */
227 16520 : exp = add( exp, Q_exc ); /* Q_exc+ Q19 */
228 :
229 1073800 : FOR( i = 0; i < L_SUBFR; i++ )
230 : {
231 : /* exc2[i] *= enr */
232 1057280 : L_tmp = L_mult( exc2[i_subfr + i], tmp ); /* Q-4 * Q_exc+19 -> Q_exc +16 */
233 1057280 : exc2[i_subfr + i] = round_fx_sat( L_shl_sat( L_tmp, exp ) );
234 1057280 : move16();
235 : }
236 : }
237 3582 : IF( NE_16( Opt_AMR_WB, 1 ) )
238 : {
239 3582 : Copy( exc2, exc3, L_FRAME16k );
240 :
241 : /* enr1 = (float)log10( *Enew*L_frame + 0.1f ) / (float)log10( 2.0f ); */
242 3582 : exp = norm_l( *Enew );
243 3582 : L_tmp = L_shl( *Enew, exp ); /* Q(exp+6) */
244 3582 : L_tmp = Mult_32_16( L_tmp, shl( L_frame, 5 ) ); /* Q(exp+6+5-15=exp-4) */
245 3582 : L_tmp = L_shr_sat( L_tmp, sub( exp, 10 ) ); /* Q6 */
246 3582 : exp = norm_l( L_tmp );
247 3582 : fra = Log2_norm_lc( L_shl( L_tmp, exp ) );
248 3582 : exp = sub( sub( 30, exp ), 6 );
249 3582 : L_tmp = L_Comp( exp, fra );
250 : /* enr1 = round_fx(L_shl(L_tmp,8)); */ /*Q8 */
251 3582 : enr1 = L_shr( L_tmp, 10 ); /* Q6 */
252 :
253 :
254 3582 : IF( EQ_32( core_brate, SID_2k40 ) )
255 : {
256 650 : 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 650 : test();
275 650 : IF( *first_CNG == 0 && *sid_bw == 0 )
276 : {
277 0 : Copy32( env, lp_env, NUM_ENV_CNG );
278 : }
279 :
280 650 : IF( *sid_bw == 0 )
281 : {
282 0 : Copy32( env, old_env, NUM_ENV_CNG );
283 : }
284 : }
285 :
286 75222 : 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 71640 : L_tmp = Mult_32_16( lp_env[i], 29491 /*.9f in Q15*/ );
291 71640 : lp_env[i] = L_add( L_tmp, Mult_32_16( old_env[i], 3277 /*.1f in Q15*/ ) );
292 71640 : move32(); /* Q6 */
293 : }
294 :
295 : /* calculate the spectrum of random excitation signal */
296 3582 : Copy( exc2, fft_io, L_frame );
297 :
298 3582 : IF( EQ_16( L_frame, L_FRAME16k ) )
299 : {
300 2192 : 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 3582 : fft_rel_fx( fft_io, L_FFT, LOG2_L_FFT ); /* ??????? */
305 3582 : ptR = &fft_io[1];
306 3582 : ptI = &fft_io[L_FFT - 1];
307 75222 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
308 : {
309 : /* env[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */
310 71640 : L_tmp = L_mult0( *ptR, *ptR ); /* 2*Q_exc */
311 71640 : L_tmp = L_mac0_sat( L_tmp, *ptI, *ptI ); /* 2*Q_exc */
312 71640 : L_tmp = L_shr( L_tmp, 1 ); /* 2*Q_exc+6 */
313 71640 : tmp = add( Q_exc, Q_exc );
314 71640 : env[i] = L_shr_sat( L_tmp, tmp );
315 71640 : move32(); /* Q6 */
316 71640 : ptR++;
317 71640 : ptI--;
318 : }
319 :
320 75222 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
321 : {
322 : /* denv[i] = lp_env[i] + 2*(*lp_ener) - env[i]; */
323 71640 : L_tmp = L_add_sat( *lp_ener, *lp_ener );
324 71640 : denv[i] = L_sub_sat( L_add_sat( lp_env[i], L_tmp ), env[i] );
325 71640 : move32(); /* Q6 */
326 :
327 71640 : if ( denv[i] < 0 )
328 : {
329 11458 : denv[i] = 0;
330 11458 : move32();
331 : }
332 : }
333 3582 : set32_fx( itmp, 0, NUM_ENV_CNG );
334 :
335 3582 : set16_fx( fft_io, 0, L_FFT );
336 3582 : ptR = &fft_io[1];
337 3582 : ptI = &fft_io[L_FFT - 1];
338 75222 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
339 : {
340 : /* *ptR = own_random( cng_ener_seed1 ); */
341 : /* *ptI = own_random( cng_ener_seed1 ); */
342 71640 : *ptR = Random( cng_ener_seed1 );
343 71640 : move16();
344 71640 : *ptI = Random( cng_ener_seed1 );
345 71640 : move16();
346 :
347 : /* env[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */
348 71640 : L_tmp = L_mult0( *ptR, *ptR ); /* Q0 */
349 71640 : L_tmp = L_mac0( L_tmp, *ptI, *ptI ); /* Q0 */
350 71640 : env[i] = L_shr( L_tmp, 1 );
351 71640 : move32(); /* Q6 */
352 71640 : ptR++;
353 71640 : ptI--;
354 : }
355 :
356 75222 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
357 : {
358 : /* itmp[i] += own_random( cng_ener_seed1 )*denv[i]*0.000011f + denv[i]; */
359 71640 : L_tmp = Mult_32_16( denv[i], Random( cng_ener_seed1 ) ); // Q6
360 71640 : L_tmp = Mult_32_16( L_tmp, GAIN_VAR ); // Q6
361 71640 : L_tmp = L_add_sat( L_tmp, denv[i] );
362 71640 : itmp[i] = L_add_sat( L_tmp, itmp[i] );
363 71640 : move32(); /* Q6 */
364 :
365 71640 : if ( itmp[i] < 0 )
366 : {
367 0 : itmp[i] = 0;
368 0 : move32();
369 : }
370 : }
371 3582 : ptR = &fft_io[1];
372 3582 : ptI = &fft_io[L_FFT - 1];
373 75222 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
374 : {
375 : /* *ptR *= sqrt(itmp[i]/env[i]); */
376 : /* *ptI *= sqrt(itmp[i]/env[i]); */
377 71640 : L_tmp = L_max( 1, itmp[i] ); /*Q6*/
378 71640 : exp = norm_l( L_tmp );
379 71640 : tmp = extract_h( L_shl( L_tmp, exp ) );
380 71640 : exp = sub( 31 - 6, exp ); /* in Q15 (L_tmp in Q6)*/
381 :
382 71640 : exp2 = norm_l( env[i] );
383 71640 : tmp2 = extract_h( L_shl( env[i], exp2 ) );
384 71640 : exp2 = sub( 31 - 6, exp2 ); /* in Q15 (L_tmp in Q6)*/
385 :
386 71640 : exp = sub( exp2, exp ); /* Denormalize and substract */
387 71640 : IF( GT_16( tmp2, tmp ) )
388 : {
389 43423 : exp = add( exp, 1 );
390 : }
391 71640 : IF( GT_16( tmp2, tmp ) )
392 : {
393 43423 : tmp2 = shr( tmp2, 1 );
394 : }
395 71640 : tmp = div_s( tmp2, tmp );
396 71640 : L_tmp = L_deposit_h( tmp );
397 71640 : L_tmp = Isqrt_lc( L_tmp, &exp ); /*Q(31-exp)*/
398 :
399 71640 : L_tmp2 = Mult_32_16( L_tmp, *ptR ); /*Q(16-exp)*/
400 71640 : *ptR = extract_h( L_shl_sat( L_tmp2, add( exp, Q_exc ) ) ); /*Q_exc*/
401 71640 : move16();
402 71640 : L_tmp2 = Mult_32_16( L_tmp, *ptI ); /*Q(16-exp)*/
403 71640 : *ptI = extract_h( L_shl_sat( L_tmp2, add( exp, Q_exc ) ) ); /*Q_exc*/
404 71640 : move16();
405 71640 : ptR++;
406 71640 : ptI--;
407 : }
408 :
409 3582 : ifft_rel_fx( fft_io, L_FFT, LOG2_L_FFT );
410 :
411 3582 : IF( EQ_16( L_frame, L_FRAME16k ) )
412 : {
413 2192 : 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 3582 : enr1 = 1;
419 3582 : move32();
420 3582 : pt_fft_io = fft_io;
421 3582 : IF( EQ_16( L_frame, L_FRAME ) )
422 : {
423 179310 : FOR( j = 0; j < 128; j++ )
424 : {
425 177920 : L_tmp = L_mult0( *pt_fft_io, *pt_fft_io );
426 177920 : pt_fft_io++;
427 177920 : L_tmp = L_mac0( L_tmp, *pt_fft_io, *pt_fft_io ); /* 2*(Q_exc) */
428 177920 : pt_fft_io++;
429 177920 : 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 352912 : FOR( j = 0; j < 160; j++ )
435 : {
436 350720 : L_tmp = L_mult0( *pt_fft_io, *pt_fft_io );
437 350720 : pt_fft_io++;
438 350720 : L_tmp = L_mac0( L_tmp, *pt_fft_io, *pt_fft_io ); /* 2*(Q_exc) */
439 350720 : pt_fft_io++;
440 350720 : 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 3582 : enr1 = L_shr( enr1, sub( add( Q_exc, Q_exc ), 5 ) ); /*Q6*/
444 :
445 : /* add time domain randomization */
446 20102 : FOR( i_subfr = 0; i_subfr < L_frame; i_subfr += L_SUBFR )
447 : {
448 :
449 16520 : L_tmp = Mult_32_16( enr1, Random( cng_ener_seed1 ) );
450 16520 : L_tmp = Mult_32_16( L_tmp, GAIN_VAR );
451 16520 : L_tmp = L_add( L_tmp, enr1 );
452 16520 : L_tmp = L_max( L_tmp, 1 );
453 :
454 : /* enr = dot_product( fft_io, fft_io, L_SUBFR ) + 0.01f */
455 16520 : tmp = extract_h( Dot_product12( &fft_io[i_subfr], &fft_io[i_subfr], L_SUBFR, &exp ) );
456 16520 : 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 16520 : exp2 = norm_l( L_tmp );
460 16520 : tmp2 = extract_h( L_shl( L_tmp, exp2 ) );
461 16520 : exp2 = sub( 31 - 6, exp2 ); /* in Q15 (L_tmp in Q6)*/
462 :
463 16520 : exp = sub( exp, exp2 );
464 :
465 16520 : IF( GT_16( tmp, tmp2 ) )
466 : {
467 8835 : exp = add( exp, 1 );
468 : }
469 16520 : IF( GT_16( tmp, tmp2 ) )
470 : {
471 8835 : tmp = shr( tmp, 1 );
472 : }
473 16520 : tmp = div_s( tmp, tmp2 );
474 :
475 16520 : L_tmp = L_deposit_h( tmp );
476 16520 : L_tmp = Isqrt_lc( L_tmp, &exp ); /*Q(31-exp)*/
477 16520 : test();
478 16520 : test();
479 16520 : test();
480 16520 : 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 1437 : IF( GT_32( L_tmp, L_shl_sat( 1, sub( 31, exp ) ) ) )
483 : {
484 790 : L_tmp = L_shl( 1, sub( 31, exp ) );
485 : }
486 : }
487 :
488 16520 : tmp = extract_h( L_tmp );
489 1073800 : FOR( i = 0; i < L_SUBFR; i++ )
490 : {
491 : /* fft_io[i] *= enr */
492 1057280 : L_tmp = L_mult( fft_io[i_subfr + i], tmp ); /* Q_exc + 16 - exp */
493 1057280 : fft_io[i_subfr + i] = round_fx( L_shl( L_tmp, exp ) ); /*Q_exc*/
494 1057280 : move16();
495 : }
496 : }
497 :
498 1060862 : FOR( i = 0; i < L_frame; i++ )
499 : {
500 : /* fft_io[i] = 0.75f*fft_io[i] + exc2[i];*/
501 1057280 : tmp = mult( fft_io[i], 24576 /*.75f in Q15*/ );
502 1057280 : fft_io[i] = add_sat( tmp, exc2[i] );
503 1057280 : move16(); /*Q_exc*/
504 : }
505 :
506 : /* enr = (dotp( fft_io, fft_io, L_frame ) / L_frame) + 0.01f */
507 :
508 3582 : L_tmp2 = 1;
509 3582 : move32();
510 3582 : pt_fft_io = fft_io;
511 3582 : IF( EQ_16( L_frame, L_FRAME ) )
512 : {
513 179310 : FOR( j = 0; j < 128; j++ )
514 : {
515 177920 : L_tmp = L_mult0( *pt_fft_io, *pt_fft_io );
516 177920 : pt_fft_io++;
517 177920 : L_tmp = L_mac0_sat( L_tmp, *pt_fft_io, *pt_fft_io ); /* 2*(Q_exc) */
518 177920 : pt_fft_io++;
519 177920 : 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 352912 : FOR( j = 0; j < 160; j++ )
525 : {
526 350720 : L_tmp = L_mult0( *pt_fft_io, *pt_fft_io );
527 350720 : pt_fft_io++;
528 350720 : L_tmp = L_mac0_sat( L_tmp, *pt_fft_io, *pt_fft_io ); /* 2*(Q_exc) */
529 350720 : pt_fft_io++;
530 350720 : 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 3582 : 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 3582 : L_tmp = L_max( 1, *lp_ener ); /*Q6*/
539 3582 : exp = norm_l( L_tmp );
540 3582 : tmp = extract_h( L_shl( L_tmp, exp ) );
541 3582 : exp = sub( 31 - 6, exp ); /* in Q15 (L_tmp in Q6)*/
542 :
543 3582 : exp2 = norm_l( L_tmp2 );
544 3582 : tmp2 = extract_h( L_shl( L_tmp2, exp2 ) );
545 3582 : exp2 = sub( 31 - 6, exp2 ); /* in Q15 (L_tmp in Q6)*/
546 :
547 3582 : exp = sub( exp2, exp ); /* Denormalize and substract */
548 3582 : IF( GT_16( tmp2, tmp ) )
549 : {
550 1874 : exp = add( exp, 1 );
551 : }
552 3582 : IF( GT_16( tmp2, tmp ) )
553 : {
554 1874 : tmp2 = shr( tmp2, 1 );
555 : }
556 3582 : tmp = div_s( tmp2, tmp );
557 3582 : L_tmp = L_deposit_h( tmp );
558 3582 : L_tmp = Isqrt_lc( L_tmp, &exp ); /*Q(31-exp)*/
559 :
560 3582 : ftmp = extract_h( L_shl_sat( L_tmp, exp ) ); /* Q15 */
561 1060862 : FOR( i = 0; i < L_frame; i++ )
562 : {
563 : /* fft_io[i] *= ftmp;*/
564 1057280 : fft_io[i] = mult( fft_io[i], ftmp );
565 1057280 : move16(); /* Q_exc */
566 : }
567 3582 : Copy( fft_io, exc2, L_frame );
568 : }
569 3582 : IF( NE_16( Opt_AMR_WB, 1 ) )
570 : {
571 3582 : Copy( exc3, exc, L_frame );
572 : }
573 : ELSE
574 : {
575 0 : Copy( exc2, exc, L_frame );
576 : }
577 :
578 3582 : IF( EQ_16( L_frame, L_FRAME ) )
579 : {
580 1390 : interp_code_5over2_fx( exc2, bwe_exc, L_FRAME );
581 : }
582 : ELSE
583 : {
584 2192 : interp_code_4over2_fx( exc2, bwe_exc, L_frame );
585 : }
586 3582 : 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 : #ifdef IVAS_CODE_CNG_COM
602 : ,
603 : const Word16 element_mode, /* i : Element mode */
604 : const Word16 bwidth /* i : Audio bandwidth */
605 : #endif
606 : )
607 : {
608 : Word16 i, j;
609 : Word16 Q_exc;
610 : const Word16 *exc2;
611 : Word16 fft_io[L_FFT];
612 : Word32 sp[129];
613 : Word16 *ptR, *ptI;
614 : Word32 env[NUM_ENV_CNG];
615 : Word32 L_tmp;
616 : Word16 tmp;
617 : Word16 temp_lo_fx, temp_hi_fx;
618 : Word16 exp_pow;
619 : Word16 exp1;
620 : Word16 CNG_mode;
621 : Word16 ptr;
622 : Word32 last_active_brate;
623 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
624 0 : Flag Overflow = 0;
625 0 : move32();
626 : #endif
627 :
628 0 : ptr = add( sub( ho_circ_ptr, *cng_buf_cnt ), 1 );
629 0 : IF( ptr < 0 )
630 : {
631 0 : ptr = add( ptr, HO_HIST_SIZE );
632 : }
633 :
634 0 : FOR( j = 0; j < *cng_buf_cnt; j++ )
635 : {
636 0 : exc2 = &cng_exc2_buf[ptr * L_FFT];
637 0 : Q_exc = cng_Qexc_buf[ptr];
638 0 : move16();
639 0 : last_active_brate = cng_brate_buf[ptr];
640 0 : move32();
641 :
642 : /* calculate the spectrum of residual signal */
643 0 : Copy( exc2, fft_io, L_FFT );
644 :
645 0 : fft_rel_fx( fft_io, L_FFT, LOG2_L_FFT );
646 :
647 0 : ptR = &fft_io[1];
648 0 : ptI = &fft_io[L_FFT - 1];
649 0 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
650 : {
651 : /* sp[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */
652 0 : L_tmp = L_mult_o( *ptR, *ptR, &Overflow ); /* 2*Q_exc+1 */
653 0 : L_tmp = L_add_o( L_tmp, L_mult_o( *ptI, *ptI, &Overflow ), &Overflow ); /* 2*Q_exc+1 */
654 0 : L_tmp = L_add_o( L_tmp, L_tmp, &Overflow ); /* 2*Q_exc+1 */
655 0 : L_tmp = Mult_32_16( L_tmp, 128 ); /* 2*Q_exc+1 */
656 0 : tmp = add( add( Q_exc, Q_exc ), 1 );
657 0 : sp[i] = L_shr( L_tmp, sub( tmp, 6 ) );
658 0 : move32(); /* Q6 */
659 :
660 0 : ptR++;
661 0 : ptI--;
662 : }
663 :
664 0 : Copy32( sp, env, NUM_ENV_CNG );
665 : #ifdef IVAS_CODE_CNG_COM
666 : if ( element_mode == IVAS_SCE || element_mode == IVAS_CPE_DFT )
667 : {
668 : att = 0.0f;
669 : apply_scale( &att, bwidth, last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO );
670 : att = powf( 10, att / 10.0f );
671 : }
672 : else
673 : #endif
674 : {
675 :
676 0 : CNG_mode = get_cng_mode( last_active_brate );
677 :
678 : /* att = 1/pow(2,ENR_ATT_fx[CNG_mode]); */
679 0 : L_tmp = L_shl( L_deposit_l( ENR_ATT_fx[CNG_mode] ), 8 ); /* 16 */
680 0 : temp_lo_fx = L_Extract_lc( L_tmp, &temp_hi_fx );
681 :
682 0 : exp_pow = sub( 14, temp_hi_fx );
683 0 : L_tmp = Pow2( 14, temp_lo_fx ); /* Qexp_pow */
684 0 : L_tmp = L_shl( L_tmp, sub( 13, exp_pow ) ); /* Q13 */
685 0 : tmp = extract_l( L_tmp ); /* Q13 */
686 :
687 0 : exp1 = norm_s( tmp );
688 0 : tmp = shl( tmp, exp1 ); /*Q(exp1+13) */
689 0 : tmp = div_s( 16384, tmp ); /*Q(15+14-exp1-13) */
690 0 : tmp = shr( tmp, sub( 1, exp1 ) ); /* Q15 */
691 : }
692 :
693 0 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
694 : {
695 0 : env[i] = Mult_32_16( env[i], tmp );
696 0 : move32();
697 : }
698 :
699 : /* update the circular buffer of old residual envelope */
700 0 : Copy32( env, &( ho_env_circ[(ptr) *NUM_ENV_CNG] ), NUM_ENV_CNG );
701 :
702 0 : ptr = add( ptr, 1 );
703 0 : if ( EQ_16( ptr, HO_HIST_SIZE ) )
704 : {
705 0 : ptr = 0;
706 0 : move16();
707 : }
708 : }
709 :
710 0 : *cng_buf_cnt = 0;
711 0 : move16();
712 :
713 0 : return;
714 : }
715 :
716 2441 : void cng_params_postupd_ivas_fx(
717 : const Word16 ho_circ_ptr, /* i : pointer for CNG averaging buffers Q0 */
718 : Word16 *cng_buf_cnt, /* i/o: counter for CNG store buffers Q0 */
719 : const Word16 *const cng_exc2_buf, /* i : Excitation buffer Q_exc */
720 : const Word16 *const cng_Qexc_buf, /* i : Q_exc buffer Q0 */
721 : const Word32 *const cng_brate_buf, /* i : bit rate buffer Q0 */
722 : Word32 ho_env_circ[], /* i/o: Envelope buffer Q6 */
723 : const Word16 element_mode, /* i : Element mode */
724 : const Word16 bwidth /* i : Audio bandwidth */
725 : )
726 : {
727 : Word16 i, j;
728 : Word16 Q_exc;
729 : const Word16 *exc2;
730 : Word16 fft_io[L_FFT];
731 : Word32 sp[129];
732 : Word16 *ptR, *ptI;
733 : Word32 env[NUM_ENV_CNG];
734 : Word32 L_tmp;
735 : Word16 tmp;
736 : Word16 temp_lo_fx, temp_hi_fx;
737 : Word16 exp_pow;
738 : Word16 exp1;
739 : Word16 CNG_mode;
740 : Word16 ptr;
741 : Word32 last_active_brate;
742 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
743 2441 : Flag Overflow = 0;
744 2441 : move32();
745 : #endif
746 :
747 2441 : ptr = add( sub( ho_circ_ptr, *cng_buf_cnt ), 1 );
748 2441 : IF( ptr < 0 )
749 : {
750 89 : ptr = add( ptr, HO_HIST_SIZE );
751 : }
752 :
753 3267 : FOR( j = 0; j < *cng_buf_cnt; j++ )
754 : {
755 826 : exc2 = &cng_exc2_buf[ptr * L_FFT];
756 826 : Q_exc = cng_Qexc_buf[ptr];
757 826 : move16();
758 826 : last_active_brate = cng_brate_buf[ptr];
759 826 : move32();
760 :
761 : /* calculate the spectrum of residual signal */
762 826 : Copy( exc2, fft_io, L_FFT );
763 :
764 826 : fft_rel_fx( fft_io, L_FFT, LOG2_L_FFT );
765 :
766 826 : ptR = &fft_io[1];
767 826 : ptI = &fft_io[L_FFT - 1];
768 17346 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
769 : {
770 : /* sp[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */
771 16520 : L_tmp = L_mult_o( *ptR, *ptR, &Overflow ); /* 2*Q_exc+1 */
772 16520 : L_tmp = L_add_o( L_tmp, L_mult_o( *ptI, *ptI, &Overflow ), &Overflow ); /* 2*Q_exc+1 */
773 16520 : L_tmp = L_add_o( L_tmp, L_tmp, &Overflow ); /* 2*Q_exc+1 */
774 16520 : L_tmp = Mult_32_16( L_tmp, 128 ); /* 2*Q_exc+1 */
775 16520 : tmp = add( add( Q_exc, Q_exc ), 1 );
776 : // To do : Saturation to be re-validated.
777 16520 : sp[i] = L_shr_sat( L_tmp, sub( tmp, 6 ) );
778 16520 : move32(); /* Q6 */
779 :
780 16520 : ptR++;
781 16520 : ptI--;
782 : }
783 :
784 826 : Copy32( sp, env, NUM_ENV_CNG );
785 :
786 826 : test();
787 826 : IF( EQ_16( element_mode, IVAS_SCE ) || EQ_16( element_mode, IVAS_CPE_DFT ) )
788 826 : {
789 826 : Word32 att_fx = 0;
790 826 : move32();
791 826 : tmp = 0;
792 826 : move16();
793 826 : apply_scale( &att_fx, bwidth, last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO );
794 826 : att_fx = L_shr( Mpy_32_16_1( att_fx, 26214 ), 3 ); /* 26214 = 0.1f in Q18 */
795 826 : att_fx = BASOP_Util_fPow( 1342177280 /* 10 in Q27 */, 4, att_fx, 8, &tmp );
796 826 : tmp = extract_h( L_shl_sat( att_fx, tmp ) ); // Fix for 3gpp #1080 (tmp set to 1.0)
797 : }
798 : ELSE
799 : {
800 :
801 0 : CNG_mode = get_cng_mode( last_active_brate );
802 :
803 : /* att = 1/pow(2,ENR_ATT_fx[CNG_mode]); */
804 0 : L_tmp = L_shl( L_deposit_l( ENR_ATT_fx[CNG_mode] ), 8 ); /* 16 */
805 0 : temp_lo_fx = L_Extract_lc( L_tmp, &temp_hi_fx );
806 :
807 0 : exp_pow = sub( 14, temp_hi_fx );
808 0 : L_tmp = Pow2( 14, temp_lo_fx ); /* Qexp_pow */
809 0 : L_tmp = L_shl( L_tmp, sub( 13, exp_pow ) ); /* Q13 */
810 0 : tmp = extract_l( L_tmp ); /* Q13 */
811 :
812 0 : exp1 = norm_s( tmp );
813 0 : tmp = shl( tmp, exp1 ); /*Q(exp1+13) */
814 0 : tmp = div_s( 16384, tmp ); /*Q(15+14-exp1-13) */
815 0 : tmp = shr( tmp, sub( 1, exp1 ) ); /* Q15 */
816 : }
817 :
818 17346 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
819 : {
820 16520 : env[i] = Mult_32_16( env[i], tmp );
821 16520 : move32();
822 : }
823 :
824 : /* update the circular buffer of old residual envelope */
825 826 : Copy32( env, &( ho_env_circ[(ptr) *NUM_ENV_CNG] ), NUM_ENV_CNG );
826 :
827 826 : ptr = add( ptr, 1 );
828 826 : if ( EQ_16( ptr, HO_HIST_SIZE ) )
829 : {
830 107 : ptr = 0;
831 107 : move16();
832 : }
833 : }
834 :
835 2441 : *cng_buf_cnt = 0;
836 2441 : move16();
837 :
838 2441 : return;
839 : }
840 :
841 :
842 : /*-------------------------------------------------------*
843 : * cng_params_upd_fx()
844 : *
845 : * update CNG parameters
846 : *-------------------------------------------------------*/
847 2671 : void cng_params_upd_fx(
848 : const Word16 lsp_new[], /* i : LSP aprameters Q15 */
849 : const Word16 exc2[], /* i : current enhanced excitation Q_exc */
850 : const Word16 L_frame, /* i : frame length Q0 */
851 : Word16 *ho_circ_ptr, /* i/o: pointer for CNG averaging buffers Q0 */
852 : Word32 ho_ener_circ[], /* o : energy buffer for CNG averaging Q6 */
853 : Word16 *ho_circ_size, /* i/o: size of DTX hangover history buffer for averaging Q0 */
854 : Word16 ho_lsp_circ[], /* o : old LSP buffer for CNG averaging Q15 */
855 : const Word16 Q_exc, /* i : Q value of excitation */
856 : const Word16 enc_dec_flag, /* i : Flag indicating encoder or decoder (ENC,DEC) */
857 : Word32 ho_env_circ[], /* i/o: Envelope buffer Q6 */
858 : Word16 *cng_buf_cnt, /* i/o: Counter of postponed FFT-processing instances */
859 : Word16 cng_exc2_buf[], /* i/o: Excitation buffer Q_exc */
860 : Word16 cng_Qexc_buf[], /* i/o: Q_exc buffer Q0 */
861 : Word32 cng_brate_buf[], /* i/o: last_active_brate buffer Q0 */
862 : const Word32 last_active_brate /* i : Last active bit rate Q0 */
863 : #ifdef IVAS_CODE_CNG_COM
864 : ,
865 : const Word16 element_mode, /* i : Element mode */
866 : const Word16 bwidth /* i : Audio bandwidth */
867 : #endif
868 : )
869 : {
870 : Word32 L_ener, L_tmp;
871 : Word16 i, j;
872 : const Word16 *pt_exc2;
873 : Word16 tmpv, maxv, scale;
874 : Word16 fft_io[L_FRAME16k];
875 : Word32 sp[129];
876 : Word16 *ptR, *ptI;
877 : Word32 env[NUM_ENV_CNG];
878 : Word16 exp1;
879 : Word16 CNG_mode;
880 : Word16 tmp;
881 : Word16 temp_lo_fx, temp_hi_fx;
882 : Word16 exp_pow;
883 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
884 2671 : Flag Overflow = 0;
885 2671 : move32();
886 : #endif
887 :
888 :
889 : /* update the pointer to circular buffer of old LSP vectors */
890 2671 : *ho_circ_ptr = add( *ho_circ_ptr, 1 );
891 2671 : move16();
892 :
893 2671 : if ( EQ_16( *ho_circ_ptr, HO_HIST_SIZE ) )
894 : {
895 332 : *ho_circ_ptr = 0;
896 332 : move16();
897 : }
898 :
899 : /* update the circular buffer of old LSP vectors with the new LSP vector */
900 2671 : Copy( lsp_new, &( ho_lsp_circ[( *ho_circ_ptr ) * M] ), M );
901 :
902 : /* calculate the residual signal energy */
903 : /*enr = dotp( exc2, exc2, L_frame ) / L_frame; */
904 :
905 2671 : maxv = 0;
906 2671 : move16();
907 792239 : FOR( i = 0; i < L_frame; i++ )
908 : {
909 789568 : maxv = s_max( maxv, abs_s( exc2[i] ) );
910 : }
911 2671 : scale = norm_s( maxv );
912 :
913 2671 : pt_exc2 = exc2;
914 2671 : L_ener = 0;
915 2671 : move32();
916 2671 : IF( EQ_16( L_frame, L_FRAME ) )
917 : {
918 131322 : FOR( j = 0; j < 128; j++ )
919 : {
920 130304 : tmpv = shl( *pt_exc2, scale );
921 130304 : L_tmp = L_mult0( tmpv, tmpv ); /* 2*(Q_exc+scale) */
922 130304 : pt_exc2++;
923 130304 : tmpv = shl( *pt_exc2, scale );
924 130304 : L_tmp = L_mac0_o( L_tmp, tmpv, tmpv, &Overflow );
925 130304 : pt_exc2++;
926 130304 : 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 */
927 : }
928 : }
929 : ELSE /* L_FRAME16k */
930 : {
931 266133 : FOR( j = 0; j < 160; j++ )
932 : {
933 264480 : tmpv = shl( *pt_exc2, scale );
934 264480 : L_tmp = L_mult0( tmpv, tmpv ); /* 2*(Q_exc+scale) */
935 264480 : pt_exc2++;
936 264480 : tmpv = shl( *pt_exc2, scale );
937 264480 : L_tmp = L_mac0_o( L_tmp, tmpv, tmpv, &Overflow );
938 264480 : pt_exc2++;
939 264480 : 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 */
940 : }
941 : }
942 2671 : 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) */
943 :
944 : /* update the circular buffer of old energies */
945 2671 : ho_ener_circ[*ho_circ_ptr] = L_ener;
946 2671 : move32();
947 :
948 2671 : IF( enc_dec_flag == ENC )
949 : {
950 : /* Store residual signal for postponed FFT-processing*/
951 0 : *cng_buf_cnt = add( *cng_buf_cnt, 1 );
952 0 : move16();
953 0 : if ( GT_16( *cng_buf_cnt, HO_HIST_SIZE ) )
954 : {
955 0 : *cng_buf_cnt = HO_HIST_SIZE;
956 0 : move16();
957 : }
958 0 : Copy( exc2, &( cng_exc2_buf[( *ho_circ_ptr ) * L_FFT] ), L_FFT );
959 0 : cng_Qexc_buf[*ho_circ_ptr] = Q_exc;
960 0 : move16();
961 0 : cng_brate_buf[*ho_circ_ptr] = last_active_brate;
962 0 : move32();
963 : }
964 : ELSE
965 : {
966 : /* calculate the spectrum of residual signal */
967 2671 : Copy( exc2, fft_io, L_frame );
968 :
969 2671 : fft_rel_fx( fft_io, L_FFT, LOG2_L_FFT );
970 :
971 2671 : ptR = &fft_io[1];
972 2671 : ptI = &fft_io[L_FFT - 1];
973 56091 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
974 : {
975 : /* sp[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */
976 53420 : L_tmp = L_mult_o( *ptR, *ptR, &Overflow ); /* 2*Q_exc+1 */
977 53420 : L_tmp = L_add_o( L_tmp, L_mult_o( *ptI, *ptI, &Overflow ), &Overflow ); /* 2*Q_exc+1 */
978 53420 : L_tmp = L_add_o( L_tmp, L_tmp, &Overflow ); /* 2*Q_exc+1 */
979 53420 : L_tmp = Mult_32_16( L_tmp, 128 ); /* 2*Q_exc+1 */
980 53420 : tmp = add( add( Q_exc, Q_exc ), 1 );
981 53420 : sp[i] = L_shr( L_tmp, sub( tmp, 6 ) );
982 53420 : move32(); /* Q6 */
983 :
984 53420 : ptR++;
985 53420 : ptI--;
986 : }
987 :
988 2671 : Copy32( sp, env, NUM_ENV_CNG );
989 : #ifdef IVAS_CODE_CNG_COM
990 : if ( element_mode == IVAS_SCE || element_mode == IVAS_CPE_DFT )
991 : {
992 : att = 0.0f;
993 : apply_scale( &att, bwidth, last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO );
994 : att = powf( 10, att / 10.0f );
995 : }
996 : else
997 : #endif
998 : {
999 2671 : CNG_mode = get_cng_mode( last_active_brate );
1000 : /* att = 1/pow(2,ENR_ATT_fx[CNG_mode]); */
1001 2671 : L_tmp = L_shl( L_deposit_l( ENR_ATT_fx[CNG_mode] ), 8 ); /* 16 */
1002 2671 : temp_lo_fx = L_Extract_lc( L_tmp, &temp_hi_fx );
1003 :
1004 2671 : exp_pow = sub( 14, temp_hi_fx );
1005 2671 : L_tmp = Pow2( 14, temp_lo_fx ); /* Qexp_pow */
1006 2671 : L_tmp = L_shl( L_tmp, sub( 13, exp_pow ) ); /* Q13 */
1007 2671 : tmp = extract_l( L_tmp ); /* Q13 */
1008 :
1009 2671 : exp1 = norm_s( tmp );
1010 2671 : tmp = shl( tmp, exp1 ); /*Q(exp1+13) */
1011 2671 : tmp = div_s( 16384, tmp ); /*Q(15+14-exp1-13) */
1012 2671 : tmp = shr( tmp, sub( 1, exp1 ) ); /* Q15 */
1013 : }
1014 :
1015 56091 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
1016 : {
1017 53420 : env[i] = Mult_32_16( env[i], tmp );
1018 53420 : move32();
1019 : }
1020 :
1021 : /* update the circular buffer of old residual envelope */
1022 : /* Copy32( env, &(ho_env_circ[add(shl(*ho_circ_ptr,4),shl(*ho_circ_ptr,2))]), NUM_ENV_CNG ); */
1023 2671 : Copy32( env, &( ho_env_circ[( *ho_circ_ptr ) * NUM_ENV_CNG] ), NUM_ENV_CNG );
1024 : }
1025 2671 : *ho_circ_size = add( *ho_circ_size, 1 );
1026 2671 : move16();
1027 2671 : if ( GT_16( *ho_circ_size, HO_HIST_SIZE ) )
1028 : {
1029 2647 : *ho_circ_size = HO_HIST_SIZE;
1030 2647 : move16();
1031 : }
1032 :
1033 2671 : return;
1034 : }
1035 :
1036 203381 : void cng_params_upd_ivas_fx(
1037 : const Word16 lsp_new[], /* i : LSP aprameters Q15 */
1038 : const Word16 exc2[], /* i : current enhanced excitation Q_exc */
1039 : const Word16 L_frame, /* i : frame length Q0 */
1040 : Word16 *ho_circ_ptr, /* i/o: pointer for CNG averaging buffers Q0 */
1041 : Word32 ho_ener_circ[], /* o : energy buffer for CNG averaging Q6 */
1042 : Word16 *ho_circ_size, /* i/o: size of DTX hangover history buffer for averaging Q0 */
1043 : Word16 ho_lsp_circ[], /* o : old LSP buffer for CNG averaging Q15 */
1044 : const Word16 Q_exc, /* i : Q value of excitation */
1045 : const Word16 enc_dec_flag, /* i : Flag indicating encoder or decoder (ENC,DEC) */
1046 : Word32 ho_env_circ[], /* i/o: Envelope buffer Q(6+shift) */
1047 : Word16 *cng_buf_cnt, /* i/o: Counter of postponed FFT-processing instances */
1048 : Word16 cng_exc2_buf[], /* i/o: Excitation buffer Q_exc */
1049 : Word16 cng_Qexc_buf[], /* i/o: Q_exc buffer Q0 */
1050 : Word32 cng_brate_buf[], /* i/o: last_active_brate buffer Q0 */
1051 : const Word32 last_active_brate /* i : Last active bit rate Q0 */
1052 : ,
1053 : const Word16 element_mode, /* i : Element mode */
1054 : const Word16 bwidth /* i : Audio bandwidth */
1055 : )
1056 : {
1057 : Word32 L_ener, L_tmp;
1058 : Word16 i, j;
1059 : const Word16 *pt_exc2;
1060 : Word16 tmpv, maxv, scale;
1061 : Word16 fft_io[L_FRAME16k];
1062 : Word32 sp[129];
1063 : Word16 *ptR, *ptI;
1064 : Word32 env[NUM_ENV_CNG];
1065 : Word16 exp1;
1066 : Word16 CNG_mode;
1067 203381 : Word16 tmp = 0;
1068 203381 : move16();
1069 : Word16 temp_lo_fx, temp_hi_fx;
1070 : Word16 exp_pow;
1071 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1072 203381 : Flag Overflow = 0;
1073 203381 : move32();
1074 : #endif
1075 :
1076 : /* update the pointer to circular buffer of old LSP vectors */
1077 203381 : *ho_circ_ptr = add( *ho_circ_ptr, 1 );
1078 203381 : move16();
1079 :
1080 203381 : if ( EQ_16( *ho_circ_ptr, HO_HIST_SIZE ) )
1081 : {
1082 24782 : *ho_circ_ptr = 0;
1083 24782 : move16();
1084 : }
1085 :
1086 : /* update the circular buffer of old LSP vectors with the new LSP vector */
1087 203381 : Copy( lsp_new, &( ho_lsp_circ[( *ho_circ_ptr ) * M] ), M );
1088 :
1089 : /* calculate the residual signal energy */
1090 : /*enr = dotp( exc2, exc2, L_frame ) / L_frame; */
1091 :
1092 203381 : maxv = 0;
1093 203381 : move16();
1094 59651317 : FOR( i = 0; i < L_frame; i++ )
1095 : {
1096 59447936 : maxv = s_max( maxv, abs_s( exc2[i] ) );
1097 : }
1098 203381 : scale = norm_s( maxv );
1099 :
1100 203381 : pt_exc2 = exc2;
1101 203381 : L_ener = 0;
1102 203381 : move32();
1103 203381 : IF( EQ_16( L_frame, L_FRAME ) )
1104 : {
1105 11355999 : FOR( j = 0; j < 128; j++ )
1106 : {
1107 11267968 : tmpv = shl( *pt_exc2, scale );
1108 11267968 : L_tmp = L_mult0( tmpv, tmpv ); /* 2*(Q_exc+scale) */
1109 11267968 : pt_exc2++;
1110 11267968 : tmpv = shl( *pt_exc2, scale );
1111 11267968 : L_tmp = L_mac0_o( L_tmp, tmpv, tmpv, &Overflow );
1112 11267968 : pt_exc2++;
1113 11267968 : 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 */
1114 : }
1115 : }
1116 : ELSE /* L_FRAME16k */
1117 : {
1118 18571350 : FOR( j = 0; j < 160; j++ )
1119 : {
1120 18456000 : tmpv = shl( *pt_exc2, scale );
1121 18456000 : L_tmp = L_mult0( tmpv, tmpv ); /* 2*(Q_exc+scale) */
1122 18456000 : pt_exc2++;
1123 18456000 : tmpv = shl( *pt_exc2, scale );
1124 18456000 : L_tmp = L_mac0_o( L_tmp, tmpv, tmpv, &Overflow );
1125 18456000 : pt_exc2++;
1126 18456000 : 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 */
1127 : }
1128 : }
1129 203381 : 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) */
1130 :
1131 : /* update the circular buffer of old energies */
1132 203381 : ho_ener_circ[*ho_circ_ptr] = L_ener;
1133 203381 : move32();
1134 :
1135 203381 : IF( enc_dec_flag == ENC )
1136 : {
1137 : /* Store residual signal for postponed FFT-processing*/
1138 33630 : *cng_buf_cnt = add( *cng_buf_cnt, 1 );
1139 33630 : move16();
1140 33630 : if ( GT_16( *cng_buf_cnt, HO_HIST_SIZE ) )
1141 : {
1142 31850 : *cng_buf_cnt = HO_HIST_SIZE;
1143 31850 : move16();
1144 : }
1145 33630 : Copy( exc2, &( cng_exc2_buf[( *ho_circ_ptr ) * L_FFT] ), L_FFT );
1146 33630 : cng_Qexc_buf[*ho_circ_ptr] = Q_exc;
1147 33630 : move16();
1148 33630 : cng_brate_buf[*ho_circ_ptr] = last_active_brate;
1149 33630 : move32();
1150 : }
1151 : ELSE
1152 : {
1153 : /* calculate the spectrum of residual signal */
1154 169751 : Copy( exc2, fft_io, L_frame );
1155 :
1156 169751 : fft_rel_fx( fft_io, L_FFT, LOG2_L_FFT );
1157 :
1158 169751 : ptR = &fft_io[1];
1159 169751 : ptI = &fft_io[L_FFT - 1];
1160 3564771 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
1161 : {
1162 : /* sp[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */
1163 3395020 : L_tmp = L_mult_o( *ptR, *ptR, &Overflow ); /* 2*Q_exc+1 */
1164 3395020 : L_tmp = L_add_o( L_tmp, L_mult_o( *ptI, *ptI, &Overflow ), &Overflow ); /* 2*Q_exc+1 */
1165 3395020 : L_tmp = L_add_o( L_tmp, L_tmp, &Overflow ); /* 2*Q_exc+1 */
1166 3395020 : L_tmp = Mult_32_16( L_tmp, 128 ); /* 2*Q_exc+1 */
1167 3395020 : tmp = add( add( Q_exc, Q_exc ), 1 );
1168 3395020 : sp[i] = L_shr_o( L_tmp, sub( tmp, 6 ), &Overflow );
1169 3395020 : move32(); /* Q6 */
1170 3395020 : ptR++;
1171 3395020 : ptI--;
1172 : }
1173 :
1174 :
1175 169751 : Copy32( sp, env, NUM_ENV_CNG );
1176 169751 : Word16 shift = 0;
1177 169751 : move16();
1178 169751 : test();
1179 169751 : IF( EQ_16( element_mode, IVAS_SCE ) || EQ_16( element_mode, IVAS_CPE_DFT ) )
1180 166000 : {
1181 166000 : Word32 att_fx = 0;
1182 166000 : Word16 index = 0;
1183 166000 : move32();
1184 166000 : move16();
1185 166000 : apply_scale_ivas_fx( &att_fx, bwidth, last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO, &index );
1186 166000 : att_fx = pow_10_q23[index]; // Q23
1187 166000 : move32();
1188 166000 : tmp = extract_h( att_fx ); // Q7
1189 166000 : shift = 8;
1190 166000 : move16();
1191 : }
1192 : ELSE
1193 : {
1194 3751 : CNG_mode = get_cng_mode( last_active_brate );
1195 : /* att = 1/pow(2,ENR_ATT_fx[CNG_mode]); */
1196 3751 : L_tmp = L_shl( L_deposit_l( ENR_ATT_fx[CNG_mode] ), 8 ); /* 16 */
1197 3751 : temp_lo_fx = L_Extract_lc( L_tmp, &temp_hi_fx );
1198 :
1199 3751 : exp_pow = sub( 14, temp_hi_fx );
1200 3751 : L_tmp = Pow2( 14, temp_lo_fx ); /* Qexp_pow */
1201 3751 : L_tmp = L_shl( L_tmp, sub( 13, exp_pow ) ); /* Q13 */
1202 3751 : tmp = extract_l( L_tmp ); /* Q13 */
1203 :
1204 3751 : exp1 = norm_s( tmp );
1205 3751 : tmp = shl( tmp, exp1 ); /*Q(exp1+13) */
1206 3751 : tmp = div_s( 16384, tmp ); /*Q(15+14-exp1-13) */
1207 3751 : tmp = shr( tmp, sub( 1, exp1 ) ); /* Q15 */
1208 : }
1209 :
1210 3564771 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
1211 : {
1212 3395020 : env[i] = Mult_32_16( env[i], tmp );
1213 3395020 : move32();
1214 : }
1215 :
1216 : /* update the circular buffer of old residual envelope */
1217 : /* Copy32( env, &(ho_env_circ[add(shl(*ho_circ_ptr,4),shl(*ho_circ_ptr,2))]), NUM_ENV_CNG ); */
1218 169751 : Copy32( env, &( ho_env_circ[( *ho_circ_ptr ) * NUM_ENV_CNG] ), NUM_ENV_CNG );
1219 169751 : scale_sig32( &( ho_env_circ[( *ho_circ_ptr ) * NUM_ENV_CNG] ), NUM_ENV_CNG, shift ); // Q(6+shift)
1220 : }
1221 203381 : *ho_circ_size = add( *ho_circ_size, 1 );
1222 203381 : move16();
1223 203381 : if ( GT_16( *ho_circ_size, HO_HIST_SIZE ) )
1224 : {
1225 193912 : *ho_circ_size = HO_HIST_SIZE;
1226 193912 : move16();
1227 : }
1228 :
1229 203381 : return;
1230 : }
1231 :
1232 : /*---------------------------------------------------------------------*
1233 : * get_cng_mode()
1234 : *
1235 : *
1236 : *---------------------------------------------------------------------*/
1237 :
1238 6425 : Word16 get_cng_mode(
1239 : const Word32 last_active_brate /* i : last active bitrate */
1240 : )
1241 : {
1242 : Word16 CNG_mode;
1243 :
1244 6425 : IF( GT_32( last_active_brate, ACELP_13k20 ) )
1245 : {
1246 4142 : CNG_mode = 4;
1247 4142 : move16();
1248 : }
1249 2283 : ELSE IF( GT_32( last_active_brate, ACELP_9k60 ) )
1250 : {
1251 1727 : CNG_mode = 3;
1252 1727 : move16();
1253 : }
1254 556 : ELSE IF( GT_32( last_active_brate, ACELP_8k00 ) )
1255 : {
1256 397 : CNG_mode = 2;
1257 397 : move16();
1258 : }
1259 159 : ELSE IF( GT_32( last_active_brate, ACELP_7k20 ) )
1260 : {
1261 156 : CNG_mode = 1;
1262 156 : move16();
1263 : }
1264 : ELSE
1265 : {
1266 3 : CNG_mode = 0;
1267 3 : move16();
1268 : }
1269 :
1270 6425 : return ( CNG_mode );
1271 : }
|