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