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