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