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"
6 : #include "rom_com.h"
7 : #include "prot_fx.h"
8 :
9 : /*-------------------------------------------------------------------*
10 : * gs_noisf()
11 : *
12 : * Noise fill-in function
13 : *-------------------------------------------------------------------*/
14 :
15 229892 : static void gs_noisf_fx(
16 : const Word16 Start_BIN, /* i : First bin for noise fill */
17 : const Word16 NB_Qbins, /* i : Number of bin per band */
18 : const Word16 Noise_fac, /* i : Noise level Q15 */
19 : const Word16 *y_norm, /* i : Quantized pulses Q(qNoise_fac) */
20 : Word16 *exc_diffQ, /* o : Quantized pulses with noise added Q(qNoise_fac) */
21 : Word16 *seed_tcx, /* i : Random generator seed */
22 : const Word16 coder_type, /* i : coder type */
23 : Word16 qNoise_fac )
24 : {
25 : Word32 ftmp;
26 : Word16 i, k;
27 : Word16 NB_zer;
28 229892 : Word32 const_1 = 1;
29 229892 : move32();
30 : Word16 tmp;
31 :
32 229892 : NB_zer = shr( NB_Qbins, 1 );
33 :
34 229892 : const_1 = L_shl( const_1, add( qNoise_fac, qNoise_fac ) ); /*2*Q(qNoise_fac)*/
35 229892 : if ( ( coder_type == INACTIVE ) )
36 : {
37 70714 : NB_zer = 2;
38 70714 : move16();
39 : }
40 :
41 : /*----------------------------------------------*
42 : * noise fill-in on unquantized subvector *
43 : * injected only from 1066Hz to 6400Hz. *
44 : *----------------------------------------------*/
45 :
46 1154360 : FOR( k = Start_BIN; k < NB_Qbins + Start_BIN; k += NB_zer )
47 : {
48 924468 : ftmp = L_deposit_l( 0 );
49 4683572 : FOR( i = k; i < k + NB_zer; i++ )
50 : {
51 3759104 : exc_diffQ[i] = y_norm[i];
52 3759104 : move16();
53 3759104 : ftmp = L_mac0( ftmp, exc_diffQ[i], exc_diffQ[i] ); /*2*Q(qNoise_fac)*/
54 : }
55 :
56 924468 : IF( LT_32( L_shl( ftmp, 1 ), const_1 ) )
57 : {
58 3500858 : FOR( i = k; i < k + NB_zer; i++ )
59 : {
60 : /*exc_diffQ[i] += Noise_fac*((float)own_random(seed_tcx)/32768.0f);*/
61 2808276 : tmp = mult( Noise_fac, Random( seed_tcx ) ); /*Q15 */
62 2808276 : tmp = shr( tmp, sub( 15, qNoise_fac ) ); /*qNoise_fac */
63 2808276 : exc_diffQ[i] = add( exc_diffQ[i], tmp );
64 2808276 : move16(); /*Q */
65 : }
66 : }
67 : ELSE
68 : {
69 : /* This is added only to keep the seed in sync between different compilers */
70 1182714 : FOR( i = k; i < k + NB_zer; i++ )
71 : {
72 950828 : Random( seed_tcx );
73 : }
74 : }
75 : }
76 :
77 229892 : return;
78 : }
79 :
80 : /*-------------------------------------------------------------------*
81 : * EstimateNoiseLevel_inner()
82 : *
83 : * Estimate noise level from the power spectrum
84 : *-------------------------------------------------------------------*/
85 :
86 11499 : static void EstimateNoiseLevel_inner_fx(
87 : Word16 *noisepb, /* o : Noise per band Q15 */
88 : const long bitrate, /* i : Bitrate of the codec */
89 : const Word16 i_band, /* i : First band to compute the noise */
90 : const Word16 Mbands_gn /* i : number of bands */
91 : )
92 : {
93 : Word16 i;
94 : Word16 noise_offset;
95 :
96 11499 : noise_offset = 8192;
97 11499 : move16();
98 : /*0.25f * 32768 */
99 11499 : IF( GT_32( bitrate, ACELP_24k40 ) )
100 : {
101 187 : noise_offset = 6554;
102 187 : move16(); /*.2f * 32768 */
103 : }
104 11312 : ELSE IF( GE_32( bitrate, ACELP_22k60 ) )
105 : {
106 638 : noise_offset = 9830;
107 638 : move16(); /*.3f * 32768 */
108 : }
109 10674 : ELSE IF( GE_32( bitrate, ACELP_9k60 ) )
110 : {
111 4649 : noise_offset = 11469;
112 4649 : move16(); /*0.35f * 32768 */
113 : }
114 : ELSE
115 : {
116 6025 : noise_offset = 13107;
117 6025 : move16(); /*.4f * 32768 */
118 : }
119 :
120 11499 : set16_fx( noisepb + i_band, noise_offset, sub( Mbands_gn, i_band ) ); /*Q15*/
121 :
122 68994 : FOR( i = i_band; i < 5; i++ )
123 : {
124 57495 : noisepb[i] = s_min( noisepb[i], 6554 /*0.2(Q15)*/ );
125 57495 : move16();
126 : }
127 :
128 11499 : return;
129 : }
130 : /*==========================================================================*/
131 : /* FUNCTION : void EstimateNoiseLevel_fx() */
132 : /*--------------------------------------------------------------------------*/
133 : /* PURPOSE : */
134 : /*--------------------------------------------------------------------------*/
135 : /* INPUT ARGUMENTS : */
136 : /* _ (Word32) bitrate : Bitrate of the codec Q0 */
137 : /* _ (Word16) Diff_len : number of bin before cut-off frequency */
138 : /* _ (Word16) Mbands_gn : number of bands Q0 */
139 : /* _ (Word16) coder_type : coder type Q0 */
140 : /* _ (Word16) noise_lev : pulses dynamic Q0 */
141 : /* _ (Word16) pit_band_idx : bin position of the cut-off frequency */
142 : /* _ (Word16*) freq_nsbin_per_band : bin per bands tables Q0 */
143 : /*--------------------------------------------------------------------------*/
144 : /* OUTPUT ARGUMENTS : */
145 : /* _ (Word16*) noisepb : Noise per band Q15 */
146 : /*--------------------------------------------------------------------------*/
147 : /* INPUT/OUTPUT ARGUMENTS : */
148 : /* None */
149 : /*--------------------------------------------------------------------------*/
150 : /* RETURN ARGUMENTS : */
151 : /* _ None */
152 : /*==========================================================================*/
153 11499 : static void EstimateNoiseLevel_fx(
154 : Word16 *noisepb, /* o : Noise per band */
155 : const Word32 bitrate, /* i : Bitrate of the codec */
156 : const Word16 Diff_len, /* i : number of bin before cut-off frequency */
157 : const Word16 Mbands_gn, /* i : number of bands */
158 : const Word16 coder_type, /* i : coder type */
159 : const Word16 noise_lev, /* i : pulses dynamic */
160 : const Word16 pit_band_idx, /* i : bin position of the cut-off frequency */
161 : Word16 last_bin, /* i : the last bin of bit allocation */
162 : Word16 bwidth,
163 : const Word16 L_frame /* i : frame length */
164 : )
165 : {
166 : Word16 i_band;
167 :
168 11499 : i_band = 0;
169 11499 : move16();
170 :
171 11499 : IF( LT_16( Diff_len, L_frame ) )
172 : {
173 11499 : EstimateNoiseLevel_inner_fx( noisepb, bitrate, i_band, MBANDS_GN );
174 11499 : IF( coder_type != INACTIVE )
175 : {
176 7516 : test();
177 7516 : test();
178 7516 : IF( ( EQ_32( bitrate, ACELP_8k00 ) && GT_16( last_bin, 8 ) ) && NE_16( bwidth, NB ) )
179 : {
180 34 : FOR( ; Mbands_gn > i_band; i_band++ )
181 : {
182 32 : noisepb[i_band] = add( noisepb[i_band], noisepb[i_band] );
183 32 : move16();
184 : }
185 : }
186 : ELSE
187 : {
188 71427 : FOR( ; pit_band_idx > i_band; i_band++ )
189 : {
190 63913 : noisepb[i_band] = mult_r( noisepb[i_band], 16384 );
191 63913 : move16(); /* 1/2=0.5 in Q15 */
192 : }
193 : }
194 : }
195 : }
196 11499 : test();
197 11499 : test();
198 11499 : IF( ( ( coder_type == INACTIVE ) || GE_16( noise_lev, NOISE_LEVEL_SP3 ) ) && EQ_16( L_frame, L_FRAME ) )
199 : {
200 46752 : FOR( i_band = 9; i_band < Mbands_gn; i_band++ )
201 : {
202 40908 : noisepb[i_band] = add( noisepb[i_band], mult_r( noisepb[i_band], 4915 ) );
203 40908 : move16(); /*noisepb[i_band]*1.15=noisepb[i_band] *(1 + 0.15) */
204 : }
205 : }
206 5655 : ELSE IF( EQ_16( L_frame, L_FRAME16k ) )
207 : {
208 2525 : IF( EQ_32( bitrate, ACELP_13k20 ) )
209 : {
210 0 : set16_fx( noisepb, 14746 /*0.45*/, Mbands_gn );
211 : }
212 :
213 2525 : IF( ( coder_type == INACTIVE ) )
214 : {
215 47975 : FOR( ; i_band < Mbands_gn; i_band++ )
216 : {
217 45450 : noisepb[i_band] = 13107 /*.4f*/;
218 45450 : move16();
219 : }
220 : }
221 0 : ELSE IF( LE_16( noise_lev, NOISE_LEVEL_SP1 ) && GT_32( bitrate, ACELP_16k40 ) )
222 : {
223 0 : FOR( ; i_band < sub( Mbands_gn, 4 ); i_band++ )
224 : {
225 0 : noisepb[i_band] = mult_r( noisepb[i_band], 19661 ) /*.6f*/;
226 0 : move16();
227 : }
228 : }
229 0 : ELSE IF( LE_16( noise_lev, NOISE_LEVEL_SP2 ) && GT_32( bitrate, ACELP_16k40 ) )
230 : {
231 0 : FOR( ; i_band < sub( Mbands_gn, 4 ); i_band++ )
232 : {
233 0 : noisepb[i_band] = mult_r( noisepb[i_band], 26214 ) /*.8f*/;
234 0 : move16();
235 : }
236 : }
237 : }
238 :
239 :
240 11499 : return;
241 : }
242 :
243 : /*============================================================================*/
244 : /* FUNCTION : void Appy_NoiseFill_fx() */
245 : /*----------------------------------------------------------------------------*/
246 : /* PURPOSE : */
247 : /*----------------------------------------------------------------------------*/
248 : /* INPUT ARGUMENTS : */
249 : /* _ (Word16*) seed_tcx : Seed for noise Q0 */
250 : /* _ (Word16*) noisepb : Noise per band Q15 */
251 : /* _ (Word16) Diff_len : number of bin before cut-off frequency Q0 */
252 : /* _ (Word16) Mbands_gn : number of bands Q0 */
253 : /* _ (Word16) coder_type : pulses dynamic Q0 */
254 : /* _ (Word16*) freq_nsbin_per_band: bin per bands tables Q0 */
255 : /* _ (Word16) qexc_diffQ : Q format of exc_diffQ */
256 : /*----------------------------------------------------------------------------*/
257 : /* OUTPUT ARGUMENTS : */
258 : /* _ (Word16*) exc_diffQ : Noise per band qexc_diffQ */
259 : /*----------------------------------------------------------------------------*/
260 : /* INPUT/OUTPUT ARGUMENTS : */
261 : /* None */
262 : /*----------------------------------------------------------------------------*/
263 : /* RETURN ARGUMENTS : */
264 : /* _ None */
265 : /*============================================================================*/
266 14054 : static void Apply_NoiseFill_fx(
267 : Word16 *exc_diffQ, /* i/o: Noise per band qexc_diffQ */
268 : Word16 *seed_tcx, /* i : Seed for noise */
269 : const Word16 *noisepb, /* i : Noise per band Q15 */
270 : const Word16 Diff_len, /* i : number of bin before cut-off frequency */
271 : const Word16 Mbands_gn, /* i : number of bands */
272 : const Word16 coder_type, /* i : coder type */
273 : const Word16 *freq_nsbin_per_band, /* i : bin per bands tables */
274 : Word16 qexc_diffQ )
275 : {
276 : Word16 StartBin, NB_Qbins, i_band;
277 14054 : StartBin = 0;
278 14054 : move16();
279 14054 : NB_Qbins = 0;
280 14054 : move16();
281 :
282 243946 : FOR( i_band = 0; i_band < Mbands_gn; i_band++ )
283 : {
284 229892 : StartBin = add( StartBin, NB_Qbins );
285 229892 : NB_Qbins = freq_nsbin_per_band[i_band];
286 229892 : move16();
287 :
288 229892 : IF( LT_16( Diff_len, L_FRAME ) )
289 : {
290 229892 : gs_noisf_fx( StartBin, NB_Qbins, noisepb[i_band], exc_diffQ, exc_diffQ, seed_tcx, coder_type, qexc_diffQ );
291 : }
292 : }
293 :
294 14054 : return;
295 : }
296 : /*==========================================================================*/
297 : /* FUNCTION :void freq_dnw_scaling_fx () */
298 : /*--------------------------------------------------------------------------*/
299 : /* PURPOSE : */
300 : /*--------------------------------------------------------------------------*/
301 : /* INPUT ARGUMENTS : */
302 : /* _ (Word16) cor_strong_limit : HF correlation Q0 */
303 : /* _ (Word16) coder_type : coder type Q0 */
304 : /* _ (Word16) noise_lev : Noise level Q0 */
305 : /* _ (Word32) core_brate : Core bitrate Q0 */
306 : /* _ (Word16) Qx : Q format of fy_norm */
307 : /*--------------------------------------------------------------------------*/
308 : /* OUTPUT ARGUMENTS : */
309 : /* _ None */
310 : /*--------------------------------------------------------------------------*/
311 : /* INPUT/OUTPUT ARGUMENTS : */
312 : /* _ (Word16[]) fy_norm : Frequency quantized parameter Qx */
313 : /*--------------------------------------------------------------------------*/
314 : /* RETURN ARGUMENTS : */
315 : /* _None */
316 : /*==========================================================================*/
317 13760 : void freq_dnw_scaling_fx(
318 : const Word16 cor_strong_limit, /* i : HF correlation */
319 : const Word16 coder_type, /* i : coder type */
320 : const Word16 noise_lev, /* i : Noise level */
321 : const Word32 core_brate, /* i : Core bitrate */
322 : Word16 fy_norm[], /* i/o: Frequency quantized parameter Qx */
323 : Word16 Qx, /* Q format of fy_norm*/
324 : const Word16 L_frame /* i : frame length */
325 :
326 : )
327 : {
328 : Word16 sc_dyn;
329 : Word16 start_sc, i;
330 :
331 13760 : sc_dyn = 32767;
332 13760 : move16(); /*Q15 */
333 13760 : start_sc = L_frame;
334 13760 : move16();
335 13760 : test();
336 13760 : IF( LE_32( core_brate, ACELP_8k00 ) && ( coder_type == INACTIVE ) )
337 : {
338 30 : sc_dyn = mult_r( sc_dyn, 4915 ); /*Q15 (0.15 in Q15) */
339 30 : start_sc = 64;
340 30 : move16();
341 : }
342 13730 : ELSE IF( ( coder_type == INACTIVE ) )
343 : {
344 4048 : sc_dyn = mult_r( sc_dyn, 8192 ); /*Q15 (0.25 in Q15) */
345 4048 : start_sc = 80;
346 4048 : move16();
347 : }
348 : ELSE
349 : {
350 : /*sc_dyn = (float)(NOISE_LEVEL_SP3 - noise_lev)/10.0f + 0.4f;*/
351 9682 : sc_dyn = extract_l( L_mac( 13107, sub( NOISE_LEVEL_SP3, noise_lev ), 1638 ) ); /*Q0*Q14x2+Q15 =Q15*/
352 9682 : start_sc = add( 112, shl( sub( NOISE_LEVEL_SP3, noise_lev ), 4 ) );
353 9682 : if ( EQ_16( noise_lev, NOISE_LEVEL_SP0 ) )
354 : {
355 2165 : start_sc = L_FRAME;
356 2165 : move16();
357 : }
358 : }
359 :
360 13760 : test();
361 13760 : IF( EQ_16( L_frame, L_FRAME16k ) && LE_32( core_brate, ACELP_24k40 ) )
362 : {
363 : /*sc_dyn += 0.125f;*/
364 2338 : sc_dyn = add( sc_dyn, 4096 ); /* Saturates to 1.0 */
365 : }
366 :
367 1881232 : FOR( i = start_sc; i < L_frame; i++ )
368 : {
369 1867472 : fy_norm[i] = mult_r( fy_norm[i], sc_dyn );
370 1867472 : move16(); /*Qx */
371 : }
372 :
373 13760 : test();
374 13760 : test();
375 13760 : IF( ( LT_32( core_brate, ACELP_13k20 ) && cor_strong_limit == 0 ) || LT_32( core_brate, ACELP_9k60 ) )
376 : {
377 985520 : FOR( i = 160; i < L_frame; i++ )
378 : {
379 975360 : fy_norm[i] = s_min( fy_norm[i], shl( 1, Qx ) ); /*Qx*/
380 975360 : move16();
381 975360 : fy_norm[i] = s_max( fy_norm[i], shl( -1, Qx ) ); /*Qx*/
382 975360 : move16();
383 : }
384 : }
385 3600 : ELSE IF( LT_32( core_brate, ACELP_22k60 ) )
386 : {
387 377975 : FOR( i = 160; i < L_frame; i++ )
388 : {
389 375200 : fy_norm[i] = s_min( fy_norm[i], shr_r( 1536 /*1.5 in Q10*/, sub( 10, Qx ) ) ); /*Qx*/
390 375200 : move16();
391 375200 : fy_norm[i] = s_max( fy_norm[i], shr_r( -1536 /*1.5 in Q10*/, sub( 10, Qx ) ) ); /*Qx*/
392 375200 : move16();
393 : }
394 : }
395 :
396 13760 : return;
397 : }
398 :
399 20 : static void Decreas_freqPeak_fx(
400 : const Word16 *lsf_new, /* i : ISFs at the end of the frame Qx2.56 */
401 : Word16 *exc_diffQ, /* i/o: frequency coefficients of per band */
402 : Word16 rat /* i : threshold of ratio between consecutive lsf_new_diff */
403 : )
404 : {
405 : Word16 i, j, k;
406 20 : Word16 last_bin = 0;
407 20 : Word16 pos = 0;
408 20 : move16();
409 : Word16 *src, max_val, avrg;
410 : Word32 L_avrg, L_tmp;
411 : Word16 lsf_new_diff[M];
412 : Word16 tmp, tmp1, exp;
413 : Word16 tmp2;
414 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
415 20 : Flag Overflow = 0;
416 20 : move16();
417 : #endif
418 20 : move16(); /*ptr init*/
419 20 : lsf_new_diff[0] = 0; /* prevent unitialized value */
420 20 : move16();
421 300 : FOR( j = 1; j < ( M - 1 ); j++ )
422 : {
423 280 : lsf_new_diff[j] = sub( lsf_new[j], lsf_new[j - 1] ); /*Qx2.56 */
424 280 : move16();
425 : }
426 :
427 20 : avrg = 0;
428 20 : move16();
429 20 : L_avrg = L_deposit_l( 0 );
430 20 : max_val = 1;
431 20 : move16();
432 1940 : FOR( i = 160; i < L_FRAME; i++ )
433 : {
434 1920 : IF( GT_16( abs_s( exc_diffQ[i] ), max_val ) )
435 : {
436 116 : max_val = abs_s( exc_diffQ[i] );
437 116 : pos = i;
438 116 : move16();
439 : }
440 1920 : L_avrg = L_add( L_avrg, abs_s( exc_diffQ[i] ) );
441 : }
442 : /* avrg /= 96; */
443 20 : L_avrg = Mult_32_16( L_avrg, 21845 ); /*Q_exc+21 -15 ->Q_exc + 6 */
444 20 : avrg = round_fx( L_shl( L_avrg, 10 ) ); /*Q_exc */
445 20 : last_bin = M - 1;
446 20 : move16(); /* When the search is false, should equate the end of the vector, not the beginning */
447 215 : FOR( i = 0; i < ( M - 1 ); i++ )
448 : {
449 215 : IF( GT_16( lsf_new[i], 10240 /*4000 in Qx2.56*/ ) )
450 : {
451 20 : last_bin = i;
452 20 : move16();
453 20 : BREAK;
454 : }
455 : }
456 :
457 105 : FOR( i = last_bin; i < 14; i++ )
458 : {
459 85 : tmp = mult_r( rat, lsf_new_diff[i - 1] ); /*Qx2.56 */
460 85 : IF( GT_16( tmp, lsf_new_diff[i] ) )
461 : {
462 4 : src = &exc_diffQ[( i - 1 ) << 4];
463 4 : move16();
464 12 : FOR( j = 0; j < 2; j++ )
465 : {
466 136 : FOR( k = 0; k < 16; k++ )
467 : {
468 128 : tmp = mult_r( 16384, abs_s( *src ) );
469 128 : IF( GT_16( tmp, avrg ) )
470 : {
471 10 : tmp = abs_s( *src );
472 10 : exp = norm_s( max_val );
473 10 : tmp1 = div_s( shl( 1, sub( 14, exp ) ), max_val ); /*Q(29 - exp - Q_exc) */
474 10 : L_tmp = L_mult( tmp, tmp1 ); /*Q(30 - exp) */
475 10 : tmp = round_fx_o( L_shl_o( L_tmp, exp, &Overflow ), &Overflow ); /*Q14 */
476 10 : tmp = sub( 32767, tmp ); /*Q14 */
477 10 : L_tmp = L_mult( avrg, tmp ); /*Q_exc +15 */
478 :
479 10 : tmp = round_fx( L_shl( L_tmp, 1 ) );
480 10 : tmp1 = negate( tmp );
481 :
482 10 : tmp2 = *src;
483 10 : move16();
484 10 : *( src ) = tmp1;
485 10 : move16();
486 10 : if ( tmp2 > 0 )
487 : {
488 6 : *( src ) = tmp;
489 6 : move16();
490 : }
491 : }
492 128 : src++;
493 : }
494 : }
495 : }
496 : }
497 :
498 20 : tmp = mult_r( 8192, max_val ); /*Q_exc */
499 20 : test();
500 20 : IF( EQ_16( abs_s( exc_diffQ[pos] ), max_val ) && GT_16( tmp, avrg ) )
501 : {
502 24 : FOR( i = pos - 1; i < pos + 2; i++ )
503 : {
504 18 : exc_diffQ[pos] = mult_r( 16384 /*0.5 in Q15*/, exc_diffQ[pos] );
505 18 : move16();
506 : }
507 : }
508 :
509 20 : return;
510 : }
511 :
512 6 : static void envelop_modify_fx(
513 : Word16 *exc_diffQ_fx, /* i/o: frequency coefficients of per band */
514 : Word16 *seed_tcx, /* i : Seed for noise */
515 : Word16 last_bin, /* i : last bin of bit allocation */
516 : Word16 *Ener_per_bd_iQ_fx, /* i : Quantized energy of targeted vector */
517 : Word16 Q_exc,
518 : Word16 *Q_hb_exc )
519 : {
520 : Word16 i, j, end_band;
521 : Word16 start_band;
522 : Word32 Ener_fx;
523 : Word16 Ener1_fx;
524 : Word16 tmp, tmp1;
525 : Word32 L_tmp;
526 : Word16 exp, exp1, frac;
527 : Word16 *src_fx;
528 : Word16 weight_fx;
529 : Word32 L_exc_diffQ_fx[L_FRAME16k], exc_diffQ_max;
530 : Word16 Q_tmp;
531 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
532 6 : Flag Overflow = 0;
533 6 : move16();
534 : #endif
535 :
536 6 : start_band = i_mult( last_bin, 16 );
537 6 : end_band = L_FRAME;
538 6 : move16();
539 6 : Ener_fx = L_deposit_l( 0 );
540 582 : FOR( i = start_band; i < end_band; i++ )
541 : {
542 576 : L_tmp = L_mult0( exc_diffQ_fx[i], exc_diffQ_fx[i] ); /*2*Q_exc */
543 576 : Ener_fx = L_add( Ener_fx, L_shr( L_tmp, 7 ) ); /*2*Q_exc-7 */
544 : }
545 :
546 6 : tmp = sub( end_band, start_band );
547 6 : tmp = div_s( 1, tmp ); /*Q15 */
548 6 : Ener_fx = Mult_32_16( Ener_fx, tmp ); /*Q(2*Q_exc-7+15)->Q(2*Q_exc-7) */
549 :
550 6 : exp1 = norm_l( Ener_fx );
551 6 : Ener_fx = L_shl( Ener_fx, exp1 );
552 6 : exp1 = sub( sub( 31, exp1 ), sub( shl( Q_exc, 1 ), 7 ) );
553 6 : Ener_fx = Isqrt_lc( Ener_fx, &exp1 ); /*Q(31-exp1) */
554 :
555 6 : weight_fx = 16384; /*Q15 */
556 6 : move16();
557 6 : src_fx = &exc_diffQ_fx[start_band]; /*Q_exc */
558 30 : FOR( i = last_bin; i < last_bin + 4; i++ )
559 : {
560 : /*Ener1 = (float)(0.4f*pow(10, Ener_per_bd_iQ[i+1])); */
561 24 : L_tmp = L_shr( L_mult0( Ener_per_bd_iQ_fx[i + 1], 27213 ), 9 ); /* 3.321928 in Q13 -> Q16 */
562 :
563 24 : frac = L_Extract_lc( L_tmp, &exp ); /* Extract exponent of L_tmp */
564 24 : tmp = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
565 : /* output of Pow2() will be: */
566 : /* 16384 < Pow2() <= 32767 */
567 24 : exp = sub( exp, 14 );
568 24 : Ener1_fx = mult_ro( 13107, shl_o( tmp, exp, &Overflow ), &Overflow ); /*Q0 */
569 :
570 408 : FOR( j = 0; j < 16; j++ )
571 : {
572 : /**src = Ener1*(weight*(*src)*Ener + (1.0f-weight)*own_random(seed_tcx)/32768.0f); */
573 384 : L_tmp = Mult_32_16( Ener_fx, *src_fx ); /*Q(31-exp+Q_exc-15) -> Q(16-exp+Q_exc) */
574 384 : tmp = extract_l( L_shr( L_tmp, add( 4, sub( Q_exc, exp1 ) ) ) ); /*Q12 */
575 384 : tmp = mult_r( weight_fx, tmp ); /*Q12 */
576 :
577 384 : L_tmp = L_mult0( sub( 32767, weight_fx ), Random( seed_tcx ) ); /*Q30 */
578 384 : tmp1 = round_fx( L_shr( L_tmp, 2 ) );
579 :
580 384 : L_exc_diffQ_fx[( ( 16 * i ) + j )] = L_mult0( Ener1_fx, add( tmp, tmp1 ) ); /*Q12 */
581 384 : move32();
582 384 : src_fx++;
583 : }
584 : }
585 :
586 : /*Ener1 = (float)(0.4f*pow(10, Ener_per_bd_iQ[15])); */
587 6 : L_tmp = L_shr( L_mult0( Ener_per_bd_iQ_fx[15], 27213 ), 9 ); /* 3.321928 in Q13 -> Q16 */
588 :
589 6 : frac = L_Extract_lc( L_tmp, &exp ); /* Extract exponent of L_tmp */
590 6 : tmp = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
591 : /* output of Pow2() will be: */
592 : /* 16384 < Pow2() <= 32767 */
593 6 : exp = sub( exp, 14 );
594 6 : Ener1_fx = mult_r( 13107, shl_o( tmp, exp, &Overflow ) ); /*Q0 */
595 :
596 6 : src_fx = &exc_diffQ_fx[224];
597 198 : FOR( j = 0; j < 32; j++ )
598 : {
599 : /**src = Ener1*(weight*(*src)*Ener + (1.0f-weight)*own_random(seed_tcx)/32768.0f); */
600 192 : L_tmp = Mult_32_16( Ener_fx, *src_fx ); /*Q(31-exp+Q_exc-15) -> Q(16-exp+Q_exc) */
601 192 : tmp = extract_l( L_shr( L_tmp, add( 4, sub( Q_exc, exp1 ) ) ) ); /*Q12 */
602 192 : tmp = mult_r( weight_fx, tmp ); /*Q12 */
603 :
604 192 : L_tmp = L_mult0( sub( 32767, weight_fx ), Random( seed_tcx ) ); /*Q30 */
605 192 : tmp1 = round_fx( L_shr( L_tmp, 2 ) ); /*Q12 */
606 :
607 192 : L_exc_diffQ_fx[( ( 16 * i ) + j )] = L_mult0( Ener1_fx, add( tmp, tmp1 ) ); /*Q12 */
608 192 : move32();
609 192 : src_fx++;
610 : }
611 :
612 6 : exc_diffQ_max = 0;
613 6 : move16();
614 582 : FOR( i = start_band; i < L_FRAME; i++ )
615 : {
616 576 : if ( GT_32( L_abs( L_exc_diffQ_fx[i] ), exc_diffQ_max ) )
617 : {
618 6 : exc_diffQ_max = L_abs( L_exc_diffQ_fx[i] );
619 : }
620 : }
621 6 : exp = norm_l( exc_diffQ_max );
622 :
623 6 : IF( GT_16( exp, 16 ) )
624 : {
625 0 : *Q_hb_exc = 12;
626 0 : move16();
627 0 : FOR( i = start_band; i < L_FRAME; i++ )
628 : {
629 0 : exc_diffQ_fx[i] = extract_l( L_exc_diffQ_fx[i] );
630 0 : move16();
631 : }
632 : }
633 : ELSE
634 : {
635 6 : Q_tmp = sub( 16, exp );
636 6 : *Q_hb_exc = sub( 12, Q_tmp );
637 6 : move16();
638 582 : FOR( i = start_band; i < L_FRAME; i++ )
639 : {
640 576 : exc_diffQ_fx[i] = extract_l( L_shr( L_exc_diffQ_fx[i], Q_tmp ) );
641 576 : move16();
642 : }
643 : }
644 :
645 6 : return;
646 : }
647 :
648 0 : void highband_exc_dct_in_fx(
649 : const Word32 core_brate, /* i : core bitrate */
650 : const Word16 *mfreq_bindiv, /* i : bin per bands tables */
651 : Word16 last_bin, /* i : last bin of bit allocation */
652 : Word16 Diff_len, /* i : number of bin before cut-off frequency */
653 : Word16 noise_lev, /* i : pulses dynamic */
654 : Word16 pit_band_idx, /* i : bin position of the cut-off frequency */
655 : Word16 *exc_diffQ, /* i : frequency coefficients of per band */
656 : Word16 *seed_tcx, /* i : Seed for noise */
657 : Word16 *Ener_per_bd_iQ, /* i : Quantized energy of targeted vector */
658 : Word16 nb_subfr, /* i : Number of subframe considered */
659 : Word16 *exc_dct_in, /* o : dct of residual signal */
660 : Word16 last_coder_type, /* i : coding type of last frame */
661 : Word16 *bitallocation_band, /* i : bit allocation flag of each band */
662 : const Word16 *lsf_new, /* i : LSFs at the end of the frame */
663 : Word16 *last_exc_dct_in, /* i : dct of residual signal of last frame */
664 : Word16 *last_ener, /* i : frequency energy of last frame */
665 : Word16 *last_bitallocation_band, /* i : bit allocation flag of each band of last frame */
666 : Word16 *bitallocation_exc, /* i : flag of decoded coefficients */
667 : Word16 bfi, /* i : bad frame indicator */
668 : const Word16 coder_type, /* i : coder type */
669 : Word16 bwidth,
670 : Word16 *exc_wo_nf, /* o : temporal excitation (in f domain) without noisefill */
671 : Word16 Qexc_diffQ,
672 : Word16 Q_exc,
673 : const Word16 GSC_noisy_speech,
674 : Word16 *lt_ener_per_band_fx, /* i/o: Average per band energy */
675 : const Word16 L_frame, /* i : frame length */
676 : const Word16 element_mode, /* i : IVAS element mode */
677 : const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */
678 : )
679 : {
680 : Word16 i, j, k;
681 0 : Word16 MAX_Bin = 0;
682 0 : Word16 last_bin_tmp, ener = 0;
683 0 : move16();
684 : Word16 noisepb[MBANDS_GN16k];
685 : Word16 Ener_per_bd_yQ[MBANDS_GN16k];
686 : Word16 *src, *dst;
687 : Word32 L_tmp;
688 0 : Word16 length_bin, bwe_flag = 0, tmp;
689 0 : move16();
690 : Word16 frac, exp, tmp1;
691 : Word16 tmp2;
692 : Word16 *end, Q_hb_exc;
693 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
694 0 : Flag Overflow = 0;
695 0 : move16();
696 : #endif
697 :
698 0 : FOR( j = 10; j < MBANDS_GN; j++ )
699 : {
700 : /* ener += (float)pow(10, Ener_per_bd_iQ[j]);
701 : ener += (float)pow(2, 3.321928*Ener_per_bd_iQ[j]); */
702 :
703 0 : L_tmp = L_mult( Ener_per_bd_iQ[j], 27213 ); /* 3.321928 in Q13 -> Q27 */
704 0 : L_tmp = L_shr( L_tmp, 10 ); /* From Q27 to Q16 */
705 :
706 0 : frac = L_Extract_lc( L_tmp, &exp ); /* Extract exponent of L_tmp */
707 0 : tmp = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
708 : /* output of Pow2() will be: */
709 : /* 16384 < Pow2() <= 32767 */
710 0 : exp = sub( exp, 14 );
711 0 : tmp1 = shl_o( tmp, exp, &Overflow );
712 0 : move16();
713 0 : ener = add_o( tmp1, ener, &Overflow ); /*Q0 */
714 : }
715 :
716 0 : test();
717 0 : IF( EQ_32( core_brate, ACELP_8k00 ) && NE_16( bwidth, NB ) )
718 : {
719 0 : if ( NE_16( last_coder_type, AUDIO ) )
720 : {
721 0 : *last_ener = ener;
722 0 : move16();
723 : }
724 0 : test();
725 0 : test();
726 0 : IF( ( GT_16( last_bin, 8 ) || Diff_len != 0 ) && EQ_16( last_coder_type, AUDIO ) )
727 : {
728 0 : MAX_Bin = 10;
729 0 : move16();
730 0 : bwe_flag = 1;
731 0 : move16();
732 : }
733 : ELSE
734 : {
735 0 : MAX_Bin = 15;
736 0 : move16();
737 : }
738 :
739 0 : last_bin_tmp = last_bin;
740 0 : move16();
741 0 : last_bin = s_max( last_bin, MAX_Bin );
742 0 : last_bin = add( last_bin, 1 );
743 : }
744 : ELSE
745 : {
746 0 : IF( EQ_16( L_frame, L_FRAME16k ) )
747 : {
748 0 : last_bin = MBANDS_GN16k;
749 0 : move16();
750 : }
751 : ELSE
752 : {
753 0 : last_bin = MBANDS_GN;
754 0 : move16();
755 : }
756 0 : last_bin_tmp = last_bin;
757 0 : move16();
758 : }
759 :
760 0 : test();
761 0 : test();
762 0 : test();
763 0 : test();
764 0 : IF( bfi || LT_32( core_brate, 6000 ) || ( LT_32( core_brate, 8600 ) && EQ_16( coder_type, UNVOICED ) ) )
765 : {
766 0 : set16_fx( noisepb, 13107, MBANDS_GN ); /*0.4 in Q15 */
767 : }
768 0 : ELSE IF( EQ_16( GSC_IVAS_mode, 3 ) || ( GSC_IVAS_mode > 0 && EQ_16( GSC_noisy_speech, 1 ) ) )
769 : {
770 0 : set16_fx( noisepb, 13107 /*0.4f*/, MBANDS_GN16k );
771 : }
772 : ELSE
773 : {
774 0 : EstimateNoiseLevel_fx( noisepb, core_brate, Diff_len, last_bin, coder_type, noise_lev, pit_band_idx, last_bin_tmp, bwidth, L_frame );
775 : }
776 :
777 0 : IF( exc_wo_nf != NULL )
778 : {
779 0 : Copy( exc_diffQ, exc_wo_nf, L_frame );
780 : }
781 :
782 0 : test();
783 0 : test();
784 0 : test();
785 0 : IF( GSC_IVAS_mode == 0 && GSC_noisy_speech && !bfi && LE_16( element_mode, IVAS_SCE ) )
786 : {
787 0 : set16_fx( noisepb, 3277, MBANDS_GN );
788 : }
789 0 : test();
790 0 : IF( LT_32( core_brate, 6000 ) && LE_16( coder_type, UNVOICED ) )
791 : {
792 0 : FOR( i = 0; i < L_frame; i++ )
793 : {
794 0 : IF( exc_diffQ[i] == 0 )
795 : {
796 : /* exc_diffQ[i] += 2.0f * noisepb[0] * ((float)own_random(seed_tcx) / PCM16_TO_FLT_FAC);*/
797 0 : tmp = mult( shl( noisepb[0], 1 ), Random( seed_tcx ) ); /*Q15 */
798 0 : tmp = shr( tmp, sub( 15, Qexc_diffQ ) ); /*qNoise_fac */
799 0 : exc_diffQ[i] = add( exc_diffQ[i], tmp );
800 0 : move16(); /*Q */
801 : }
802 : }
803 : }
804 : ELSE
805 : {
806 0 : Apply_NoiseFill_fx( exc_diffQ, seed_tcx, noisepb, Diff_len, last_bin, coder_type, mfreq_bindiv, Qexc_diffQ );
807 : }
808 : /*--------------------------------------------------------------------------------------*
809 : * Quantize average gain
810 : * Subtract Q averaged gain
811 : * VQ of remaining gain per band
812 : *--------------------------------------------------------------------------------------*/
813 0 : test();
814 0 : IF( EQ_32( core_brate, ACELP_8k00 ) && NE_16( bwidth, NB ) )
815 : {
816 0 : Ener_per_band_comp_fx( exc_diffQ, Ener_per_bd_yQ, Qexc_diffQ, add( last_bin, 1 ), 0 );
817 : }
818 : ELSE
819 : {
820 0 : Ener_per_band_comp_fx( exc_diffQ, Ener_per_bd_yQ, Qexc_diffQ, MBANDS_GN, 1 );
821 :
822 0 : IF( LT_16( nb_subfr, 4 ) && LT_16( L_frame, L_FRAME16k ) )
823 : {
824 0 : FOR( i = L_FRAME - 16; i < L_FRAME; i++ )
825 : {
826 : /*exc_diffQ[i] *= 0.067f * i - 15.0f; = -15 - (-0.067f * i) */
827 0 : tmp = msu_r( -7680 * 65536, -17564, shl( i, 6 ) ); /*-15 in Q9; -0.067 in Q18 and i in Q6= Q9 */
828 0 : L_tmp = L_mult( exc_diffQ[i], tmp ); /*Q(Qexc_diffQ+10) */
829 0 : exc_diffQ[i] = round_fx( L_shl( L_tmp, 16 - 10 ) ); /*Qexc_diffQ */
830 0 : move16();
831 : }
832 : }
833 : }
834 : /*--------------------------------------------------------------------------------------*
835 : * Check potential energy excitation overshoot
836 : *--------------------------------------------------------------------------------------*/
837 0 : IF( bfi )
838 : {
839 0 : test();
840 0 : IF( GSC_noisy_speech == 0 && GT_16( coder_type, UNVOICED ) ) /* Here coder_type == last_coder_type because of the bfi */
841 : {
842 0 : FOR( i = 0; i < last_bin; i++ )
843 : {
844 0 : Ener_per_bd_iQ[i] = s_min( Ener_per_bd_iQ[i], sub( sub( lt_ener_per_band_fx[i], 154 ), Ener_per_bd_yQ[i] ) );
845 0 : move16();
846 0 : lt_ener_per_band_fx[i] = sub( lt_ener_per_band_fx[i], 77 );
847 0 : move16();
848 : }
849 0 : FOR( ; i < MBANDS_GN; i++ )
850 : {
851 0 : Ener_per_bd_iQ[i] = s_min( Ener_per_bd_iQ[i], sub( lt_ener_per_band_fx[i], 154 ) );
852 0 : move16();
853 0 : lt_ener_per_band_fx[i] = sub( lt_ener_per_band_fx[i], 77 );
854 0 : move16();
855 : }
856 : }
857 : ELSE
858 : {
859 0 : FOR( i = 0; i < last_bin; i++ )
860 : {
861 0 : Ener_per_bd_iQ[i] = s_min( Ener_per_bd_iQ[i], sub( add( lt_ener_per_band_fx[i], 1229 ), Ener_per_bd_yQ[i] ) );
862 0 : move16();
863 0 : lt_ener_per_band_fx[i] = sub( lt_ener_per_band_fx[i], 77 );
864 0 : move16();
865 : }
866 0 : FOR( ; i < MBANDS_GN; i++ )
867 : {
868 0 : Ener_per_bd_iQ[i] = s_min( Ener_per_bd_iQ[i], add( lt_ener_per_band_fx[i], 1229 ) );
869 0 : move16();
870 0 : lt_ener_per_band_fx[i] = sub( lt_ener_per_band_fx[i], 77 );
871 0 : move16();
872 : }
873 : }
874 : }
875 : /*--------------------------------------------------------------------------------------*
876 : * Apply decoded gain onto the difference signal
877 : *--------------------------------------------------------------------------------------*/
878 :
879 0 : IF( GSC_noisy_speech )
880 : {
881 0 : FOR( i = 0; i < L_frame; i++ )
882 : {
883 0 : exc_diffQ[i] = mult_r( exc_diffQ[i], 29491 );
884 0 : move16();
885 : }
886 : }
887 :
888 0 : Comp_and_apply_gain_fx( exc_diffQ, Ener_per_bd_iQ, Ener_per_bd_yQ, last_bin, 0, Qexc_diffQ, Q_exc );
889 :
890 0 : IF( exc_wo_nf != NULL )
891 : {
892 0 : Comp_and_apply_gain_fx( exc_wo_nf, Ener_per_bd_iQ, Ener_per_bd_yQ, last_bin, 1, Qexc_diffQ, Q_exc );
893 0 : Vr_add( exc_dct_in, exc_wo_nf, exc_wo_nf, L_frame );
894 : }
895 : /*--------------------------------------------------------------------------------------*
896 : * add the correction layer to the LF bins,
897 : * and add the quantized pulses or the noise for the higher part of the spectrum
898 : * (non valuable temporal content already zeroed)
899 : * DC is Zeroed
900 : *--------------------------------------------------------------------------------------*/
901 :
902 0 : Vr_add( exc_dct_in, exc_diffQ, exc_dct_in, L_frame );
903 0 : test();
904 0 : IF( core_brate == ACELP_8k00 && bwidth != NB )
905 : {
906 0 : IF( EQ_16( bwe_flag, 1 ) )
907 : {
908 0 : last_bin = sub( last_bin, 1 );
909 0 : tmp = i_mult( MAX_Bin, 16 );
910 0 : tmp1 = i_mult( last_bin, 16 );
911 0 : src = &exc_diffQ[L_FRAME - 1];
912 0 : move16();
913 0 : dst = &exc_dct_in[( tmp - 1 )];
914 0 : move16();
915 0 : end = &exc_diffQ[( tmp1 - 1 )];
916 0 : move16();
917 :
918 0 : WHILE( src > end )
919 : {
920 0 : *src-- = *dst--;
921 0 : move16();
922 : }
923 0 : test();
924 0 : test();
925 0 : if ( ( bitallocation_exc[0] != 0 || bitallocation_exc[1] != 0 ) && EQ_32( core_brate, ACELP_8k00 ) )
926 : {
927 0 : exc_diffQ[160] = 0;
928 0 : move16();
929 : }
930 :
931 0 : Q_hb_exc = 0;
932 0 : move16();
933 0 : envelop_modify_fx( exc_diffQ, seed_tcx, last_bin, Ener_per_bd_iQ, Q_exc, &Q_hb_exc );
934 0 : Copy_Scale_sig( &exc_diffQ[tmp1], &exc_dct_in[tmp1], sub( L_FRAME, tmp1 ), sub( Q_exc, Q_hb_exc ) ); /* from Q_hb_exc -> Q_exc as expected */
935 : }
936 :
937 0 : IF( LT_16( nb_subfr, 4 ) )
938 : {
939 0 : FOR( i = sub( L_FRAME, 16 ); i < L_FRAME; i++ )
940 : {
941 : /*exc_dct_in[i] *= (0.067f*i-15.f); */
942 0 : tmp = mult_r( 17564, shl( i, 6 ) ); /*0.067 in Q18 and i in Q6= Q9 */
943 0 : tmp = sub( tmp, 7680 ); /*15 in Q9 = Q9 */
944 0 : L_tmp = L_mult( exc_dct_in[i], tmp ); /*Q(Q_exc+10) */
945 0 : exc_dct_in[i] = round_fx_o( L_shl_o( L_tmp, 6, &Overflow ), &Overflow ); /*Q_exc */
946 : }
947 : }
948 :
949 0 : tmp1 = mult_r( ener, 16384 );
950 0 : tmp1 = sub( *last_ener, tmp1 );
951 0 : tmp = mult_r( *last_ener, 16384 );
952 0 : tmp = sub( ener, tmp );
953 0 : test();
954 0 : IF( tmp > 0 && tmp1 > 0 )
955 : {
956 0 : length_bin = 6;
957 0 : move16();
958 0 : IF( last_coder_type != AUDIO )
959 : {
960 0 : set16_fx( last_bitallocation_band, 0, 6 );
961 0 : Copy( &exc_dct_in[( 4 + length_bin ) * 16], &last_exc_dct_in[( 4 + length_bin ) * 16], length_bin * 16 );
962 : }
963 :
964 0 : FOR( i = 4; i < ( 4 + length_bin ); i++ )
965 : {
966 0 : test();
967 0 : IF( !( bitallocation_band[i] == 0 && last_bitallocation_band[i - 4] == 0 ) )
968 : {
969 0 : k = shl( add( i, length_bin ), 4 );
970 0 : src = &exc_dct_in[k]; /*(i+length_bin)*16*/
971 0 : dst = &last_exc_dct_in[k];
972 0 : FOR( j = 0; j < 16; j++ )
973 : {
974 0 : tmp = mult_r( 10923, abs_s( *src ) );
975 0 : tmp1 = mult_r( 10923, abs_s( *dst ) );
976 :
977 0 : IF( GT_16( tmp, abs_s( *dst ) ) )
978 : {
979 0 : tmp2 = *src;
980 0 : *src = mult_r( 16384, sub_o( *src, abs_s( *dst ), &Overflow ) ); /*Q_exc */
981 0 : move16();
982 0 : tmp = mult_r( 16384, add_o( tmp2, abs_s( *dst ), &Overflow ) ); /*Q_exc */
983 0 : if ( tmp2 > 0 )
984 : {
985 0 : *src = tmp;
986 0 : move16();
987 : }
988 : }
989 0 : ELSE IF( GT_16( tmp1, abs_s( *src ) ) )
990 : {
991 0 : tmp = mult_r( *src, 22938 );
992 0 : tmp1 = mult_r( 9830, abs_s( *dst ) );
993 0 : tmp2 = *src;
994 0 : *src = sub( tmp, tmp1 ); /*Q_exc */
995 0 : move16();
996 0 : if ( tmp2 > 0 )
997 : {
998 0 : *src = add( tmp, tmp1 ); /*Q_exc */
999 0 : move16();
1000 : }
1001 : }
1002 0 : src++;
1003 0 : dst++;
1004 : }
1005 : }
1006 : }
1007 : }
1008 0 : IF( EQ_16( bwe_flag, 1 ) )
1009 : {
1010 0 : Decreas_freqPeak_fx( lsf_new, exc_dct_in, 9830 );
1011 : }
1012 : ELSE
1013 : {
1014 0 : Decreas_freqPeak_fx( lsf_new, exc_dct_in, 16384 );
1015 : }
1016 : }
1017 :
1018 0 : Copy( &exc_dct_in[64], &last_exc_dct_in[64], L_frame - 64 );
1019 0 : Copy( &bitallocation_band[4], last_bitallocation_band, 6 );
1020 0 : *last_ener = ener;
1021 0 : move16();
1022 :
1023 0 : return;
1024 : }
1025 :
1026 20762 : void highband_exc_dct_in_ivas_fx(
1027 : const Word32 core_brate, /* i : core bitrate */
1028 : const Word16 *mfreq_bindiv, /* i : bin per bands tables */
1029 : Word16 last_bin, /* i : last bin of bit allocation */
1030 : Word16 Diff_len, /* i : number of bin before cut-off frequency */
1031 : Word16 noise_lev, /* i : pulses dynamic */
1032 : Word16 pit_band_idx, /* i : bin position of the cut-off frequency */
1033 : Word16 *exc_diffQ, /* i : frequency coefficients of per band */
1034 : Word16 *seed_tcx, /* i : Seed for noise */
1035 : Word16 *Ener_per_bd_iQ, /* i : Quantized energy of targeted vector */
1036 : Word16 nb_subfr, /* i : Number of subframe considered */
1037 : Word16 *exc_dct_in, /* o : dct of residual signal */
1038 : Word16 last_coder_type, /* i : coding type of last frame */
1039 : Word16 *bitallocation_band, /* i : bit allocation flag of each band */
1040 : const Word16 *lsf_new, /* i : LSFs at the end of the frame */
1041 : Word16 *last_exc_dct_in, /* i : dct of residual signal of last frame */
1042 : Word16 *last_ener, /* i : frequency energy of last frame */
1043 : Word16 *last_bitallocation_band, /* i : bit allocation flag of each band of last frame */
1044 : Word16 *bitallocation_exc, /* i : flag of decoded coefficients */
1045 : Word16 bfi, /* i : bad frame indicator */
1046 : const Word16 coder_type, /* i : coder type */
1047 : Word16 bwidth,
1048 : Word16 *exc_wo_nf, /* o : temporal excitation (in f domain) without noisefill */
1049 : Word16 Qexc_diffQ,
1050 : Word16 *Q_exc,
1051 : const Word16 GSC_noisy_speech,
1052 : Word16 *lt_ener_per_band_fx, /* i/o: Average per band energy */
1053 : const Word16 L_frame, /* i : frame length */
1054 : const Word16 element_mode, /* i : IVAS element mode */
1055 : const Word16 GSC_IVAS_mode /* i : GSC IVAS mode */
1056 : )
1057 : {
1058 : Word16 i, j, k;
1059 20762 : Word16 MAX_Bin = 0;
1060 20762 : Word16 last_bin_tmp, ener = 0;
1061 20762 : move16();
1062 : Word16 noisepb[MBANDS_GN16k];
1063 : Word16 Ener_per_bd_yQ[MBANDS_GN16k];
1064 : Word16 *src, *dst;
1065 : Word32 L_tmp;
1066 20762 : Word16 length_bin, bwe_flag = 0, tmp;
1067 20762 : move16();
1068 : Word16 frac, exp, tmp1;
1069 : Word16 tmp2;
1070 : Word16 *end, Q_hb_exc;
1071 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1072 20762 : Flag Overflow = 0;
1073 20762 : move16();
1074 : #endif
1075 :
1076 145334 : FOR( j = 10; j < MBANDS_GN; j++ )
1077 : {
1078 : /* ener += (float)pow(10, Ener_per_bd_iQ[j]);
1079 : ener += (float)pow(2, 3.321928*Ener_per_bd_iQ[j]); */
1080 :
1081 124572 : L_tmp = L_mult( Ener_per_bd_iQ[j], 27213 ); /* 3.321928 in Q13 -> Q27 */
1082 124572 : L_tmp = L_shr( L_tmp, 10 ); /* From Q27 to Q16 */
1083 :
1084 124572 : frac = L_Extract_lc( L_tmp, &exp ); /* Extract exponent of L_tmp */
1085 124572 : tmp = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
1086 : /* output of Pow2() will be: */
1087 : /* 16384 < Pow2() <= 32767 */
1088 124572 : exp = sub( exp, 14 );
1089 124572 : tmp1 = shl_o( tmp, exp, &Overflow );
1090 124572 : move16();
1091 124572 : ener = add_o( tmp1, ener, &Overflow ); /*Q0 */
1092 : }
1093 :
1094 20762 : test();
1095 20762 : IF( EQ_32( core_brate, ACELP_8k00 ) && NE_16( bwidth, NB ) )
1096 : {
1097 20 : IF( NE_16( last_coder_type, AUDIO ) )
1098 : {
1099 14 : *last_ener = ener;
1100 14 : move16();
1101 : }
1102 20 : test();
1103 20 : test();
1104 20 : IF( ( GT_16( last_bin, 8 ) || Diff_len != 0 ) && EQ_16( last_coder_type, AUDIO ) )
1105 : {
1106 6 : MAX_Bin = 10;
1107 6 : move16();
1108 6 : bwe_flag = 1;
1109 6 : move16();
1110 : }
1111 : ELSE
1112 : {
1113 14 : MAX_Bin = 15;
1114 14 : move16();
1115 : }
1116 :
1117 20 : last_bin_tmp = last_bin;
1118 20 : move16();
1119 20 : last_bin = s_max( last_bin, MAX_Bin );
1120 20 : last_bin = add( last_bin, 1 );
1121 : }
1122 : ELSE
1123 : {
1124 20742 : IF( EQ_16( L_frame, L_FRAME16k ) )
1125 : {
1126 2529 : last_bin = MBANDS_GN16k;
1127 2529 : move16();
1128 : }
1129 : ELSE
1130 : {
1131 18213 : last_bin = MBANDS_GN;
1132 18213 : move16();
1133 : }
1134 20742 : last_bin_tmp = last_bin;
1135 20742 : move16();
1136 : }
1137 :
1138 20762 : test();
1139 20762 : test();
1140 20762 : test();
1141 20762 : test();
1142 20762 : IF( bfi || LT_32( core_brate, 6000 ) || ( LT_32( core_brate, 8600 ) && EQ_16( coder_type, UNVOICED ) ) )
1143 : {
1144 6885 : set16_fx( noisepb, 13107, MBANDS_GN ); /*0.4 in Q15 */
1145 : }
1146 13877 : ELSE IF( EQ_16( GSC_IVAS_mode, 3 ) || ( GSC_IVAS_mode > 0 && EQ_16( GSC_noisy_speech, 1 ) ) )
1147 : {
1148 2378 : set16_fx( noisepb, 13107 /*0.4f*/, MBANDS_GN16k );
1149 : }
1150 : ELSE
1151 : {
1152 11499 : EstimateNoiseLevel_fx( noisepb, core_brate, Diff_len, last_bin, coder_type, noise_lev, pit_band_idx, last_bin_tmp, bwidth, L_frame );
1153 : }
1154 :
1155 20762 : IF( exc_wo_nf != NULL )
1156 : {
1157 20560 : Copy( exc_diffQ, exc_wo_nf, L_frame );
1158 : }
1159 :
1160 20762 : test();
1161 20762 : test();
1162 :
1163 20762 : IF( GSC_IVAS_mode == 0 && GSC_noisy_speech && !bfi && LE_16( element_mode, IVAS_SCE ) )
1164 : {
1165 7158 : set16_fx( noisepb, 3277, MBANDS_GN );
1166 : }
1167 :
1168 20762 : test();
1169 20762 : IF( LT_32( core_brate, 6000 ) && LE_16( coder_type, UNVOICED ) )
1170 : {
1171 1723956 : FOR( i = 0; i < L_frame; i++ )
1172 : {
1173 1717248 : IF( exc_diffQ[i] == 0 )
1174 : {
1175 : /* exc_diffQ[i] += 2.0f * noisepb[0] * ((float)own_random(seed_tcx) / PCM16_TO_FLT_FAC);*/
1176 1703284 : tmp = mult( shl( noisepb[0], 1 ), Random( seed_tcx ) ); /*Q15 */
1177 1703284 : tmp = shr( tmp, sub( 15, Qexc_diffQ ) ); /*qNoise_fac */
1178 1703284 : exc_diffQ[i] = add( exc_diffQ[i], tmp );
1179 1703284 : move16(); /*Q */
1180 : }
1181 : }
1182 : }
1183 : ELSE
1184 : {
1185 14054 : Apply_NoiseFill_fx( exc_diffQ, seed_tcx, noisepb, Diff_len, last_bin, coder_type, mfreq_bindiv, Qexc_diffQ );
1186 : }
1187 : /*--------------------------------------------------------------------------------------*
1188 : * Quantize average gain
1189 : * Subtract Q averaged gain
1190 : * VQ of remaining gain per band
1191 : *--------------------------------------------------------------------------------------*/
1192 20762 : test();
1193 20762 : IF( EQ_32( core_brate, ACELP_8k00 ) && NE_16( bwidth, NB ) )
1194 : {
1195 20 : Ener_per_band_comp_ivas_fx( exc_diffQ, Ener_per_bd_yQ, Qexc_diffQ, add( last_bin, 1 ), 0, L_frame );
1196 : }
1197 : ELSE
1198 : {
1199 20742 : Ener_per_band_comp_ivas_fx( exc_diffQ, Ener_per_bd_yQ, Qexc_diffQ, MBANDS_GN, 1, L_frame );
1200 :
1201 20742 : test();
1202 20742 : IF( LT_16( nb_subfr, 4 ) && LT_16( L_frame, L_FRAME16k ) )
1203 : {
1204 255493 : FOR( i = L_FRAME - 16; i < L_FRAME; i++ )
1205 : {
1206 : /*exc_diffQ[i] *= 0.067f * i - 15.0f; = -15 - (-0.067f * i) */
1207 240464 : tmp = msu_r( -7680 * 65536, -17564, shl( i, 6 ) ); /*-15 in Q9; -0.067 in Q18 and i in Q6= Q9 */
1208 240464 : L_tmp = L_mult( exc_diffQ[i], tmp ); /*Q(Qexc_diffQ+10) */
1209 240464 : exc_diffQ[i] = round_fx( L_shl( L_tmp, 16 - 10 ) ); /*Qexc_diffQ */
1210 240464 : move16();
1211 : }
1212 : }
1213 : }
1214 : /*--------------------------------------------------------------------------------------*
1215 : * Check potential energy excitation overshoot
1216 : *--------------------------------------------------------------------------------------*/
1217 20762 : IF( bfi )
1218 : {
1219 202 : test();
1220 202 : IF( GSC_noisy_speech == 0 && GT_16( coder_type, UNVOICED ) ) /* Here coder_type == last_coder_type because of the bfi */
1221 : {
1222 1394 : FOR( i = 0; i < last_bin; i++ )
1223 : {
1224 1312 : Ener_per_bd_iQ[i] = s_min( Ener_per_bd_iQ[i], sub_sat( sub_sat( lt_ener_per_band_fx[i], 154 ), Ener_per_bd_yQ[i] ) );
1225 1312 : move16();
1226 1312 : lt_ener_per_band_fx[i] = sub_sat( lt_ener_per_band_fx[i], 77 );
1227 1312 : move16();
1228 : }
1229 82 : FOR( ; i < MBANDS_GN; i++ )
1230 : {
1231 0 : Ener_per_bd_iQ[i] = s_min( Ener_per_bd_iQ[i], sub( lt_ener_per_band_fx[i], 154 ) );
1232 0 : move16();
1233 0 : lt_ener_per_band_fx[i] = sub( lt_ener_per_band_fx[i], 77 );
1234 0 : move16();
1235 : }
1236 : }
1237 : ELSE
1238 : {
1239 2048 : FOR( i = 0; i < last_bin; i++ )
1240 : {
1241 1928 : Ener_per_bd_iQ[i] = s_min( Ener_per_bd_iQ[i], sub_sat( add( lt_ener_per_band_fx[i], 1229 ), Ener_per_bd_yQ[i] ) );
1242 1928 : move16();
1243 1928 : lt_ener_per_band_fx[i] = sub_sat( lt_ener_per_band_fx[i], 77 );
1244 1928 : move16();
1245 : }
1246 120 : FOR( ; i < MBANDS_GN; i++ )
1247 : {
1248 0 : Ener_per_bd_iQ[i] = s_min( Ener_per_bd_iQ[i], add( lt_ener_per_band_fx[i], 1229 ) );
1249 0 : move16();
1250 0 : lt_ener_per_band_fx[i] = sub( lt_ener_per_band_fx[i], 77 );
1251 0 : move16();
1252 : }
1253 : }
1254 : }
1255 :
1256 : /*--------------------------------------------------------------------------------------*
1257 : * Apply decoded gain onto the difference signal
1258 : *--------------------------------------------------------------------------------------*/
1259 :
1260 20762 : IF( GSC_IVAS_mode >= 1 )
1261 : {
1262 4128 : Word16 scale_factLF = 29491; /* 0.9f */
1263 4128 : move16();
1264 4128 : Word16 scale_factHF = 29491; /* 0.9f */
1265 4128 : move16();
1266 :
1267 4128 : test();
1268 4128 : test();
1269 4128 : IF( EQ_16( GSC_IVAS_mode, 1 ) && GSC_noisy_speech == 0 )
1270 : {
1271 1532 : scale_factHF = 26214;
1272 1532 : move16();
1273 : }
1274 2596 : ELSE IF( EQ_16( GSC_IVAS_mode, 2 ) || EQ_16( GSC_noisy_speech, 1 ) )
1275 : {
1276 317 : scale_factHF = 23265; /* 0.71f */
1277 317 : move16();
1278 : }
1279 2279 : ELSE IF( EQ_16( GSC_IVAS_mode, 3 ) )
1280 : {
1281 2279 : scale_factHF = 29491; /* 0.9f */
1282 2279 : move16();
1283 : }
1284 572688 : FOR( i = 0; i < pit_band_idx * 16; i++ )
1285 : {
1286 568560 : exc_diffQ[i] = mult_r( exc_diffQ[i], scale_factLF );
1287 : }
1288 492336 : FOR( ; i < L_frame; i++ )
1289 : {
1290 488208 : exc_diffQ[i] = mult_r( exc_diffQ[i], scale_factHF );
1291 488208 : move16();
1292 : }
1293 : }
1294 16634 : ELSE IF( GSC_noisy_speech )
1295 : {
1296 7536 : Word16 scale_fact = 29491; /* 0.9f */
1297 7536 : move16();
1298 :
1299 7536 : IF( EQ_16( element_mode, IVAS_CPE_TD ) )
1300 : {
1301 27 : IF( coder_type == INACTIVE )
1302 : {
1303 0 : scale_fact = 32767; /* 1.0f */
1304 0 : move16();
1305 : }
1306 : ELSE
1307 : {
1308 27 : scale_fact = 31129; /* 0.95f */
1309 27 : move16();
1310 : }
1311 : }
1312 7509 : ELSE IF( GT_16( element_mode, IVAS_SCE ) )
1313 : {
1314 305 : scale_fact = 23265; /* 0.71f */
1315 305 : move16();
1316 : }
1317 :
1318 1936752 : FOR( i = 0; i < L_frame; i++ )
1319 : {
1320 1929216 : exc_diffQ[i] = mult_r( exc_diffQ[i], scale_fact );
1321 1929216 : move16();
1322 : }
1323 : }
1324 :
1325 20762 : IF( GSC_noisy_speech && GT_16( element_mode, IVAS_SCE ) && LT_32( core_brate, ACELP_7k20 ) )
1326 : {
1327 4602 : FOR( i = 80; i < L_frame; i++ )
1328 : {
1329 : /* exc_diffQ[i] *= (+0.0024f * (float)i + 1.192f); */
1330 4576 : exc_diffQ[i] = mult_r( shl( exc_diffQ[i], 1 ) /*Q16*/, (Word16) L_shr( L_add( 629 * i, 312475 ) /*Q18*/, Q4 ) /*Q14*/ );
1331 4576 : move16();
1332 : }
1333 : }
1334 :
1335 20762 : IF( EQ_16( element_mode, EVS_MONO ) )
1336 : {
1337 6 : Comp_and_apply_gain_fx( exc_diffQ, Ener_per_bd_iQ, Ener_per_bd_yQ, last_bin, 0, Qexc_diffQ, *Q_exc );
1338 :
1339 6 : IF( exc_wo_nf != NULL )
1340 : {
1341 6 : Comp_and_apply_gain_fx( exc_wo_nf, Ener_per_bd_iQ, Ener_per_bd_yQ, last_bin, 1, Qexc_diffQ, *Q_exc );
1342 6 : Vr_add( exc_dct_in, exc_wo_nf, exc_wo_nf, L_frame );
1343 : }
1344 : }
1345 : ELSE
1346 : {
1347 20756 : Word16 Q_tmp = *Q_exc;
1348 20756 : move16();
1349 20756 : Word16 Q_old = *Q_exc;
1350 20756 : move16();
1351 20756 : Comp_and_apply_gain_ivas_fx( exc_diffQ, Ener_per_bd_iQ, Ener_per_bd_yQ, last_bin, 0, Qexc_diffQ, Q_exc );
1352 :
1353 20756 : IF( exc_wo_nf != NULL )
1354 : {
1355 20554 : Comp_and_apply_gain_ivas_fx( exc_wo_nf, Ener_per_bd_iQ, Ener_per_bd_yQ, last_bin, 1, Qexc_diffQ, &Q_tmp );
1356 20554 : IF( GT_16( Q_tmp, *Q_exc ) )
1357 : {
1358 0 : Scale_sig( exc_wo_nf, L_frame, sub( *Q_exc, Q_tmp ) );
1359 : }
1360 20554 : ELSE IF( LT_16( Q_tmp, *Q_exc ) )
1361 : {
1362 3 : Scale_sig( exc_diffQ, L_frame, sub( Q_tmp, *Q_exc ) );
1363 3 : *Q_exc = Q_tmp;
1364 3 : move16();
1365 : }
1366 20554 : Scale_sig( exc_dct_in, L_frame, sub( *Q_exc, Q_old ) );
1367 20554 : Vr_add( exc_dct_in, exc_wo_nf, exc_wo_nf, L_frame );
1368 : }
1369 : ELSE
1370 : {
1371 202 : Scale_sig( exc_dct_in, L_frame, sub( *Q_exc, Q_old ) );
1372 : }
1373 : }
1374 :
1375 : /*--------------------------------------------------------------------------------------*
1376 : * add the correction layer to the LF bins,
1377 : * and add the quantized pulses or the noise for the higher part of the spectrum
1378 : * (non valuable temporal content already zeroed)
1379 : * DC is Zeroed
1380 : *--------------------------------------------------------------------------------------*/
1381 :
1382 20762 : Vr_add( exc_dct_in, exc_diffQ, exc_dct_in, L_frame );
1383 20762 : test();
1384 20762 : IF( EQ_32( core_brate, ACELP_8k00 ) && bwidth != NB )
1385 : {
1386 20 : IF( EQ_16( bwe_flag, 1 ) )
1387 : {
1388 6 : last_bin = sub( last_bin, 1 );
1389 6 : tmp = i_mult( MAX_Bin, 16 );
1390 6 : tmp1 = i_mult( last_bin, 16 );
1391 6 : src = &exc_diffQ[( L_FRAME - 1 )];
1392 6 : move16();
1393 6 : dst = &exc_dct_in[( tmp - 1 )];
1394 6 : move16();
1395 6 : end = &exc_diffQ[( tmp1 - 1 )];
1396 6 : move16();
1397 :
1398 582 : WHILE( src > end )
1399 : {
1400 576 : *src-- = *dst--;
1401 576 : move16();
1402 : }
1403 6 : test();
1404 6 : test();
1405 6 : IF( ( bitallocation_exc[0] != 0 || bitallocation_exc[1] != 0 ) && EQ_32( core_brate, ACELP_8k00 ) )
1406 : {
1407 0 : exc_diffQ[160] = 0;
1408 0 : move16();
1409 : }
1410 :
1411 6 : Q_hb_exc = 0;
1412 6 : move16();
1413 6 : envelop_modify_fx( exc_diffQ, seed_tcx, last_bin, Ener_per_bd_iQ, *Q_exc, &Q_hb_exc );
1414 :
1415 6 : test();
1416 6 : test();
1417 6 : IF( GT_16( *Q_exc, Q_hb_exc ) && GT_16( element_mode, EVS_MONO ) && exc_wo_nf != NULL )
1418 : {
1419 0 : Scale_sig( exc_wo_nf, L_frame, sub( Q_hb_exc, *Q_exc ) );
1420 0 : *Q_exc = Q_hb_exc;
1421 0 : move16();
1422 : }
1423 : ELSE
1424 : {
1425 6 : Scale_sig( &exc_diffQ[tmp1], sub( L_FRAME, tmp1 ), sub( *Q_exc, Q_hb_exc ) );
1426 : }
1427 6 : Copy( &exc_diffQ[tmp1], &exc_dct_in[tmp1], sub( L_FRAME, tmp1 ) ); /* from Q_hb_exc -> Q_exc as expected */
1428 : }
1429 :
1430 20 : IF( LT_16( nb_subfr, 4 ) )
1431 : {
1432 85 : FOR( i = sub( L_FRAME, 16 ); i < L_FRAME; i++ )
1433 : {
1434 : /*exc_dct_in[i] *= (0.067f*i-15.f); */
1435 80 : tmp = mult_r( 17564, shl( i, 6 ) ); /*0.067 in Q18 and i in Q6= Q9 */
1436 80 : tmp = sub( tmp, 7680 ); /*15 in Q9 = Q9 */
1437 80 : L_tmp = L_mult( exc_dct_in[i], tmp ); /*Q(Q_exc+10) */
1438 80 : exc_dct_in[i] = round_fx_o( L_shl_o( L_tmp, 6, &Overflow ), &Overflow ); /*Q_exc */
1439 : }
1440 : }
1441 :
1442 20 : tmp1 = mult_r( ener, 16384 );
1443 20 : tmp1 = sub( *last_ener, tmp1 );
1444 20 : tmp = mult_r( *last_ener, 16384 );
1445 20 : tmp = sub( ener, tmp );
1446 20 : test();
1447 20 : IF( tmp > 0 && tmp1 > 0 )
1448 : {
1449 20 : length_bin = 6;
1450 20 : move16();
1451 20 : IF( last_coder_type != AUDIO )
1452 : {
1453 14 : set16_fx( last_bitallocation_band, 0, 6 );
1454 14 : Copy( &exc_dct_in[( 4 + length_bin ) * 16], &last_exc_dct_in[( 4 + length_bin ) * 16], length_bin * 16 );
1455 : }
1456 :
1457 140 : FOR( i = 4; i < ( 4 + length_bin ); i++ )
1458 : {
1459 120 : test();
1460 120 : IF( !( bitallocation_band[i] == 0 && last_bitallocation_band[i - 4] == 0 ) )
1461 : {
1462 100 : k = shl( add( i, length_bin ), 4 );
1463 100 : src = &exc_dct_in[k]; /*(i+length_bin)*16*/
1464 100 : dst = &last_exc_dct_in[k];
1465 1700 : FOR( j = 0; j < 16; j++ )
1466 : {
1467 1600 : tmp = mult_r( 10923, abs_s( *src ) );
1468 1600 : tmp1 = mult_r( 10923, abs_s( *dst ) );
1469 :
1470 1600 : IF( GT_16( tmp, abs_s( *dst ) ) )
1471 : {
1472 114 : tmp2 = *src;
1473 114 : *src = mult_r( 16384, sub_o( *src, abs_s( *dst ), &Overflow ) ); /*Q_exc */
1474 114 : move16();
1475 114 : tmp = mult_r( 16384, add_o( tmp2, abs_s( *dst ), &Overflow ) ); /*Q_exc */
1476 114 : IF( tmp2 > 0 )
1477 : {
1478 72 : *src = tmp;
1479 72 : move16();
1480 : }
1481 : }
1482 1486 : ELSE IF( GT_16( tmp1, abs_s( *src ) ) )
1483 : {
1484 126 : tmp = mult_r( *src, 22938 );
1485 126 : tmp1 = mult_r( 9830, abs_s( *dst ) );
1486 126 : tmp2 = *src;
1487 126 : *src = sub( tmp, tmp1 ); /*Q_exc */
1488 126 : move16();
1489 126 : IF( tmp2 > 0 )
1490 : {
1491 72 : *src = add( tmp, tmp1 ); /*Q_exc */
1492 72 : move16();
1493 : }
1494 : }
1495 1600 : src++;
1496 1600 : dst++;
1497 : }
1498 : }
1499 : }
1500 : }
1501 20 : IF( EQ_16( bwe_flag, 1 ) )
1502 : {
1503 6 : Decreas_freqPeak_fx( lsf_new, exc_dct_in, 9830 );
1504 : }
1505 : ELSE
1506 : {
1507 14 : Decreas_freqPeak_fx( lsf_new, exc_dct_in, 16384 );
1508 : }
1509 : }
1510 :
1511 20762 : Copy( &exc_dct_in[64], &last_exc_dct_in[64], L_frame - 64 );
1512 20762 : Copy( &bitallocation_band[4], last_bitallocation_band, 6 );
1513 20762 : *last_ener = ener;
1514 20762 : move16();
1515 :
1516 20762 : return;
1517 : }
|