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 3846 : denv[i] = 0;
330 3846 : 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 13560 : exp = add( exp, 1 );
390 : }
391 22820 : IF( GT_16( tmp2, tmp ) )
392 : {
393 13560 : 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 : #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 0 : 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 0 : Flag Overflow = 0;
730 0 : move32();
731 : #endif
732 :
733 0 : ptr = add( sub( ho_circ_ptr, *cng_buf_cnt ), 1 );
734 0 : IF( ptr < 0 )
735 : {
736 0 : ptr = add( ptr, HO_HIST_SIZE );
737 : }
738 :
739 0 : FOR( j = 0; j < *cng_buf_cnt; j++ )
740 : {
741 0 : exc2 = &cng_exc2_buf[ptr * L_FFT];
742 0 : Q_exc = cng_Qexc_buf[ptr];
743 0 : move16();
744 0 : last_active_brate = cng_brate_buf[ptr];
745 0 : move32();
746 :
747 : /* calculate the spectrum of residual signal */
748 0 : Copy( exc2, fft_io, L_FFT );
749 :
750 0 : fft_rel_fx( fft_io, L_FFT, LOG2_L_FFT );
751 :
752 0 : ptR = &fft_io[1];
753 0 : ptI = &fft_io[L_FFT - 1];
754 0 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
755 : {
756 : /* sp[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */
757 0 : L_tmp = L_mult_o( *ptR, *ptR, &Overflow ); /* 2*Q_exc+1 */
758 0 : L_tmp = L_add_o( L_tmp, L_mult_o( *ptI, *ptI, &Overflow ), &Overflow ); /* 2*Q_exc+1 */
759 0 : L_tmp = L_add_o( L_tmp, L_tmp, &Overflow ); /* 2*Q_exc+1 */
760 0 : L_tmp = Mult_32_16( L_tmp, 128 ); /* 2*Q_exc+1 */
761 0 : tmp = add( add( Q_exc, Q_exc ), 1 );
762 : // To do : Saturation to be re-validated.
763 0 : sp[i] = L_shr_sat( L_tmp, sub( tmp, 6 ) );
764 0 : move32(); /* Q6 */
765 :
766 0 : ptR++;
767 0 : ptI--;
768 : }
769 :
770 0 : Copy32( sp, env, NUM_ENV_CNG );
771 :
772 0 : test();
773 0 : IF( EQ_16( element_mode, IVAS_SCE ) || EQ_16( element_mode, IVAS_CPE_DFT ) )
774 0 : {
775 0 : Word32 att_fx = 0;
776 0 : move32();
777 0 : tmp = 0;
778 0 : move16();
779 0 : apply_scale( &att_fx, bwidth, last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO );
780 0 : att_fx = L_shr( Mpy_32_16_1( att_fx, 26214 ), 3 ); /* 26214 = 0.1f in Q18 */
781 0 : att_fx = BASOP_Util_fPow( 1342177280 /* 10 in Q27 */, 4, att_fx, 8, &tmp );
782 0 : 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 0 : FOR( i = 0; i < NUM_ENV_CNG; i++ )
805 : {
806 0 : env[i] = Mult_32_16( env[i], tmp );
807 0 : move32();
808 : }
809 :
810 : /* update the circular buffer of old residual envelope */
811 0 : Copy32( env, &( ho_env_circ[(ptr) *NUM_ENV_CNG] ), NUM_ENV_CNG );
812 :
813 0 : ptr = add( ptr, 1 );
814 0 : if ( EQ_16( ptr, HO_HIST_SIZE ) )
815 : {
816 0 : ptr = 0;
817 0 : move16();
818 : }
819 : }
820 :
821 0 : *cng_buf_cnt = 0;
822 0 : move16();
823 :
824 0 : 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 169751 : 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 169751 : Word16 tmp = 0;
1040 169751 : move16();
1041 : Word16 temp_lo_fx, temp_hi_fx;
1042 : Word16 exp_pow;
1043 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1044 169751 : Flag Overflow = 0;
1045 169751 : move32();
1046 : #endif
1047 :
1048 : /* update the pointer to circular buffer of old LSP vectors */
1049 169751 : *ho_circ_ptr = add( *ho_circ_ptr, 1 );
1050 169751 : move16();
1051 :
1052 169751 : if ( EQ_16( *ho_circ_ptr, HO_HIST_SIZE ) )
1053 : {
1054 20650 : *ho_circ_ptr = 0;
1055 20650 : move16();
1056 : }
1057 :
1058 : /* update the circular buffer of old LSP vectors with the new LSP vector */
1059 169751 : 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 169751 : maxv = 0;
1065 169751 : move16();
1066 49730775 : FOR( i = 0; i < L_frame; i++ )
1067 : {
1068 49561024 : maxv = s_max( maxv, abs_s( exc2[i] ) );
1069 : }
1070 169751 : scale = norm_s( maxv );
1071 :
1072 169751 : pt_exc2 = exc2;
1073 169751 : L_ener = 0;
1074 169751 : move32();
1075 169751 : IF( EQ_16( L_frame, L_FRAME ) )
1076 : {
1077 9592956 : FOR( j = 0; j < 128; j++ )
1078 : {
1079 9518592 : tmpv = shl( *pt_exc2, scale );
1080 9518592 : L_tmp = L_mult0( tmpv, tmpv ); /* 2*(Q_exc+scale) */
1081 9518592 : pt_exc2++;
1082 9518592 : tmpv = shl( *pt_exc2, scale );
1083 9518592 : L_tmp = L_mac0_o( L_tmp, tmpv, tmpv, &Overflow );
1084 9518592 : pt_exc2++;
1085 9518592 : 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 15357307 : FOR( j = 0; j < 160; j++ )
1091 : {
1092 15261920 : tmpv = shl( *pt_exc2, scale );
1093 15261920 : L_tmp = L_mult0( tmpv, tmpv ); /* 2*(Q_exc+scale) */
1094 15261920 : pt_exc2++;
1095 15261920 : tmpv = shl( *pt_exc2, scale );
1096 15261920 : L_tmp = L_mac0_o( L_tmp, tmpv, tmpv, &Overflow );
1097 15261920 : pt_exc2++;
1098 15261920 : 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 169751 : 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 169751 : ho_ener_circ[*ho_circ_ptr] = L_ener;
1105 169751 : move32();
1106 :
1107 169751 : IF( enc_dec_flag == ENC )
1108 : {
1109 : /* Store residual signal for postponed FFT-processing*/
1110 0 : *cng_buf_cnt = add( *cng_buf_cnt, 1 );
1111 0 : move16();
1112 0 : if ( GT_16( *cng_buf_cnt, HO_HIST_SIZE ) )
1113 : {
1114 0 : *cng_buf_cnt = HO_HIST_SIZE;
1115 0 : move16();
1116 : }
1117 0 : Copy( exc2, &( cng_exc2_buf[( *ho_circ_ptr ) * L_FFT] ), L_FFT );
1118 0 : cng_Qexc_buf[*ho_circ_ptr] = Q_exc;
1119 0 : move16();
1120 0 : cng_brate_buf[*ho_circ_ptr] = last_active_brate;
1121 0 : 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 169751 : *ho_circ_size = add( *ho_circ_size, 1 );
1194 169751 : move16();
1195 169751 : if ( GT_16( *ho_circ_size, HO_HIST_SIZE ) )
1196 : {
1197 161466 : *ho_circ_size = HO_HIST_SIZE;
1198 161466 : move16();
1199 : }
1200 :
1201 169751 : 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 : }
|