Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 : #include <stdint.h>
6 : #include "options.h" /* Compilation switches */
7 : #include "prot_fx.h" /* Function prototypes */
8 : #include "cnst.h" /* Function prototypes */
9 :
10 : /*---------------------------------------------------------------------*
11 : * Local function prototypes
12 : *---------------------------------------------------------------------*/
13 :
14 : #define TILT_COMP_LIM_FX 24576 /* 0.75 in Q15 */
15 : #define GE_SHIFT 6
16 : #define P1 ( 32768 - ISP_SMOOTHING_QUANT_A1_FX - 1 )
17 : #define P9 ( 32767 - P1 )
18 :
19 : /*---------------------------------------------------------*
20 : * Local functions
21 : *---------------------------------------------------------*/
22 :
23 : static Word16 calc_tilt_fx( const Word16 *x, const Word16 Q_shift, const Word16 len );
24 : Word32 L_Sqrt_Q0( const Word32 x );
25 : /*--------------------------------------------------------------------*
26 : * stat_noise_uv_mod()
27 : *
28 : * Modifies excitation signal in stationary noise segments
29 : *--------------------------------------------------------------------*/
30 :
31 4369 : void stat_noise_uv_mod_fx(
32 : const Word16 coder_type, /* i : Coder type */
33 : Word16 noisiness, /* i : noisiness parameter Q0 */
34 : const Word16 *lsp_old, /* i : old LSP vector at 4th sfr Q15 */
35 : const Word16 *lsp_new, /* i : LSP vector at 4th sfr Q15 */
36 : const Word16 *lsp_mid, /* i : LSP vector at 2nd sfr Q15 */
37 : Word16 *Aq, /* o : A(z) quantized for the 4 subframes Q12 */
38 : Word16 *exc2, /* i/o: excitation buffer Q_exc */
39 : Word16 Q_exc, /* i : Q of exc2 excitation buffer [11..-1] expected */
40 : const Word16 bfi, /* i : Bad frame indicator */
41 : Word32 *ge_sm, /* i/o: smoothed excitation gain Q_ge */
42 : Word16 *uv_count, /* i/o: unvoiced counter */
43 : Word16 *act_count, /* i/o: activation counter */
44 : Word16 lspold_s[], /* i/o: old LSP Q15 */
45 : Word16 *noimix_seed, /* i/o: mixture seed Q0 */
46 : Word16 *st_min_alpha, /* i/o: minimum alpha Q15 */
47 : Word16 *exc_pe, /* i/o: scale Q_stat_noise Q_stat_noise */
48 : const Word32 bitrate, /* i : core bitrate */
49 : const Word16 bwidth_fx, /* i : input bandwidth */
50 : Word16 *Q_stat_noise, /* i/o: noise scaling */
51 : Word16 *Q_stat_noise_ge /* i/o: noise scaling */
52 : )
53 : {
54 : Word16 exctilt; /* Q15 */
55 : Word32 vare; /* Q31 */
56 : Word16 randval; /* Q?? */
57 : Word16 alpha; /* Q15 */
58 : Word16 alpha_m1; /* (1-alpha) Q15 */
59 : Word16 min_alpha; /* Q15 */
60 : Word16 lspnew_s[M]; /* Same for all LSP (Q15) */
61 : Word16 oldlsp_mix[M];
62 : Word16 midlsp_mix[M];
63 : Word16 newlsp_mix[M];
64 : Word16 beta; /* Q15 */
65 : Word16 Noimix_fract; /* (noimix_fac - 1.0) in Q15 */
66 : /* noimix_fax * x <-> x + Noimix_fract * x */
67 : Word16 i_subfr;
68 : Word16 i, k;
69 :
70 : /* Work variables for div and sqrt */
71 : Word16 tmp_nom, tmp_den, tmp_shift, tmp_res;
72 : Word16 Qdiff, Q_local; /* new Q to be used for states Exc_pe and Ge_sm, and Exc2_local */
73 : Word32 L_tmp_res, L_tmp, L_tmp3, L_Ge;
74 :
75 : Word16 En_shift, Tmp;
76 : Word16 Exc2_local[L_FRAME]; /* local_copy in scaled Q_local*/
77 : #ifndef ISSUE_1836_replace_overflow_libcom
78 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
79 : Flag Overflow = 0;
80 : move32();
81 : #endif
82 : #endif
83 :
84 : /*---------------------------------------------------------*
85 : * Init local variables
86 : *---------------------------------------------------------*/
87 4369 : alpha = 32767;
88 4369 : move16();
89 4369 : min_alpha = 16384;
90 4369 : move16();
91 :
92 4369 : test();
93 4369 : test();
94 4369 : test();
95 4369 : IF( EQ_16( coder_type, INACTIVE ) && ( EQ_32( bitrate, ACELP_9k60 ) || ( LT_32( bitrate, ACELP_9k60 ) && GT_16( bwidth_fx, NB ) ) ) )
96 : {
97 0 : min_alpha = *st_min_alpha;
98 0 : move16();
99 : /*---------------------------------------------------------*
100 : * decode noisiness parameter
101 : *---------------------------------------------------------*/
102 0 : IF( bfi == 0 )
103 : {
104 0 : tmp_den = 31;
105 0 : move16();
106 0 : tmp_shift = norm_s( tmp_den );
107 0 : move16();
108 0 : L_tmp_res = L_deposit_h( noisiness );
109 0 : L_tmp_res = L_shl( L_tmp_res, sub( tmp_shift, 1 ) );
110 0 : tmp_den = shl( tmp_den, tmp_shift );
111 0 : move16();
112 0 : tmp_res = div_l( L_tmp_res, tmp_den );
113 0 : move16();
114 : #ifdef ISSUE_1836_replace_overflow_libcom
115 0 : min_alpha = add_sat( tmp_res, 16384 );
116 : #else
117 : min_alpha = add_o( tmp_res, 16384, &Overflow );
118 : #endif
119 0 : move16();
120 :
121 : /**st_min_alpha = sub(*st_min_alpha, 1638); move16();*/
122 0 : min_alpha = s_max( min_alpha, sub( *st_min_alpha, 1638 ) );
123 :
124 0 : *st_min_alpha = min_alpha;
125 0 : move16();
126 : }
127 : }
128 :
129 : /*---------------------------------------------------------*
130 : * Mix excitation signal with random noise
131 : *---------------------------------------------------------*/
132 4369 : test();
133 4369 : test();
134 4369 : test();
135 4369 : IF( EQ_16( coder_type, INACTIVE ) && ( EQ_32( bitrate, ACELP_9k60 ) || ( LT_32( bitrate, ACELP_9k60 ) && GT_16( bwidth_fx, NB ) ) ) )
136 : {
137 : /* use a local working copy for scaling and filtering, not needed if input Q-range is fixed */
138 0 : Copy( exc2, Exc2_local, L_FRAME );
139 :
140 : /* bound Q for internal use, optimization possible */
141 0 : Q_local = s_min( 11, s_max( -1, Q_exc ) );
142 : /* local excitation Q and incoming excitation Q*/
143 0 : Qdiff = sub( Q_local, Q_exc );
144 : /* only shift if incoming Q is outside [11..-1] shift is done in energy calculations aswell */
145 0 : Scale_sig( Exc2_local, L_FRAME, Qdiff );
146 : /* current excitation Q and previous stat_noise states Q */
147 0 : Qdiff = sub( Q_local, *Q_stat_noise );
148 :
149 0 : *Q_stat_noise_ge = GE_SHIFT;
150 0 : move16(); /* assign the fixed Q for Ge_sm */
151 :
152 0 : IF( Qdiff != 0 )
153 : {
154 0 : Scale_sig( exc_pe, 1, Qdiff );
155 : }
156 :
157 0 : En_shift = 0;
158 0 : move16();
159 0 : if ( GT_16( Q_local, 3 ) )
160 : {
161 : /* increase margin for energy accumulation in calc_tilt and vare accumulation */
162 0 : En_shift = sub( Q_local, 3 );
163 : }
164 :
165 0 : IF( LT_16( min_alpha, TILT_COMP_LIM_FX ) )
166 : {
167 0 : FOR( i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR )
168 : {
169 0 : exctilt = calc_tilt_fx( &Exc2_local[i_subfr], En_shift, L_SUBFR ); /*Q15 */
170 : #ifdef ISSUE_1836_replace_overflow_libcom
171 0 : exctilt = mult( shl_sat( sub( TILT_COMP_LIM_FX, min_alpha ), 2 ), exctilt ); /*Q15 */ //??Sat
172 : #else
173 : exctilt = mult( shl_o( sub( TILT_COMP_LIM_FX, min_alpha ), 2, &Overflow ), exctilt ); /*Q15 */
174 : #endif
175 :
176 0 : PREEMPH_FX( &Exc2_local[i_subfr], exctilt, L_SUBFR, exc_pe );
177 : }
178 : }
179 :
180 0 : ( *uv_count )++;
181 :
182 0 : IF( LE_16( *uv_count, START_NG ) )
183 : {
184 0 : alpha = 32767;
185 0 : move16();
186 0 : *act_count = 3;
187 0 : move16();
188 0 : Copy( lsp_new, lspold_s, M );
189 : }
190 : ELSE
191 : {
192 0 : *uv_count = s_min( *uv_count, FULL_NG );
193 0 : move16();
194 0 : tmp_nom = sub( *uv_count, START_NG );
195 0 : tmp_den = sub( FULL_NG, START_NG );
196 0 : tmp_shift = norm_s( tmp_den );
197 0 : tmp_den = shl( tmp_den, tmp_shift );
198 0 : tmp_res = div_s( tmp_nom, tmp_den );
199 : #ifdef ISSUE_1836_replace_overflow_libcom
200 0 : tmp_res = shl_sat( tmp_res, tmp_shift ); //??Sat
201 : #else
202 : tmp_res = shl_o( tmp_res, tmp_shift, &Overflow );
203 : #endif
204 0 : alpha = add( 32767, mult( tmp_res, sub( min_alpha, 32767 ) ) );
205 :
206 0 : *act_count = 0;
207 0 : move16();
208 : }
209 :
210 : /*---------------------------------------------------------*
211 : * calculate lowpass filtered excitation gain
212 : *---------------------------------------------------------*/
213 0 : Tmp = shr( Exc2_local[0], En_shift );
214 0 : vare = L_mult( Tmp, Tmp ); /* positive accumulation only */
215 0 : FOR( i = 1; i < L_FRAME; i++ )
216 : {
217 0 : Tmp = shr( Exc2_local[i], En_shift );
218 0 : vare = L_mac_sat( vare, Tmp, Tmp ); /* positive accumulation only */
219 : }
220 :
221 : /* obtain Ge in Q_local with safety saturation */
222 0 : L_Ge = L_shl( L_Sqrt_Q0( L_shr( vare, 1 ) ), add( sub( *Q_stat_noise_ge, 4 ), En_shift ) ); /* L_Ge in Q_local*/
223 :
224 : /* st->ge_sm = ISP_SMOOTHING_QUANT_A1 * st->ge_sm + (1.0f-ISP_SMOOTHING_QUANT_A1) * ge */
225 :
226 0 : IF( EQ_16( *uv_count, 1 ) )
227 : {
228 0 : *ge_sm = L_shr( L_Ge, Q_local );
229 0 : move32();
230 : }
231 : ELSE
232 : {
233 0 : L_tmp = Mult_32_16( L_Ge, P1 ); /* 0.1*ge still in Q local */
234 0 : L_tmp3 = Mult_32_16( *ge_sm, P9 ); /* 0.9*ge_sm still in Q_ge */
235 :
236 0 : *ge_sm = L_add( L_shr( L_tmp, Q_local ), L_tmp3 );
237 0 : move32(); /* addition in Q_ge domain*/
238 : }
239 :
240 : /*--------------------------------------------------------------------*
241 : * generate mixture of excitation and noise
242 : * float:
243 : * noimix_fac = 1.0f/(float)sqrt(alpha*alpha + (1-alpha)*(1-alpha))
244 : *--------------------------------------------------------------------*/
245 :
246 0 : beta = shl( sub( alpha, 16384 ), 1 );
247 0 : alpha_m1 = sub( 32767, alpha );
248 0 : L_tmp_res = L_mac( 0, alpha, alpha );
249 0 : L_tmp_res = L_mac( L_tmp_res, alpha_m1, alpha_m1 );
250 0 : tmp_den = round_fx( L_Frac_sqrtQ31( L_tmp_res ) );
251 :
252 0 : tmp_nom = sub( 32767, tmp_den );
253 0 : tmp_shift = norm_s( tmp_den );
254 0 : tmp_den = shl( tmp_den, tmp_shift );
255 0 : tmp_res = div_s( tmp_nom, tmp_den );
256 :
257 0 : Noimix_fract = shr( tmp_res, tmp_shift ); /* float value is in range 0.0 to 0.42 */
258 :
259 : /* L_Ge might be 0 in unvoiced WB */
260 0 : L_Ge = L_max( L_Ge, 1 );
261 0 : tmp_shift = norm_l( L_Ge );
262 0 : tmp_den = extract_h( L_shl( L_Ge, tmp_shift ) ); /* Q_local+Q_ge+tmp_shift-16 */
263 0 : tmp_res = div_s( 1 << 14, tmp_den ); /* 15+14-Q_local-tmp_shift-Q_ge+16 */
264 0 : L_tmp_res = Mult_32_16( *ge_sm, tmp_res ); /* Q_stat_noise_ge+45-Q_local-Q_ge-tmp_shift-15 */
265 0 : L_tmp_res = Mult_32_16( L_tmp_res, sub( 32767, beta ) ); /*30-Q_local-tmp_shift+15-15 */
266 0 : L_tmp_res = L_add_sat( L_shl_sat( L_tmp_res, sub( add( Q_local, tmp_shift ), 15 ) ), beta ); /* Q15 */
267 : #ifdef ISSUE_1836_replace_overflow_libcom
268 0 : tmp_res = extract_h( L_shl_sat( L_tmp_res, 15 ) ); /* 15+15-16=14 */
269 : #else
270 : tmp_res = extract_h( L_shl_o( L_tmp_res, 15, &Overflow ) ); /* 15+15-16=14 */
271 : #endif
272 :
273 0 : Noimix_fract = extract_l( Mult_32_16( L_tmp_res, Noimix_fract ) ); /*15+15-15 */
274 :
275 0 : FOR( i = 0; i < L_FRAME; i++ )
276 : {
277 : /*--------------------------------------------------------------------*
278 : * flt: exc2[i] = noimix_fac*exc2[i] * alpha + st->ge_sm*Rnd*((1.0f)-alpha)
279 : * flt: exc2[i] = (noimix_fract*exc2[i]+exc2 )* alpha + st->ge_sm*Rnd*((1.0f)-alpha)
280 : * NB: currently uses 32bit accumulation for best low level performance,
281 : * possibly overkill if input is always up-scaled
282 : *--------------------------------------------------------------------*/
283 :
284 : /* (1-alpha)*(float)sqrt(12.0f) * ((float)own_random(&(st->noimix_seed))/65536.0f) */
285 0 : randval = Random( noimix_seed ); /* +/-32767 */
286 0 : randval = mult_r( 28378, randval ); /* Q downscaled by 2 bits ends up in Q14 */ /*sqrt(12.0f) in Q13*/
287 0 : randval = extract_l( L_shl( Mult_32_16( L_Ge, randval ), 1 - *Q_stat_noise_ge ) ); /*Q_local+Q_ge+14-15+1-Q_ge=Q_local */
288 :
289 0 : L_tmp = L_mult( Exc2_local[i], alpha ); /* Q_local + 16 */
290 0 : L_tmp = L_mac( L_tmp, randval, alpha_m1 ); /* Q_local + 16 */
291 0 : L_tmp3 = Mult_32_16( L_tmp, Noimix_fract ); /* Q_local+16+15-15 */
292 0 : L_tmp = L_add_sat( L_tmp3, L_shl_sat( Mult_32_16( L_tmp, tmp_res ), 1 ) ); /* Q_local+16+14-15+1 */
293 0 : Exc2_local[i] = extract_h( L_tmp ); /*Q_local */
294 0 : move16();
295 : }
296 0 : *Q_stat_noise = Q_local; /* update for next call, routine can only be called once every frame */
297 0 : move16();
298 0 : Qdiff = sub( Q_exc, Q_local ); /* local excitation and incoming excitation */
299 0 : Scale_sig( Exc2_local, L_FRAME, Qdiff );
300 0 : Copy( Exc2_local, exc2, L_FRAME );
301 :
302 : /*--------------------------------------------------------------------*
303 : * Generate low-pass filtered version of ISP coefficients
304 : *--------------------------------------------------------------------*/
305 0 : FOR( k = 0; k < M; k++ )
306 : {
307 0 : move16();
308 0 : lspnew_s[k] = add(
309 0 : mult( ISP_SMOOTHING_QUANT_A1_FX, lspold_s[k] ),
310 0 : mult( 32767 - ISP_SMOOTHING_QUANT_A1_FX, lsp_new[k] ) );
311 : }
312 :
313 : /*--------------------------------------------------------------------*
314 : * replace LPC coefficients
315 : *--------------------------------------------------------------------*/
316 :
317 : /*--------------------------------------------------------------------*
318 : * pre-calculation of (1-beta)
319 : *--------------------------------------------------------------------*/
320 0 : FOR( i = 0; i < M; i++ )
321 : {
322 0 : move16();
323 0 : move16();
324 0 : move16();
325 0 : oldlsp_mix[i] = add( mult( beta, lsp_old[i] ),
326 0 : mult( sub( 32767, beta ), lspold_s[i] ) );
327 :
328 0 : midlsp_mix[i] = add( mult( beta, lsp_mid[i] ),
329 0 : mult( sub( 32767, beta ), add( shr( lspold_s[i], 1 ),
330 0 : shr( lspnew_s[i], 1 ) ) ) );
331 :
332 0 : newlsp_mix[i] = add( mult( beta, lsp_new[i] ),
333 0 : mult( sub( 32767, beta ), lspnew_s[i] ) );
334 : }
335 :
336 0 : int_lsp4_fx( L_FRAME, oldlsp_mix, midlsp_mix, newlsp_mix, Aq, M, 0 );
337 0 : Copy( lspnew_s, lspold_s, M );
338 : }
339 : ELSE /* (unvoiced_vad != 0) */
340 : {
341 4369 : ( *act_count )++;
342 4369 : IF( GT_16( *act_count, 3 ) )
343 : {
344 4369 : *act_count = 3;
345 4369 : move16();
346 4369 : *uv_count = 0;
347 4369 : move16();
348 : }
349 : }
350 4369 : }
351 : /*--------------------------------------------------------------------*
352 : * stat_noise_uv_mod()
353 : *
354 : * Modifies excitation signal in stationary noise segments
355 : *--------------------------------------------------------------------*/
356 :
357 130777 : void stat_noise_uv_mod_ivas_fx(
358 : const Word16 coder_type, /* i : Coder type */
359 : Word16 noisiness, /* i : noisiness parameter Q=0 */
360 : const Word16 *lsp_old, /* i : old LSP vector at 4th sfr Q=15*/
361 : const Word16 *lsp_new, /* i : LSP vector at 4th sfr Q=15*/
362 : const Word16 *lsp_mid, /* i : LSP vector at 2nd sfr Q=15*/
363 : Word16 *Aq, /* o : A(z) quantized for the 4 subframes Q=12*/
364 : Word16 *exc2, /* i/o: excitation buffer Q=Q_exc*/
365 : Word16 *Q_exc, /* i : Q of exc2 excitation buffer [11..-1] expected */
366 : const Word16 bfi, /* i : Bad frame indicator */
367 : Word32 *ge_sm, /* i/o: smoothed excitation gain Q=Q_stat_noise_ge (6)*/
368 : Word16 *uv_count, /* i/o: unvoiced counter */
369 : Word16 *act_count, /* i/o: activation counter */
370 : Word16 lspold_s[], /* i/o: old LSP Q=15*/
371 : Word16 *noimix_seed, /* i/o: mixture seed Q0 */
372 : Word16 *st_min_alpha, /* i/o: minimum alpha Q=15*/
373 : Word16 *exc_pe, /* i/o: scale Q_stat_noise Q=Q_stat_noise*/
374 : const Word32 bitrate, /* i : core bitrate */
375 : const Word16 bwidth_fx, /* i : i bandwidth */
376 : Word16 *Q_stat_noise, /* i/o: noise scaling */
377 : Word16 *Q_stat_noise_ge /* i/o: noise scaling */
378 : )
379 : {
380 : Word16 exctilt; /* Q15 */
381 : Word32 vare; /* Q31 */
382 : Word16 randval; /* Q?? */
383 : Word16 alpha; /* Q15 */
384 : Word16 alpha_m1; /* (1-alpha) Q15 */
385 : Word16 min_alpha; /* Q15 */
386 : Word16 lspnew_s[M]; /* Same for all LSP (Q15) */
387 : Word16 oldlsp_mix[M];
388 : Word16 midlsp_mix[M];
389 : Word16 newlsp_mix[M];
390 : Word16 beta; /* Q15 */
391 : Word16 Noimix_fract; /* (noimix_fac - 1.0) in Q15 */
392 : Word32 L_Noimix_fract; /* (noimix_fac - 1.0) in Q15 */
393 : /* noimix_fax * x <-> x + Noimix_fract * x */
394 : Word16 i_subfr;
395 : Word16 i, k;
396 :
397 : /* Work variables for div and sqrt */
398 : Word16 tmp_nom, tmp_den, tmp_shift, tmp_res;
399 : Word16 Qdiff, Q_local; /* new Q to be used for states Exc_pe and Ge_sm, and Exc2_local */
400 : Word32 L_tmp_res, L_tmp, L_tmp3, L_Ge;
401 :
402 : Word16 En_shift, Tmp;
403 : Word16 Exc2_local[L_FRAME]; /* local_copy in scaled Q_local*/
404 : Word32 L_Exc2_local[L_FRAME]; /* local_copy in scaled Q_local*/
405 : #ifndef ISSUE_1836_replace_overflow_libcom
406 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
407 : Flag Overflow = 0;
408 : move32();
409 : #endif
410 : #endif
411 :
412 : /*---------------------------------------------------------*
413 : * Init local variables
414 : *---------------------------------------------------------*/
415 130777 : alpha = 32767;
416 130777 : move16();
417 130777 : min_alpha = 16384;
418 130777 : move16();
419 :
420 130777 : test();
421 130777 : test();
422 130777 : test();
423 130777 : IF( EQ_16( coder_type, INACTIVE ) && ( EQ_32( bitrate, ACELP_9k60 ) || ( LT_32( bitrate, ACELP_9k60 ) && GT_16( bwidth_fx, NB ) ) ) )
424 : {
425 358 : min_alpha = *st_min_alpha;
426 358 : move16();
427 : /*---------------------------------------------------------*
428 : * decode noisiness parameter
429 : *---------------------------------------------------------*/
430 358 : IF( bfi == 0 )
431 : {
432 358 : tmp_den = 31;
433 358 : move16();
434 358 : tmp_shift = norm_s( tmp_den );
435 358 : L_tmp_res = L_deposit_h( noisiness );
436 358 : L_tmp_res = L_shl( L_tmp_res, sub( tmp_shift, 1 ) );
437 358 : tmp_den = shl( tmp_den, tmp_shift );
438 358 : tmp_res = div_l( L_tmp_res, tmp_den );
439 : #ifdef ISSUE_1836_replace_overflow_libcom
440 358 : min_alpha = add_sat( tmp_res, 16384 );
441 : #else
442 : min_alpha = add_o( tmp_res, 16384, &Overflow );
443 : #endif
444 :
445 : /**st_min_alpha = sub(*st_min_alpha, 1638); move16();*/
446 358 : min_alpha = s_max( min_alpha, sub( *st_min_alpha, 1638 ) );
447 :
448 358 : *st_min_alpha = min_alpha;
449 358 : move16();
450 : }
451 : }
452 :
453 : /*---------------------------------------------------------*
454 : * Mix excitation signal with random noise
455 : *---------------------------------------------------------*/
456 130777 : test();
457 130777 : test();
458 130777 : test();
459 130777 : IF( EQ_16( coder_type, INACTIVE ) && ( EQ_32( bitrate, ACELP_9k60 ) || ( LT_32( bitrate, ACELP_9k60 ) && GT_16( bwidth_fx, NB ) ) ) )
460 358 : {
461 : /* use a local working copy for scaling and filtering, not needed if input Q-range is fixed */
462 358 : Copy( exc2, Exc2_local, L_FRAME );
463 :
464 : /* bound Q for internal use, optimization possible */
465 358 : Q_local = s_min( 11, s_max( -1, *Q_exc ) );
466 : /* local excitation Q and incoming excitation Q*/
467 358 : Qdiff = sub( Q_local, *Q_exc );
468 : /* only shift if incoming Q is outside [11..-1] shift is done in energy calculations aswell */
469 358 : Scale_sig( Exc2_local, L_FRAME, Qdiff );
470 : /* current excitation Q and previous stat_noise states Q */
471 358 : Qdiff = sub( Q_local, *Q_stat_noise );
472 :
473 358 : *Q_stat_noise_ge = GE_SHIFT;
474 358 : move16(); /* assign the fixed Q for Ge_sm */
475 :
476 358 : IF( Qdiff != 0 )
477 : {
478 133 : Scale_sig( exc_pe, 1, Qdiff );
479 : }
480 :
481 358 : En_shift = 0;
482 358 : move16();
483 358 : if ( GT_16( Q_local, 3 ) )
484 : {
485 : /* increase margin for energy accumulation in calc_tilt and vare accumulation */
486 240 : En_shift = sub( Q_local, 3 );
487 : }
488 :
489 358 : IF( LT_16( min_alpha, TILT_COMP_LIM_FX ) )
490 : {
491 605 : FOR( i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR )
492 : {
493 484 : exctilt = calc_tilt_fx( &Exc2_local[i_subfr], En_shift, L_SUBFR ); /*Q15 */
494 : #ifdef ISSUE_1836_replace_overflow_libcom
495 484 : exctilt = mult( shl_sat( sub( TILT_COMP_LIM_FX, min_alpha ), 2 ), exctilt ); /*Q15 */
496 : #else
497 : exctilt = mult( shl_o( sub( TILT_COMP_LIM_FX, min_alpha ), 2, &Overflow ), exctilt ); /*Q15 */
498 : #endif
499 :
500 484 : PREEMPH_FX( &Exc2_local[i_subfr], exctilt, L_SUBFR, exc_pe );
501 : }
502 : }
503 :
504 358 : ( *uv_count )++;
505 :
506 358 : IF( LE_16( *uv_count, START_NG ) )
507 : {
508 280 : alpha = 32767;
509 280 : move16();
510 280 : *act_count = 3;
511 280 : move16();
512 280 : Copy( lsp_new, lspold_s, M );
513 : }
514 : ELSE
515 : {
516 78 : *uv_count = s_min( *uv_count, FULL_NG );
517 78 : move16();
518 78 : tmp_nom = sub( *uv_count, START_NG );
519 78 : tmp_den = sub( FULL_NG, START_NG );
520 78 : tmp_shift = norm_s( tmp_den );
521 78 : tmp_den = shl( tmp_den, tmp_shift );
522 78 : tmp_res = div_s( tmp_nom, tmp_den );
523 : #ifdef ISSUE_1836_replace_overflow_libcom
524 78 : tmp_res = shl_sat( tmp_res, tmp_shift );
525 : #else
526 : tmp_res = shl_o( tmp_res, tmp_shift, &Overflow );
527 : #endif
528 78 : alpha = add( 32767, mult( tmp_res, sub( min_alpha, 32767 ) ) );
529 :
530 78 : *act_count = 0;
531 78 : move16();
532 : }
533 :
534 : /*---------------------------------------------------------*
535 : * calculate lowpass filtered excitation gain
536 : *---------------------------------------------------------*/
537 358 : Tmp = shr( Exc2_local[0], En_shift );
538 358 : vare = L_mult( Tmp, Tmp ); /* positive accumulation only */
539 91648 : FOR( i = 1; i < L_FRAME; i++ )
540 : {
541 91290 : Tmp = shr( Exc2_local[i], En_shift );
542 91290 : vare = L_mac_sat( vare, Tmp, Tmp ); /* positive accumulation only */
543 : }
544 :
545 : /* obtain Ge in Q_local with safety saturation */
546 358 : L_Ge = L_shl( L_Sqrt_Q0( L_shr( vare, 1 ) ), add( sub( *Q_stat_noise_ge, 4 ), En_shift ) ); /* L_Ge in Q_local*/
547 :
548 : /* st->ge_sm = ISP_SMOOTHING_QUANT_A1 * st->ge_sm + (1.0f-ISP_SMOOTHING_QUANT_A1) * ge */
549 :
550 358 : IF( EQ_16( *uv_count, 1 ) )
551 : {
552 125 : *ge_sm = L_shr( L_Ge, Q_local );
553 125 : move32();
554 : }
555 : ELSE
556 : {
557 233 : L_tmp = Mult_32_16( L_Ge, P1 ); /* 0.1*ge still in Q local */
558 233 : L_tmp3 = Mult_32_16( *ge_sm, P9 ); /* 0.9*ge_sm still in Q_ge */
559 :
560 233 : *ge_sm = L_add( L_shr( L_tmp, Q_local ), L_tmp3 );
561 233 : move32(); /* addition in Q_ge domain*/
562 : }
563 :
564 : /*--------------------------------------------------------------------*
565 : * generate mixture of excitation and noise
566 : * float:
567 : * noimix_fac = 1.0f/(float)sqrt(alpha*alpha + (1-alpha)*(1-alpha))
568 : *--------------------------------------------------------------------*/
569 :
570 358 : beta = shl( sub( alpha, 16384 ), 1 );
571 358 : alpha_m1 = sub( 32767, alpha );
572 358 : L_tmp_res = L_mac( 0, alpha, alpha );
573 358 : L_tmp_res = L_mac( L_tmp_res, alpha_m1, alpha_m1 );
574 358 : tmp_den = round_fx( L_Frac_sqrtQ31( L_tmp_res ) );
575 358 : Word16 exp_sqr = 0;
576 358 : move16();
577 358 : tmp_res = BASOP_Util_Divide1616_Scale( 32767, tmp_den, &exp_sqr ); // 15-exp_sqr
578 358 : Noimix_fract = tmp_res; // 15-exp_sqr
579 358 : move16();
580 : /* L_Ge might be 0 in unvoiced WB */
581 358 : L_Ge = L_max( L_Ge, 1 );
582 358 : tmp_shift = norm_l( L_Ge );
583 358 : tmp_den = extract_h( L_shl( L_Ge, tmp_shift ) ); /* Q_local+Q_ge+tmp_shift-16 */
584 358 : tmp_res = div_s( 1 << 14, tmp_den ); /* 15+14-Q_local-tmp_shift-Q_ge+16 */
585 358 : L_tmp_res = Mult_32_16( *ge_sm, tmp_res ); /* Q_stat_noise_ge+45-Q_local-Q_ge-tmp_shift-15 */
586 358 : L_tmp_res = Mult_32_16( L_tmp_res, sub( 32767, beta ) ); /*30-Q_local-tmp_shift+15-15 */
587 358 : L_tmp_res = L_add_sat( L_shl_sat( L_tmp_res, sub( add( Q_local, tmp_shift ), 15 ) ), beta ); /* Q15 */
588 358 : L_Noimix_fract = Mult_32_16( L_tmp_res, Noimix_fract ); /*15+15-exp_sqr-15 =15-exp_sqr */
589 :
590 92006 : FOR( i = 0; i < L_FRAME; i++ )
591 : {
592 : /*--------------------------------------------------------------------*
593 : * flt: exc2[i] = noimix_fac*exc2[i] * alpha + st->ge_sm*Rnd*((1.0f)-alpha)
594 : * flt: exc2[i] = (noimix_fract*exc2[i]+exc2 )* alpha + st->ge_sm*Rnd*((1.0f)-alpha)
595 : * NB: currently uses 32bit accumulation for best low level performance,
596 : * possibly overkill if input is always up-scaled
597 : *--------------------------------------------------------------------*/
598 :
599 : /* (1-alpha)*(float)sqrt(12.0f) * ((float)own_random(&(st->noimix_seed))/65536.0f) */
600 91648 : randval = Random( noimix_seed ); /* +/-32767 */
601 91648 : randval = mult_r( 28378, randval ); /* Q downscaled by 2 bits ends up in Q14 */ /*sqrt(12.0f) in Q13*/
602 91648 : randval = extract_l( L_shl( Mult_32_16( L_Ge, randval ), sub( 1, *Q_stat_noise_ge ) ) ); /*Q_local+Q_ge+14-15+1-Q_ge=Q_local */
603 :
604 91648 : L_tmp = L_mult( Exc2_local[i], alpha ); /* Q_local + 16 */
605 91648 : L_tmp = L_mac( L_tmp, randval, alpha_m1 ); /* Q_local + 16 */
606 91648 : L_tmp3 = Mult_32_32( L_tmp, L_Noimix_fract ); /* Q_local+16+15-exp_sqr-15 =Q_local +1 */
607 91648 : L_Exc2_local[i] = L_add( L_shr( L_tmp3, 1 ), Mpy_32_32( L_tmp, L_tmp_res ) ); // Q_local + 16 +15 -31 = Q_local
608 91648 : move32();
609 : }
610 : Word32 max_val;
611 358 : maximum_abs_32_fx( L_Exc2_local, L_FRAME, &max_val );
612 358 : Word16 shift = 0;
613 358 : move16();
614 358 : IF( GT_32( max_val, ONE_IN_Q15 ) )
615 : {
616 0 : shift = norm_l( max_val );
617 0 : shift = sub( Q31 - Q15, shift );
618 0 : *Q_exc = sub( Q_local, shift ); // Q_exc = Q_local -shift
619 0 : move16();
620 : }
621 358 : *Q_stat_noise = Q_local; /* update for next call, routine can only be called once every frame */
622 358 : move16();
623 :
624 358 : Copy_Scale_sig_32_16( L_Exc2_local, exc2, L_FRAME, negate( shift ) ); // Q_exc
625 :
626 : /*--------------------------------------------------------------------*
627 : * Generate low-pass filtered version of ISP coefficients
628 : *--------------------------------------------------------------------*/
629 6086 : FOR( k = 0; k < M; k++ )
630 : {
631 5728 : move16();
632 5728 : lspnew_s[k] = add(
633 5728 : mult( ISP_SMOOTHING_QUANT_A1_FX, lspold_s[k] ),
634 5728 : mult( 32767 - ISP_SMOOTHING_QUANT_A1_FX, lsp_new[k] ) );
635 : }
636 :
637 : /*--------------------------------------------------------------------*
638 : * replace LPC coefficients
639 : *--------------------------------------------------------------------*/
640 :
641 : /*--------------------------------------------------------------------*
642 : * pre-calculation of (1-beta)
643 : *--------------------------------------------------------------------*/
644 6086 : FOR( i = 0; i < M; i++ )
645 : {
646 5728 : move16();
647 5728 : move16();
648 5728 : move16();
649 5728 : oldlsp_mix[i] = add( mult( beta, lsp_old[i] ),
650 5728 : mult( sub( 32767, beta ), lspold_s[i] ) );
651 :
652 5728 : midlsp_mix[i] = add( mult( beta, lsp_mid[i] ),
653 5728 : mult( sub( 32767, beta ), add( shr( lspold_s[i], 1 ),
654 5728 : shr( lspnew_s[i], 1 ) ) ) );
655 :
656 5728 : newlsp_mix[i] = add( mult( beta, lsp_new[i] ),
657 5728 : mult( sub( 32767, beta ), lspnew_s[i] ) );
658 : }
659 :
660 358 : int_lsp4_ivas_fx( L_FRAME, oldlsp_mix, midlsp_mix, newlsp_mix, Aq, M, 0 );
661 358 : Copy( lspnew_s, lspold_s, M );
662 : }
663 : ELSE /* (unvoiced_vad != 0) */
664 : {
665 130419 : ( *act_count )++;
666 130419 : IF( GT_16( *act_count, 3 ) )
667 : {
668 130410 : *act_count = 3;
669 130410 : move16();
670 130410 : *uv_count = 0;
671 130410 : move16();
672 : }
673 : }
674 130777 : }
675 :
676 : /*---------------------------------------------------------------------------*
677 : * calc_tilt()
678 : *
679 : * Calculate spectral tilt by means of 1st-order LP analysis
680 : *---------------------------------------------------------------------------*/
681 :
682 484 : static Word16 calc_tilt_fx( /* o : Excitation tilt Q15*/
683 : const Word16 *x, /* i : Signal input Q_shift*/
684 : const Word16 Q_shift, /* i : input scaling */
685 : const Word16 len /* i : length */
686 : )
687 : {
688 : Word16 i;
689 : Word16 tmp_shift;
690 : Word32 L_tmp_res;
691 : Word16 tmp_sign, xi, xi_p1;
692 : Word32 r0, r1;
693 :
694 484 : r0 = L_deposit_l( 0 );
695 484 : r1 = L_deposit_l( 0 );
696 484 : xi = shr( x[0], Q_shift );
697 :
698 30976 : FOR( i = 0; i < len - 1; i++ )
699 : {
700 : /* r0 = L_mac(r0,x[i],x[i]) */
701 : /* r1 = L_mac(r1,x[i],x[i+1]) -> correlation loop can be optimized */
702 30492 : r0 = L_mac_sat( r0, xi, xi );
703 30492 : xi_p1 = shr( x[i + 1], Q_shift );
704 30492 : r1 = L_mac_sat( r1, xi, xi_p1 );
705 30492 : xi = xi_p1;
706 30492 : move16();
707 : }
708 :
709 484 : if ( r0 == 0 )
710 : {
711 0 : r0 = L_shl( 327, 16 );
712 : }
713 :
714 484 : tmp_shift = norm_l( r0 );
715 484 : r0 = L_shl( r0, tmp_shift );
716 484 : tmp_sign = 1;
717 484 : move16();
718 484 : if ( r1 >= 0 )
719 : {
720 437 : tmp_sign = 0;
721 437 : move16();
722 : }
723 484 : r1 = L_abs( r1 );
724 :
725 484 : L_tmp_res = Div_32( r1, extract_h( r0 ), extract_l( r0 ) );
726 484 : L_tmp_res = L_shl_sat( L_tmp_res, tmp_shift ); /*Q31 */
727 484 : if ( tmp_sign != 0 )
728 : {
729 47 : L_tmp_res = L_negate( L_tmp_res ); /*Q31 */
730 : }
731 :
732 484 : return extract_h( L_tmp_res ); /*Q15 */
733 : }
734 :
735 : /*---------------------------------------------------------------------------*
736 : * L_Sqrt_Q0
737 : *
738 : * Calculate square root from fractional values (Q0 -> Q0)
739 : * Uses 32 bit internal representation for precision
740 : *---------------------------------------------------------------------------*/
741 358 : Word32 L_Sqrt_Q0( /* o : Square root of input Q0*/
742 : const Word32 x /* i : Input Qx */
743 : )
744 : {
745 : Word32 log2_work;
746 :
747 : Word16 log2_int;
748 : Word16 log2_frac;
749 :
750 358 : IF( x > 0 )
751 : {
752 358 : log2_int = norm_l( x );
753 358 : log2_frac = Log2_norm_lc( L_shl( x, log2_int ) );
754 :
755 358 : log2_work = L_mac0( 30 * 32768L, log2_frac, 1 );
756 358 : log2_work = L_msu( log2_work, log2_int, 16384 );
757 358 : log2_frac = L_Extract_lc( log2_work, &log2_int );
758 :
759 358 : return Pow2( log2_int, log2_frac );
760 : }
761 0 : return 0;
762 : }
|