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 "prot_fx.h"
7 : #include "basop_util.h"
8 : #include "rom_dec.h"
9 : #include "rom_com.h"
10 : #include "cnst.h"
11 : #define FORMAT_POST_FILT_G1 24576 /*0.75f Q15*/ /*0.75f*/ /*denominator 0.9,0.75,0.15,0.9*/
12 : #define FORMAT_POST_FILT_G2 22938 /*0.7f Q15*/ /*0.7f*/ /*numerator 0.75,0.7,0.1,0.7*/
13 : #define FORMAT_POST_FILT_G1_MAX 26214 /*0.8f Q15*/ /*for low bit-rates on clean speech*/
14 : #define FORMAT_POST_FILT_G1_MIN 24576 /*0.75f Q15*/ /*for high bit-rates on clean speech and noisy speech*/
15 :
16 : /*--------------------------------------------------------------------------
17 : * Local function prototypes
18 : *--------------------------------------------------------------------------*/
19 :
20 : static void Dec_postfilt_fx( PFSTAT_HANDLE hPFstat, const Word16 t0, const Word16 *signal_ptr, const Word16 *coeff, Word16 *sig_out, const Word16 gamma1, const Word16 gamma2, const Word16 Gain_factor, const Word16 disable_hpf );
21 :
22 : static void pst_ltp_fx( Word16 t0, Word16 *ptr_sig_in, Word16 *ptr_sig_pst0, Word16 gain_factor );
23 :
24 : static void search_del_fx( Word16 t0, Word16 *ptr_sig_in, Word16 *ltpdel, Word16 *phase, Word16 *num_gltp, Word16 *den_gltp, Word16 *sh_num_gltp, Word16 *sh_den_gltp, Word16 *y_up, Word16 *off_yup );
25 :
26 : static void filt_plt_fx( Word16 *s_in, Word16 *s_ltp, Word16 *s_out, Word16 gain_plt );
27 :
28 : static void compute_ltp_l_fx( Word16 *s_in, Word16 ltpdel, Word16 phase, Word16 *y_up, Word16 *num, Word16 *den, Word16 *sh_num, Word16 *sh_den );
29 :
30 : static Word16 select_ltp_fx( Word16 num1, Word16 den1, Word16 sh_num1, Word16 sh_den1, Word16 num2, Word16 den2, Word16 sh_num2, Word16 sh_den2 );
31 :
32 : static void calc_st_filt_local_fx( Word16 *apond2, Word16 *apond1, Word16 *parcor0, Word16 *sig_ltp_ptr, Word16 *mem_zero );
33 :
34 : static void modify_pst_param_fx( const Word16 lp_noise, Word16 *g1, Word16 *g2, const Word16 coder_type, Word16 *gain_factor );
35 :
36 : static void Dec_formant_postfilt_fx( PFSTAT_HANDLE hPFstat, Word16 *signal_ptr, Word16 *coeff, Word16 *sig_out, Word16 gamma1, Word16 gamma2 );
37 :
38 : static void calc_st_filt_ivas_fx( Word16 *apond2, Word16 *apond1, Word16 *parcor0, Word16 *sig_ltp_ptr, Word16 *mem_zero, const Word16 extl );
39 :
40 :
41 : /*--------------------------------------------------------------------------
42 : * Init_post_filter_fx
43 : *
44 : * post filter initialization
45 : *--------------------------------------------------------------------------*/
46 3444 : void Init_post_filter_fx(
47 : PFSTAT_HANDLE hPFstat /* i : core decoder parameters */
48 : )
49 : {
50 : /* It is off by default */
51 3444 : hPFstat->on = 0;
52 3444 : move16();
53 : /* Reset */
54 3444 : hPFstat->reset = 0;
55 3444 : move16();
56 : /* Initialize arrays and pointers */
57 3444 : set16_fx( hPFstat->mem_pf_in, 0, L_SUBFR );
58 :
59 : /* res2 = A(gamma2) residual */
60 3444 : set16_fx( hPFstat->mem_res2, 0, DECMEM_RES2 );
61 :
62 : /* 1/A(gamma1) memory */
63 3444 : set16_fx( hPFstat->mem_stp, 0, L_SUBFR );
64 :
65 : /* null memory to compute i.r. of A(gamma2)/A(gamma1) */
66 3444 : set16_fx( hPFstat->mem_zero, 0, M );
67 :
68 : /* for gain adjustment */
69 3444 : hPFstat->gain_prec = 16384; /*Q14*/
70 3444 : move16();
71 :
72 3444 : return;
73 : }
74 :
75 : /*--------------------------------------------------------------------------
76 : * NB_post_filt:
77 : *
78 : * Main routine to perform post filtering on NB synthesis
79 : *--------------------------------------------------------------------------*/
80 2202 : void nb_post_filt_fx(
81 : const Word16 L_frame, /* i : frame length */
82 : PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */
83 : Word16 *psf_lp_noise, /* i : Long term noise Q8 */
84 : const Word16 tmp_noise, /* i : noise energy Q0 */
85 : Word16 *Synth, /* i : 12k8 synthesis Qsyn */
86 : const Word16 *Aq, /* i : LP filter coefficient Q12 */
87 : const Word16 *Pitch_buf, /* i : Fractionnal subframe pitch buffer Q0 */
88 : const Word16 coder_type, /* i : coder_type */
89 : const Word16 BER_detect, /* i : BER detect flag */
90 : const Word16 disable_hpf /* i : flag to diabled HPF */
91 : )
92 : {
93 : Word16 i, j, Post_G1, Post_G2, Gain_factor;
94 : Word16 T0_first, *Pf_in;
95 : const Word16 *p_Aq;
96 : Word16 pf_in_buffer[M + L_FRAME16k];
97 :
98 2202 : IF( BER_detect == 0 )
99 : {
100 : /* update long-term background noise energy during inactive frames */
101 2202 : IF( EQ_16( coder_type, INACTIVE ) )
102 : {
103 0 : *psf_lp_noise = round_fx( L_mac( L_mult( 31130 /*0.95.Q15*/, *psf_lp_noise ), 26214 /*0.05 Q19*/, shl( tmp_noise, 4 ) ) ); /*Q8*Q15 + Q19*Q4 -> Q8 */
104 : }
105 : }
106 :
107 2202 : modify_pst_param_fx( *psf_lp_noise, &Post_G1, &Post_G2, coder_type, &Gain_factor );
108 :
109 2202 : IF( hPFstat->reset )
110 : {
111 2202 : set16_fx( hPFstat->mem_res2, 0, DECMEM_RES2 );
112 2202 : Copy( &Synth[L_frame - L_SYN_MEM], hPFstat->mem_pf_in, L_SYN_MEM ); // Qsyn
113 2202 : Copy( &Synth[L_frame - L_SYN_MEM], hPFstat->mem_stp, L_SYN_MEM );
114 2202 : hPFstat->gain_prec = 16384; // 1.Q14
115 2202 : move16();
116 2202 : hPFstat->reset = 0;
117 2202 : move16();
118 2202 : return;
119 : }
120 0 : Pf_in = &pf_in_buffer[M];
121 0 : Copy( hPFstat->mem_pf_in + L_SYN_MEM - M, &Pf_in[-M], M ); // Qsyn
122 0 : Copy( Synth, Pf_in, L_frame ); // Qsyn
123 0 : Copy( &Synth[L_frame - L_SYN_MEM], hPFstat->mem_pf_in, L_SYN_MEM );
124 : /* deactivation of the post filter in case of AUDIO because it causes problems to singing sequences */
125 0 : IF( EQ_16( coder_type, AUDIO ) )
126 : {
127 0 : Post_G1 = 32767;
128 0 : move16();
129 0 : Post_G2 = 32767;
130 0 : move16();
131 0 : Gain_factor = 32767;
132 0 : move16();
133 : }
134 :
135 :
136 : /* run the post filter */
137 0 : p_Aq = Aq; // Q12
138 0 : move16();
139 0 : j = 0;
140 0 : move16();
141 0 : FOR( i = 0; i < L_frame; i += L_SUBFR )
142 : {
143 0 : T0_first = Pitch_buf[j]; // Q0
144 0 : move16();
145 0 : Dec_postfilt_fx( hPFstat, T0_first, &Pf_in[i], p_Aq, &Synth[i], Post_G1, Post_G2, Gain_factor, disable_hpf );
146 :
147 0 : p_Aq += ( M + 1 );
148 0 : j = add( j, 1 );
149 : }
150 :
151 :
152 0 : return;
153 : }
154 :
155 : /*----------------------------------------------------------------------------
156 : * Dec_postfilt()
157 : *
158 : * Post - adaptive postfilter main function
159 : * Short term postfilter :
160 : * Hst(z) = Hst0(z) Hst1(z)
161 : * Hst0(z) = 1/g0 A(gamma2)(z) / A(gamma1)(z)
162 : * if {hi} = i.r. filter A(gamma2)/A(gamma1) (truncated)
163 : * g0 = SUM(|hi|) if > 1
164 : * g0 = 1. else
165 : * Hst1(z) = 1/(1 - |mu|) (1 + mu z-1)
166 : * with mu = k1 * gamma3
167 : * k1 = 1st parcor calculated on {hi}
168 : * gamma3 = gamma3_minus if k1<0, gamma3_plus if k1>0
169 : * Long term postfilter :
170 : * harmonic postfilter : H0(z) = gl * (1 + b * z-p)
171 : * b = gamma_g * gain_ltp
172 : * gl = 1 / 1 + b
173 : * computation of delay p on A(gamma2)(z) s(z)
174 : * sub optimal search
175 : * 1. search around 1st subframe delay (3 integer values)
176 : * 2. search around best integer with fract. delays (1/8)
177 : *----------------------------------------------------------------------------*/
178 0 : static void Dec_postfilt_fx(
179 : PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */
180 : const Word16 t0, /* i : pitch delay given by coder Q0 */
181 : const Word16 *signal_ptr, /* i : input signal (pointer to current subframe Q0 */
182 : const Word16 *coeff, /* i : LPC coefficients for current subframe Q12 */
183 : Word16 *sig_out, /* o : postfiltered output Q15*/
184 : const Word16 gamma1, /* i : short term postfilt. den. weighting factor Q15*/
185 : const Word16 gamma2, /* i : short term postfilt. num. weighting factor Q15*/
186 : const Word16 Gain_factor, /* i : Gain Factor (Q15) */
187 : const Word16 disable_hpf )
188 : {
189 : /* Local variables and arrays */
190 : Word16 apond1[M + 1]; /* s.t. denominator coeff. Q12*/
191 : Word16 apond2[LONG_H_ST]; // Q12
192 : Word16 sig_ltp[L_SUBFR + 1]; /* H0 output signal */
193 : Word16 res2[SIZ_RES2]; // Q0
194 :
195 : Word16 *sig_ltp_ptr;
196 : Word16 *res2_ptr;
197 : Word16 *ptr_mem_stp;
198 :
199 : Word16 parcor0; // Q15
200 :
201 :
202 : /* Init pointers and restore memories */
203 0 : res2_ptr = res2 + DECMEM_RES2;
204 0 : ptr_mem_stp = hPFstat->mem_stp + L_SYN_MEM - 1;
205 0 : Copy( hPFstat->mem_res2, res2, DECMEM_RES2 );
206 :
207 : /* Compute weighted LPC coefficients */
208 0 : weight_a_fx( coeff, apond1, gamma1, M );
209 0 : weight_a_fx( coeff, apond2, gamma2, M );
210 0 : set16_fx( &apond2[M + 1], 0, LONG_H_ST - ( M + 1 ) );
211 :
212 : /* Compute A(gamma2) residual */
213 0 : Residu3_fx( apond2, signal_ptr, res2_ptr, L_SUBFR, 1 );
214 :
215 : /* Harmonic filtering */
216 0 : sig_ltp_ptr = sig_ltp + 1;
217 :
218 0 : IF( disable_hpf == 0 )
219 : {
220 0 : pst_ltp_fx( t0, res2_ptr, sig_ltp_ptr, Gain_factor );
221 : }
222 : ELSE
223 : {
224 0 : Copy( res2_ptr, sig_ltp_ptr, L_SUBFR );
225 : }
226 :
227 : /* Save last output of 1/A(gamma1) */
228 : /* (from preceding subframe) */
229 0 : sig_ltp[0] = *ptr_mem_stp;
230 0 : move16();
231 :
232 : /* Controls short term pst filter gain and compute parcor0 */
233 0 : calc_st_filt_local_fx( apond2, apond1, &parcor0, sig_ltp_ptr, hPFstat->mem_zero );
234 :
235 0 : E_UTIL_synthesis( 1, apond1, sig_ltp_ptr, sig_ltp_ptr, L_SUBFR, hPFstat->mem_stp + L_SYN_MEM - M, 0, M );
236 0 : Copy( sig_ltp_ptr + L_SUBFR - L_SYN_MEM, hPFstat->mem_stp, L_SYN_MEM );
237 :
238 : /* Tilt filtering */
239 0 : Filt_mu_fx( sig_ltp, sig_out, parcor0, L_SUBFR );
240 :
241 : /* Gain control */
242 0 : scale_st_fx( signal_ptr, sig_out, &hPFstat->gain_prec, L_SUBFR );
243 :
244 : /* Update for next subframe */
245 0 : Copy( &res2[L_SUBFR], hPFstat->mem_res2, DECMEM_RES2 );
246 :
247 :
248 0 : return;
249 : }
250 :
251 : /*--------------------------------------------------------------------------
252 : * formant_post_filt_fx:
253 : *
254 : * Main routine to perform formant post filtering
255 : *--------------------------------------------------------------------------*/
256 :
257 265006 : void formant_post_filt_fx(
258 : PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */
259 : Word16 *synth_in, /* i : 12k8 synthesis */
260 : Word16 *Aq, /* i : LP filter coefficient Q12 */
261 : Word16 *synth_out, /* i/o: input signal */
262 : const Word16 L_frame, /* i : frame length */
263 : const Word32 lp_noise, /* (i) : background noise energy (15Q16) */
264 : const Word32 brate, /* (i) : bit-rate */
265 : const Word16 off_flag /* i : off flag */
266 : )
267 : {
268 : Word16 i_subfr;
269 : Word16 *p_Aq;
270 : Word16 post_G1, post_G2;
271 :
272 : /*default parameter for noisy speech and high bit-rates*/
273 265006 : IF( EQ_16( L_frame, L_FRAME ) )
274 : {
275 126702 : post_G2 = 22938 /*0.7f Q15*/;
276 126702 : move16();
277 126702 : IF( LT_32( lp_noise, LP_NOISE_THRESH ) )
278 : {
279 : /*Clean speech*/
280 106327 : IF( LT_32( brate, ACELP_13k20 ) )
281 : {
282 : /*Low rates*/
283 :
284 69641 : post_G1 = 26214 /*0.8f Q15*/;
285 69641 : move16();
286 : }
287 36686 : ELSE IF( LT_32( brate, ACELP_24k40 ) )
288 : {
289 : /*Low rates*/
290 :
291 36686 : post_G1 = 24576 /*0.75f Q15*/;
292 36686 : move16();
293 : }
294 : ELSE
295 : {
296 0 : post_G1 = 23593 /*0.72f Q15*/;
297 0 : move16();
298 : }
299 : }
300 : ELSE /*Noisy speech*/
301 : {
302 20375 : post_G1 = 22938 /*0.7f Q15*/;
303 20375 : move16();
304 20375 : if ( LT_32( brate, ACELP_15k85 ) )
305 : {
306 : /*Low rates*/
307 19098 : post_G1 = 24576 /*0.75f Q15*/;
308 19098 : move16();
309 : }
310 : }
311 : }
312 : ELSE
313 : {
314 138304 : post_G2 = 24904 /*0.76f Q15*/;
315 138304 : move16();
316 138304 : test();
317 138304 : IF( GE_32( lp_noise, LP_NOISE_THRESH ) )
318 : {
319 18511 : post_G1 = 24904 /*0.76f Q15*/;
320 : }
321 119793 : ELSE IF( EQ_32( brate, ACELP_13k20 ) )
322 : {
323 0 : post_G1 = 26870 /*0.82f Q15*/;
324 0 : move16();
325 : }
326 119793 : ELSE IF( EQ_32( brate, ACELP_16k40 ) )
327 : {
328 188 : post_G1 = 26214 /*0.80f Q15*/;
329 188 : move16();
330 : }
331 119605 : ELSE IF( EQ_32( brate, ACELP_24k40 ) || EQ_32( brate, ACELP_32k ) )
332 : {
333 1451 : post_G1 = 25559 /*0.78f Q15*/;
334 1451 : move16();
335 : }
336 : ELSE
337 : {
338 118154 : post_G1 = 24904 /*0.76f Q15*/;
339 118154 : move16();
340 : }
341 : }
342 :
343 : /* Switch off post-filter */
344 265006 : if ( off_flag != 0 )
345 : {
346 0 : post_G1 = post_G2;
347 0 : move16();
348 : }
349 :
350 : /* Reset post filter */
351 265006 : IF( hPFstat->reset != 0 )
352 : {
353 111941 : post_G1 = MAX16B;
354 111941 : move16();
355 111941 : post_G2 = MAX16B;
356 111941 : move16();
357 111941 : hPFstat->reset = 0;
358 111941 : move16();
359 111941 : Copy( &synth_in[L_frame - L_SYN_MEM], hPFstat->mem_pf_in, L_SYN_MEM );
360 111941 : Copy( &synth_in[L_frame - L_SYN_MEM], hPFstat->mem_stp, L_SYN_MEM );
361 111941 : hPFstat->gain_prec = 16384; // 1.Q14
362 111941 : move16();
363 111941 : Copy( synth_in, synth_out, L_frame );
364 :
365 111941 : return;
366 : }
367 :
368 : /* input memory*/
369 153065 : Copy( hPFstat->mem_pf_in, synth_in - L_SYN_MEM, L_SYN_MEM );
370 153065 : Copy( &synth_in[L_frame - L_SYN_MEM], hPFstat->mem_pf_in, L_SYN_MEM );
371 :
372 153065 : move16();
373 153065 : p_Aq = Aq; // Q12
374 837450 : FOR( i_subfr = 0; i_subfr < L_frame; i_subfr += L_SUBFR )
375 : {
376 684385 : Dec_formant_postfilt_fx( hPFstat, &synth_in[i_subfr], p_Aq, &synth_out[i_subfr], post_G1, post_G2 );
377 684385 : p_Aq += ( M + 1 );
378 : }
379 :
380 153065 : return;
381 : }
382 :
383 :
384 : /*----------------------------------------------------------------------------
385 : * Dec_formant_postfilt_fx()
386 : *
387 : * Post - adaptive postfilter main function
388 : * Short term postfilter :
389 : * Hst(z) = Hst0(z) Hst1(z)
390 : * Hst0(z) = 1/g0 A(gamma2)(z) / A(gamma1)(z)
391 : * if {hi} = i.r. filter A(gamma2)/A(gamma1) (truncated)
392 : * g0 = SUM(|hi|) if > 1
393 : * g0 = 1. else
394 : * Hst1(z) = 1/(1 - |mu|) (1 + mu z-1)
395 : * with mu = k1 * gamma3
396 : * k1 = 1st parcor calculated on {hi}
397 : * gamma3 = gamma3_minus if k1<0, gamma3_plus if k1>0
398 : *----------------------------------------------------------------------------*/
399 :
400 684385 : static void Dec_formant_postfilt_fx(
401 : PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */
402 : Word16 *signal_ptr, /* i : input signal (pointer to current subframe Q14*/
403 : Word16 *coeff, /* i : LPC coefficients for current subframe Q12 */
404 : Word16 *sig_out, /* o : postfiltered output */
405 : Word16 gamma1, /* i : short term postfilt. den. weighting factor Q15*/
406 : Word16 gamma2 /* i : short term postfilt. num. weighting factor Q15*/
407 : )
408 : {
409 : /* Local variables and arrays */
410 : Word16 apond1[M + 1]; /* s.t. denominator coeff. Q12*/
411 : Word16 apond2[LONG_H_ST]; // Q12
412 : Word16 res2[L_SUBFR]; // Q14
413 : Word16 resynth[L_SUBFR + 1]; // Qy
414 : Word16 parcor0; // Q15
415 : Word16 i, max;
416 : Word16 scale_down;
417 :
418 : /* Compute weighted LPC coefficients */
419 684385 : weight_a_fx( coeff, apond1, gamma1, M );
420 684385 : weight_a_fx( coeff, apond2, gamma2, M );
421 684385 : set16_fx( &apond2[M + 1], 0, LONG_H_ST - ( M + 1 ) );
422 :
423 684385 : max = abs_s( signal_ptr[0] ); // Q14
424 43800640 : FOR( i = 1; i < L_SUBFR; i++ )
425 : {
426 43116255 : max = s_max( max, abs_s( signal_ptr[i] ) );
427 : }
428 684385 : scale_down = 0;
429 684385 : move16();
430 684385 : if ( GT_16( max, 16384 /*1.Q14*/ ) )
431 : {
432 666 : scale_down = 1;
433 666 : move16();
434 : }
435 :
436 : /* Compute A(gamma2) residual */
437 684385 : IF( !scale_down )
438 : {
439 683719 : Residu3_fx( apond2, signal_ptr, res2, L_SUBFR, 1 );
440 : }
441 : ELSE
442 : {
443 666 : Residu3_fx( apond2, signal_ptr, res2, L_SUBFR, 0 );
444 666 : Scale_sig( hPFstat->mem_stp, L_SYN_MEM, -1 );
445 : }
446 :
447 : /* Controls short term pst filter gain and compute parcor0 */
448 684385 : calc_st_filt_ivas_fx( apond2, apond1, &parcor0, res2, hPFstat->mem_zero, -1 );
449 :
450 : /* 1/A(gamma1) filtering, mem_stp is updated */
451 684385 : resynth[0] = *( hPFstat->mem_stp + sub( L_SYN_MEM, 1 ) );
452 684385 : move16();
453 :
454 684385 : E_UTIL_synthesis( 1, apond1, res2, &( resynth[1] ), L_SUBFR, hPFstat->mem_stp + L_SYN_MEM - M, 0, M );
455 :
456 684385 : IF( !scale_down )
457 : {
458 683719 : Copy( &( resynth[1] ) + L_SUBFR - L_SYN_MEM, hPFstat->mem_stp, L_SYN_MEM );
459 : }
460 : ELSE
461 : {
462 666 : Copy_Scale_sig( &( resynth[1] ) + L_SUBFR - L_SYN_MEM, hPFstat->mem_stp, L_SYN_MEM, 1 );
463 : }
464 :
465 : /* Tilt filtering */
466 684385 : Filt_mu_ivas_fx( resynth, sig_out, parcor0, L_SUBFR, -1 );
467 684385 : IF( scale_down )
468 : {
469 666 : Scale_sig( sig_out, L_SUBFR, 1 );
470 : }
471 :
472 : /* Gain control */
473 684385 : scale_st_fx( signal_ptr, sig_out, &hPFstat->gain_prec, L_SUBFR );
474 :
475 :
476 684385 : return;
477 : }
478 :
479 : /*------------------------------------------------------------------------------------
480 : * modify_pst_param()
481 : *
482 : * Modify gamma1 and gamma2 values in function of the long term noise level
483 : *-----------------------------------------------------------------------------------*/
484 :
485 2202 : static void modify_pst_param_fx(
486 : const Word16 lp_noise, /* i : Long term noise energy Q8 */
487 : Word16 *g1, /* o : Gamma1 used in post filter Q15 */
488 : Word16 *g2, /* o : Gamma1 used in post filter Q15 */
489 : const Word16 coder_type, /* i : Vad information decoded in UV frame */
490 : Word16 *gain_factor /* o : Gain factor applied in post filtering Q15 */
491 : )
492 : {
493 : Word16 tmp;
494 : Word16 lp_noiseQ12;
495 : Word32 L_tmp;
496 : #ifndef ISSUE_1866_replace_overflow_libdec
497 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
498 : Flag Overflow = 0;
499 : move16();
500 : #endif
501 : #endif
502 :
503 :
504 2202 : test();
505 2202 : IF( NE_16( coder_type, INACTIVE ) && LT_16( lp_noise, LP_NOISE_THR_FX ) )
506 : {
507 : #ifdef ISSUE_1866_replace_overflow_libdec
508 2202 : lp_noiseQ12 = shl_sat( lp_noise, 4 ); /* to go from Q8 to Q12 */
509 : #else
510 : lp_noiseQ12 = shl_o( lp_noise, 4, &Overflow ); /* to go from Q8 to Q12 */
511 : #endif
512 :
513 : /* ftmp = lp_noise*BG1_FX + CG1_FX */
514 2202 : tmp = mac_r( CG1_FX * 65536L, lp_noiseQ12, BG1_FX * 8 ); /* x8 to go from Q12 to Q15 */
515 2202 : tmp = s_min( tmp, POST_G1_FX );
516 2202 : tmp = s_max( tmp, GAMMA1_PST12K_MIN_FX );
517 :
518 2202 : *g1 = tmp;
519 2202 : move16();
520 :
521 : /* ftmp = lp_noise*BG2_FX + CG2_FX */
522 2202 : L_tmp = L_mac0( CG2_FX / 2 * 65536L, lp_noiseQ12, BG2_FX * 8 ); /* L_mac0 and /2 to go from Q12 to Q14 */
523 : /* we go to Q30 to avoid overflow CG2_FX*/
524 :
525 2202 : L_tmp = L_min( L_tmp, POST_G2_FX * 65536L / 2 ); /* /2 because L_tmp is Q30 */
526 2202 : L_tmp = L_max( L_tmp, GAMMA2_PST12K_MIN_FX * 65536L / 2 );
527 :
528 2202 : *g2 = extract_h( L_shl( L_tmp, 1 ) ); /* Q30=>Q31=>Q15 */
529 : }
530 : ELSE
531 : {
532 0 : *g1 = GAMMA1_PST12K_NOIS_FX;
533 0 : move16();
534 0 : *g2 = GAMMA2_PST12K_NOIS_FX;
535 0 : move16();
536 : }
537 :
538 : /* Set gain_factor of the harmonic filtering*/
539 : /* ftmp = (lp_noise - K_LP_NOISE)*C_LP_NOISE_FX */
540 2202 : L_tmp = L_mac( -CK_LP_NOISE_FX, lp_noise, C_LP_NOISE_FX ); /* tmp is in Q24 (from Q8) */
541 :
542 2202 : L_tmp = L_min( L_tmp, 64 * 65536L ); /* 0.25 in Q24 */
543 2202 : L_tmp = L_max( L_tmp, 0 );
544 :
545 2202 : *gain_factor = extract_h( L_shl( L_tmp, 7 ) ); /* Q24=>Q31=>Q15 */
546 :
547 :
548 2202 : return;
549 : }
550 :
551 : /*----------------------------------------------------------------------------
552 : * pst_ltp_fx
553 : *
554 : * Perform harmonic postfilter
555 : *----------------------------------------------------------------------------*/
556 0 : static void pst_ltp_fx(
557 : Word16 t0, /* i : pitch delay given by coder Q0 */
558 : Word16 *ptr_sig_in, /* i : postfilter i filter (residu2) Qx */
559 : Word16 *ptr_sig_pst0, /* o : harmonic postfilter o Qx */
560 : Word16 gain_factor /* i : Gain Factor (Q15) */
561 : )
562 : {
563 : Word32 L_temp;
564 :
565 : Word16 y_up[SIZ_Y_UP];
566 : Word16 sig_cadr[SIZ_RES2];
567 :
568 : Word16 *ptr_y_up;
569 : Word16 *ptr_sig;
570 : Word16 *ptr_sig_cadr;
571 :
572 : Word16 i;
573 : Word16 temp;
574 : Word16 ltpdel, phase;
575 : Word16 num_gltp, den_gltp;
576 : Word16 num2_gltp, den2_gltp;
577 : Word16 sh_num, sh_den;
578 : Word16 sh_num2, sh_den2;
579 : Word16 gain_plt;
580 : Word16 off_yup;
581 : Word16 nb_sh_sig;
582 : #ifndef ISSUE_1866_replace_overflow_libdec
583 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
584 : Flag Overflow = 0;
585 : move16();
586 : #endif
587 : #endif
588 :
589 :
590 : /* i signal justified on 13 bits */
591 0 : ptr_sig = ptr_sig_in - DECMEM_RES2; // Qx
592 0 : nb_sh_sig = getScaleFactor16( ptr_sig, DECMEM_RES2 + L_SUBFR );
593 0 : nb_sh_sig = sub( 3, nb_sh_sig );
594 :
595 0 : FOR( i = 0; i < DECMEM_RES2 + L_SUBFR; i++ )
596 : {
597 : /* nb_sh_sig may be >0, <0 or =0 */
598 0 : sig_cadr[i] = shr( ptr_sig[i], nb_sh_sig );
599 0 : move16();
600 : }
601 0 : ptr_sig_cadr = sig_cadr + DECMEM_RES2;
602 :
603 : /* Sub optimal delay search */
604 0 : search_del_fx( t0, ptr_sig_cadr, <pdel, &phase, &num_gltp, &den_gltp, &sh_num, &sh_den, y_up, &off_yup );
605 :
606 :
607 0 : IF( num_gltp == 0 )
608 : {
609 0 : Copy( ptr_sig_in, ptr_sig_pst0, L_SUBFR );
610 : }
611 : ELSE
612 : {
613 0 : IF( phase == 0 )
614 : {
615 0 : ptr_y_up = ptr_sig_in - ltpdel; // Qx
616 : }
617 : ELSE
618 : {
619 : /* Filtering with long filter */
620 0 : compute_ltp_l_fx( ptr_sig_cadr, ltpdel, phase, ptr_sig_pst0, &num2_gltp, &den2_gltp, &sh_num2, &sh_den2 );
621 :
622 :
623 0 : IF( EQ_16( select_ltp_fx( num_gltp, den_gltp, sh_num, sh_den, num2_gltp, den2_gltp, sh_num2, sh_den2 ), 1 ) )
624 : {
625 : /* select short filter */
626 0 : temp = sub( phase, 1 );
627 0 : L_temp = L_mult0( temp, L_SUBFR + 1 );
628 0 : temp = extract_l( L_temp );
629 0 : temp = add( temp, off_yup );
630 :
631 : /* ptr_y_up = y_up + (phase-1) * (L_SUBFR+1) + off_yup */
632 0 : ptr_y_up = y_up + temp;
633 : }
634 : ELSE
635 : {
636 : /* select long filter */
637 0 : num_gltp = num2_gltp;
638 0 : move16();
639 0 : den_gltp = den2_gltp;
640 0 : move16();
641 0 : sh_num = sh_num2;
642 0 : move16();
643 0 : sh_den = sh_den2;
644 0 : move16();
645 0 : ptr_y_up = ptr_sig_pst0;
646 : }
647 :
648 : /* rescale y_up */
649 0 : FOR( i = 0; i < L_SUBFR; i++ )
650 : {
651 : /* nb_sh_sig may be >0, <0 or =0 */
652 0 : ptr_y_up[i] = shl_sat( ptr_y_up[i], nb_sh_sig );
653 0 : move16();
654 : }
655 : }
656 :
657 0 : temp = sub( sh_num, sh_den );
658 0 : IF( temp >= 0 )
659 : {
660 0 : den_gltp = shr( den_gltp, temp );
661 : }
662 : ELSE
663 : {
664 0 : num_gltp = shl( num_gltp, temp ); /* >> (-temp) */
665 : }
666 0 : IF( GE_16( num_gltp, den_gltp ) )
667 : {
668 : /* beta bounded to 1 */
669 0 : gain_plt = MIN_GPLT_FX;
670 0 : move16();
671 : }
672 : ELSE
673 : {
674 : /* GAMMA_G = 0.5 */
675 : /* gain_plt = den_gltp x 2**15 / (den_gltp + 0.5 num_gltp) */
676 : /* shift 1 bit to avoid overflows in add */
677 0 : num_gltp = shr( num_gltp, 2 );
678 0 : den_gltp = shr( den_gltp, 1 );
679 0 : temp = add( den_gltp, num_gltp );
680 0 : gain_plt = div_s( den_gltp, temp ); /* Q15 */
681 : }
682 :
683 : /* decrease gain in noisy condition */
684 : /* gain_plt += (1.0f-gain_plt) * gain_factor */
685 : /* gain_plt = gain_plt + gain_factor - gain_plt*gain_factor */
686 : #ifdef ISSUE_1866_replace_overflow_libdec
687 0 : gain_plt = msu_r_sat( L_msu( L_deposit_h( gain_plt ), gain_plt, gain_factor ), -32768, gain_factor ); // Q15
688 : #else
689 : gain_plt = msu_ro( L_msu( L_deposit_h( gain_plt ), gain_plt, gain_factor ), -32768, gain_factor, &Overflow ); // Q15
690 : #endif
691 :
692 : /** filtering by H0(z) = harmonic filter **/
693 0 : filt_plt_fx( ptr_sig_in, ptr_y_up, ptr_sig_pst0, gain_plt );
694 : }
695 0 : }
696 :
697 : /*----------------------------------------------------------------------------
698 : * search_del_fx:
699 : *
700 : * Computes best (shortest) integer LTP delay + fine search
701 : *---------------------------------------------------------------------------*/
702 0 : static void search_del_fx(
703 : Word16 t0, /* i : pitch delay given by coder Q0 */
704 : Word16 *ptr_sig_in, /* i : i signal (with delay line) */
705 : Word16 *ltpdel, /* o : delay = *ltpdel - *phase / f_up */
706 : Word16 *phase, /* o : phase */
707 : Word16 *num_gltp, /* o : 16 bits numerator of LTP gain Q(sh_num_gltp) */
708 : Word16 *den_gltp, /* o : 16 bits denominator of LTP gain Q(sh_den_gltp) */
709 : Word16 *sh_num_gltp, /* o : justification for num_gltp */
710 : Word16 *sh_den_gltp, /* o : justification for den_gltp */
711 : Word16 *y_up, /* o : LT delayed signal if fract. delay */
712 : Word16 *off_yup /* o : offset in y_up */
713 : )
714 : {
715 : Word32 L_den0[F_UP_PST - 1];
716 : Word32 L_den1[F_UP_PST - 1];
717 :
718 : Word32 *ptr_L_den0, *ptr_L_den1;
719 :
720 : Word32 L_num_int, L_den_int, L_den_max;
721 : Word32 L_temp0, L_temp1;
722 : Word32 L_acc;
723 : Word32 L_temp;
724 :
725 : const Word16 *ptr_h;
726 : Word16 *ptr_sig_past, *ptr_sig_past0;
727 : Word16 *ptr1, *ptr_y_up;
728 :
729 : Word16 i, n;
730 : Word16 num /*Q(sh_num)*/, den0 /*Q(sh_den)*/, den1 /*Q(sh_den)*/;
731 : Word16 den_max, num_max;
732 : Word32 L_numsq_max;
733 : Word16 ener; // Q(sh_ener)
734 : Word16 sh_num, sh_den, sh_ener;
735 : Word16 i_max, lambda, phi, phi_max, ioff;
736 : Word16 temp;
737 :
738 :
739 : /*-------------------------------------
740 : * Computes energy of current signal
741 : *-------------------------------------*/
742 :
743 0 : L_acc = L_mult( ptr_sig_in[0], ptr_sig_in[0] );
744 0 : FOR( i = 1; i < L_SUBFR; i++ )
745 : {
746 0 : L_acc = L_mac_sat( L_acc, ptr_sig_in[i], ptr_sig_in[i] );
747 : }
748 0 : IF( L_acc == 0 )
749 : {
750 0 : *num_gltp = 0;
751 0 : move16();
752 0 : *den_gltp = 1;
753 0 : move16();
754 0 : *ltpdel = 0;
755 0 : move16();
756 0 : *phase = 0;
757 0 : move16();
758 :
759 0 : return;
760 : }
761 0 : sh_ener = sub( 16, norm_l( L_acc ) );
762 : /* save energy for final decision */
763 0 : sh_ener = s_max( 0, sh_ener );
764 0 : ener = extract_l( L_shr( L_acc, sh_ener ) );
765 :
766 : /*-------------------------------------
767 : * Selects best of 3 integer delays
768 : * Maximum of 3 numerators around t0
769 : *-------------------------------------*/
770 0 : lambda = sub( t0, 1 );
771 0 : ptr_sig_past = ptr_sig_in - lambda;
772 0 : L_num_int = L_deposit_l( -1 );
773 :
774 : /* initialization used only to suppress Microsoft Visual C++ warnings */
775 0 : i_max = (Word16) 0;
776 0 : move16();
777 :
778 0 : FOR( i = 0; i < 3; i++ )
779 : {
780 0 : L_acc = L_mult( ptr_sig_in[0], ptr_sig_past[0] );
781 0 : FOR( n = 1; n < L_SUBFR; n++ )
782 : {
783 0 : L_acc = L_mac_sat( L_acc, ptr_sig_in[n], ptr_sig_past[n] );
784 : }
785 :
786 :
787 0 : L_acc = L_max( L_acc, 0 );
788 0 : L_temp = L_sub_sat( L_acc, L_num_int );
789 0 : if ( L_temp > 0L )
790 : {
791 0 : i_max = (Word16) i;
792 0 : move16();
793 : }
794 0 : L_num_int = L_max( L_num_int, L_acc );
795 0 : ptr_sig_past--;
796 : }
797 :
798 0 : IF( L_num_int == 0 )
799 : {
800 0 : *num_gltp = 0;
801 0 : move16();
802 0 : *den_gltp = 1;
803 0 : move16();
804 0 : *ltpdel = 0;
805 0 : move16();
806 0 : *phase = 0;
807 0 : move16();
808 :
809 0 : return;
810 : }
811 :
812 : /* Compute den for i_max */
813 0 : lambda = add( lambda, (Word16) i_max );
814 0 : ptr_sig_past = ptr_sig_in - lambda;
815 0 : temp = *ptr_sig_past++;
816 0 : move16();
817 0 : L_acc = L_mult( temp, temp );
818 0 : FOR( i = 1; i < L_SUBFR; i++ )
819 : {
820 0 : temp = *ptr_sig_past++;
821 0 : move16();
822 0 : L_acc = L_mac_sat( L_acc, temp, temp );
823 : }
824 0 : IF( L_acc == 0L )
825 : {
826 0 : *num_gltp = 0;
827 0 : move16();
828 0 : *den_gltp = 1;
829 0 : move16();
830 0 : *ltpdel = 0;
831 0 : move16();
832 0 : *phase = 0;
833 0 : move16();
834 :
835 0 : return;
836 : }
837 0 : L_den_int = L_acc; /* sets to 'L_acc' in 1 clock */
838 0 : move32();
839 :
840 : /*----------------------------------
841 : * Select best phase around lambda
842 : *----------------------------------
843 : * Compute y_up & denominators
844 : *----------------------------------*/
845 :
846 0 : ptr_y_up = y_up;
847 0 : L_den_max = L_den_int; /* sets to 'L_acc' in 1 clock */
848 0 : move32();
849 0 : ptr_L_den0 = L_den0;
850 0 : ptr_L_den1 = L_den1;
851 0 : ptr_h = tab_hup_s_fx;
852 0 : temp = sub( lambda, LH_UP_S - 1 );
853 0 : ptr_sig_past0 = ptr_sig_in - temp;
854 :
855 : /* Loop on phase */
856 0 : FOR( phi = 1; phi < F_UP_PST; phi++ )
857 : {
858 : /* Compute y_up for lambda+1 - phi/F_UP_PST */
859 : /* and lambda - phi/F_UP_PST */
860 :
861 0 : ptr_sig_past = ptr_sig_past0;
862 0 : FOR( n = 0; n <= L_SUBFR; n++ )
863 : {
864 0 : ptr1 = ptr_sig_past++;
865 :
866 0 : L_acc = L_mult( ptr_h[0], ptr1[0] );
867 0 : FOR( i = 1; i < LH2_S; i++ )
868 : {
869 0 : L_acc = L_mac( L_acc, ptr_h[i], ptr1[-i] );
870 : }
871 0 : ptr_y_up[n] = round_fx( L_acc );
872 : }
873 :
874 : /* compute den0 (lambda+1) and den1 (lambda) */
875 :
876 : /* part common to den0 and den1 */
877 0 : L_acc = L_mult( ptr_y_up[1], ptr_y_up[1] );
878 0 : FOR( n = 2; n < L_SUBFR; n++ )
879 : {
880 0 : L_acc = L_mac_sat( L_acc, ptr_y_up[n], ptr_y_up[n] );
881 : }
882 0 : L_temp0 = L_acc; /* sets to 'L_acc' in 1 clock (saved for den1) */
883 0 : move32();
884 :
885 : /* den0 */
886 0 : L_acc = L_mac_sat( L_acc, ptr_y_up[0], ptr_y_up[0] );
887 0 : *ptr_L_den0 = L_acc;
888 0 : move32();
889 :
890 : /* den1 */
891 0 : L_acc = L_mac_sat( L_temp0, ptr_y_up[L_SUBFR], ptr_y_up[L_SUBFR] );
892 0 : *ptr_L_den1 = L_acc;
893 0 : move32();
894 :
895 0 : IF( GT_16( abs_s( ptr_y_up[0] ), abs_s( ptr_y_up[L_SUBFR] ) ) )
896 : {
897 0 : L_den_max = L_max( *ptr_L_den0, L_den_max );
898 : }
899 : ELSE
900 : {
901 0 : L_den_max = L_max( *ptr_L_den1, L_den_max );
902 : }
903 0 : ptr_L_den0++;
904 0 : ptr_L_den1++;
905 0 : ptr_y_up += ( L_SUBFR + 1 );
906 0 : ptr_h += LH2_S;
907 : }
908 :
909 0 : IF( L_den_max == 0 )
910 : {
911 0 : *num_gltp = 0;
912 0 : move16();
913 0 : *den_gltp = 1;
914 0 : move16();
915 0 : *ltpdel = 0;
916 0 : move16();
917 0 : *phase = 0;
918 0 : move16();
919 :
920 0 : return;
921 : }
922 :
923 0 : sh_den = sub( 16, norm_l( L_den_max ) );
924 : /* if sh_den <= 0 : dynamic between current frame */
925 : /* and delay line too high */
926 0 : IF( sh_den <= 0 )
927 : {
928 0 : *num_gltp = 0;
929 0 : move16();
930 0 : *den_gltp = 1;
931 0 : move16();
932 0 : *ltpdel = 0;
933 0 : move16();
934 0 : *phase = 0;
935 0 : move16();
936 :
937 0 : return;
938 : }
939 :
940 : /* search sh_num to justify correlations */
941 : /* sh_num = Max(sh_den, sh_ener) */
942 0 : sh_num = sh_ener;
943 0 : move16();
944 0 : if ( GE_16( sh_den, sh_ener ) )
945 : {
946 0 : sh_num = sh_den;
947 0 : move16();
948 : }
949 :
950 : /* Computation of the numerators */
951 : /* and selection of best num*num/den */
952 : /* for non null phases */
953 :
954 : /* Initialize with null phase */
955 0 : L_acc = L_shr( L_den_int, sh_den ); /* sh_den > 0 */
956 0 : den_max = extract_l( L_acc );
957 0 : L_acc = L_shr( L_num_int, sh_num ); /* sh_num > 0 */
958 0 : num_max = extract_l( L_acc );
959 0 : L_numsq_max = L_mult( num_max, num_max );
960 :
961 0 : phi_max = 0;
962 0 : move16();
963 0 : ioff = 1;
964 0 : move16();
965 :
966 0 : ptr_L_den0 = L_den0;
967 0 : ptr_L_den1 = L_den1;
968 0 : ptr_y_up = y_up;
969 :
970 :
971 : /* if den_max = 0 : will be selected and declared unvoiced */
972 : /* if num!=0 & den=0 : will be selected and declared unvoiced */
973 : /* degenerated seldom cases, switch off LT is OK */
974 :
975 : /* Loop on phase */
976 0 : FOR( phi = 1; phi < F_UP_PST; phi++ )
977 : {
978 : /* compute num for lambda+1 - phi/F_UP_PST */
979 0 : L_acc = L_mult( ptr_sig_in[0], ptr_y_up[0] );
980 0 : FOR( n = 1; n < L_SUBFR; n++ )
981 : {
982 0 : L_acc = L_mac_sat( L_acc, ptr_sig_in[n], ptr_y_up[n] );
983 : }
984 0 : L_acc = L_shr( L_acc, sh_num ); /* sh_num > 0 */
985 0 : L_acc = L_max( 0, L_acc );
986 0 : num = extract_l( L_acc );
987 :
988 : /* selection if num**2/den0 max */
989 0 : L_temp1 = L_mult( num, num );
990 0 : L_temp0 = Mpy_32_16_1( L_temp1, den_max );
991 0 : L_acc = L_add( *ptr_L_den0++, 0 );
992 0 : L_acc = L_shr( L_acc, sh_den ); /* sh_den > 0 */
993 0 : den0 = extract_l( L_acc );
994 0 : L_temp = Msub_32_16( L_temp0, L_numsq_max, den0 );
995 0 : IF( L_temp > 0L )
996 : {
997 0 : num_max = num;
998 0 : move16();
999 0 : L_numsq_max = L_temp1; /* sets to 'L_temp1' in 1 clock */
1000 0 : move32();
1001 0 : den_max = den0;
1002 0 : move16();
1003 0 : ioff = 0;
1004 0 : move16();
1005 0 : phi_max = phi;
1006 0 : move16();
1007 : }
1008 :
1009 : /* compute num for lambda - phi/F_UP_PST */
1010 0 : ptr_y_up++;
1011 :
1012 0 : L_acc = L_mult( ptr_sig_in[0], ptr_y_up[0] );
1013 0 : FOR( n = 1; n < L_SUBFR; n++ )
1014 : {
1015 0 : L_acc = L_mac_sat( L_acc, ptr_sig_in[n], ptr_y_up[n] );
1016 : }
1017 0 : L_acc = L_shr( L_acc, sh_num ); /* sh_num > 0 */
1018 0 : L_acc = L_max( 0, L_acc );
1019 0 : num = extract_l( L_acc );
1020 :
1021 : /* selection if num**2/den1 max */
1022 0 : L_temp1 = L_mult( num, num );
1023 0 : L_temp0 = Mpy_32_16_1( L_temp1, den_max );
1024 0 : L_acc = L_add( *ptr_L_den1++, 0 );
1025 0 : L_acc = L_shr( L_acc, sh_den ); /* sh_den > 0 */
1026 0 : den1 = extract_l( L_acc );
1027 0 : L_temp = Msub_32_16( L_temp0, L_numsq_max, den1 );
1028 0 : IF( L_temp > 0L )
1029 : {
1030 0 : num_max = num;
1031 0 : move16();
1032 0 : L_numsq_max = L_temp1; /* sets to 'L_temp1' in 1 clock */
1033 0 : move32();
1034 0 : den_max = den1;
1035 0 : move16();
1036 0 : ioff = 1;
1037 0 : move16();
1038 0 : phi_max = phi;
1039 0 : move16();
1040 : }
1041 :
1042 0 : ptr_y_up += L_SUBFR;
1043 : }
1044 :
1045 : /*---------------------------------------------------
1046 : * test if normalized crit0[iopt] > THRESHCRIT
1047 : *--------------------------------------------------*/
1048 0 : test();
1049 0 : IF( num_max == 0 || LE_16( den_max, 1 ) )
1050 : {
1051 0 : *num_gltp = 0;
1052 0 : move16();
1053 0 : *den_gltp = 1;
1054 0 : move16();
1055 0 : *ltpdel = 0;
1056 0 : move16();
1057 0 : *phase = 0;
1058 0 : move16();
1059 :
1060 0 : return;
1061 : }
1062 :
1063 : /* compare num**2 */
1064 : /* to ener * den * 0.5 */
1065 : /* (THRESHCRIT = 0.5) */
1066 0 : L_temp1 = L_mult( den_max, ener );
1067 :
1068 : /* temp = 2 * sh_num - sh_den - sh_ener + 1 */
1069 : /* 16 bits with no overflows */
1070 0 : temp = shl( sh_num, 1 );
1071 0 : temp = sub( temp, sh_den );
1072 0 : temp = sub( temp, sh_ener );
1073 0 : temp = add( temp, 1 );
1074 0 : IF( temp < 0 )
1075 : {
1076 0 : temp = negate( temp ); /* no overflow */
1077 0 : L_numsq_max = L_shr( L_numsq_max, temp );
1078 : }
1079 : ELSE
1080 : {
1081 0 : IF( temp > 0 )
1082 : {
1083 0 : L_temp1 = L_shr( L_temp1, temp );
1084 : }
1085 : }
1086 0 : L_temp = L_sub( L_numsq_max, L_temp1 );
1087 0 : IF( L_temp >= 0L )
1088 : {
1089 0 : temp = add( lambda, 1 );
1090 0 : *ltpdel = sub( temp, ioff );
1091 0 : *off_yup = ioff;
1092 0 : move16();
1093 0 : *phase = phi_max;
1094 0 : move16();
1095 0 : *num_gltp = num_max;
1096 0 : move16();
1097 0 : *den_gltp = den_max;
1098 0 : move16();
1099 0 : *sh_den_gltp = sh_den;
1100 0 : move16();
1101 0 : *sh_num_gltp = sh_num;
1102 0 : move16();
1103 : }
1104 : ELSE
1105 : {
1106 0 : *num_gltp = 0;
1107 0 : move16();
1108 0 : *den_gltp = 1;
1109 0 : move16();
1110 0 : *ltpdel = 0;
1111 0 : move16();
1112 0 : *phase = 0;
1113 0 : move16();
1114 : }
1115 :
1116 :
1117 0 : return;
1118 : }
1119 :
1120 : /*----------------------------------------------------------------------------
1121 : * filt_plt_fx:
1122 : *
1123 : * Perform long term postfilter
1124 : *----------------------------------------------------------------------------*/
1125 0 : static void filt_plt_fx(
1126 : Word16 *s_in, /* i : i signal with past Qx */
1127 : Word16 *s_ltp, /* i : filtered signal with gain 1 Qx*/
1128 : Word16 *s_out, /* o : signal Qx */
1129 : Word16 gain_plt /* i : filter gain Q15 */
1130 : )
1131 : {
1132 :
1133 : /* Local variables */
1134 : Word32 L_acc;
1135 :
1136 : Word16 n;
1137 : Word16 gain_plt_1;
1138 :
1139 :
1140 0 : gain_plt_1 = sub( 32767, gain_plt ); // Q15
1141 0 : gain_plt_1 = add( gain_plt_1, 1 ); /* 2**15 (1 - g) */
1142 :
1143 0 : FOR( n = 0; n < L_SUBFR; n++ )
1144 : {
1145 : /* s_out(n) = gain_plt x s_in(n) + gain_plt_1 x s_ltp(n) */
1146 0 : L_acc = L_mult( gain_plt, s_in[n] ); // Qx + Q15 + 1
1147 0 : s_out[n] = mac_r( L_acc, gain_plt_1, s_ltp[n] ); // Qx
1148 0 : move16(); /* no overflow */
1149 : }
1150 :
1151 :
1152 0 : return;
1153 : }
1154 :
1155 :
1156 : /*----------------------------------------------------------------------------
1157 : * compute_ltp_l_fx :
1158 : *
1159 : * compute delayed signal, num & den of gain for fractional delay
1160 : * with long interpolation filter
1161 : *----------------------------------------------------------------------------*/
1162 0 : static void compute_ltp_l_fx(
1163 : Word16 *s_in, /* i/o: signal with past */
1164 : Word16 ltpdel, /* i : delay factor */
1165 : Word16 phase, /* i : phase factor */
1166 : Word16 *y_up, /* i : delayed signal */
1167 : Word16 *num, /* i : numerator of LTP gain Q(sh_num) */
1168 : Word16 *den, /* i : denominator of LTP gain Q(sh_den) */
1169 : Word16 *sh_num, /* i : justification factor of num */
1170 : Word16 *sh_den /* i : justification factor of den */
1171 : )
1172 : {
1173 : Word32 L_acc;
1174 : Word16 *ptr2;
1175 : const Word16 *ptr_h;
1176 : Word16 n, i;
1177 : Word16 temp;
1178 :
1179 0 : temp = sub( phase, 1 );
1180 0 : temp = shl( temp, L2_LH2_L );
1181 0 : ptr_h = tab_hup_l_fx + temp; /* tab_hup_l_fx + LH2_L * (phase-1) */ // Q15
1182 :
1183 0 : temp = sub( LH_UP_L, ltpdel );
1184 0 : ptr2 = s_in + temp;
1185 :
1186 : /* Compute y_up */
1187 0 : FOR( n = 0; n < L_SUBFR; n++ )
1188 : {
1189 0 : L_acc = L_mult( ptr_h[0], *ptr2-- );
1190 :
1191 0 : FOR( i = 1; i < LH2_L; i++ )
1192 : {
1193 0 : L_acc = L_mac( L_acc, ptr_h[i], *ptr2-- );
1194 : }
1195 0 : y_up[n] = round_fx( L_acc );
1196 0 : ptr2 += LH2_L_P1;
1197 : }
1198 :
1199 : /* Compute num */
1200 0 : L_acc = L_mult( y_up[0], s_in[0] );
1201 0 : FOR( n = 1; n < L_SUBFR; n++ )
1202 : {
1203 0 : L_acc = L_mac( L_acc, y_up[n], s_in[n] );
1204 : }
1205 0 : IF( L_acc < 0L )
1206 : {
1207 0 : *num = 0;
1208 0 : move16();
1209 0 : *sh_num = 0;
1210 0 : move16();
1211 : }
1212 : ELSE
1213 : {
1214 0 : temp = sub( 16, norm_l( L_acc ) );
1215 0 : temp = s_max( temp, 0 );
1216 0 : L_acc = L_shr( L_acc, temp ); /* with temp >= 0 */
1217 0 : *num = extract_l( L_acc );
1218 0 : *sh_num = temp;
1219 0 : move16();
1220 0 : move16();
1221 : }
1222 :
1223 : /* Compute den */
1224 0 : L_acc = L_mult( y_up[0], y_up[0] );
1225 0 : FOR( n = 1; n < L_SUBFR; n++ )
1226 : {
1227 0 : L_acc = L_mac_sat( L_acc, y_up[n], y_up[n] );
1228 : }
1229 0 : temp = sub( 16, norm_l( L_acc ) );
1230 0 : temp = s_max( temp, 0 );
1231 0 : L_acc = L_shr( L_acc, temp ); /* with temp >= 0 */
1232 0 : *den = extract_l( L_acc );
1233 0 : *sh_den = temp;
1234 0 : move16();
1235 0 : move16();
1236 :
1237 :
1238 0 : return;
1239 : }
1240 :
1241 : /*----------------------------------------------------------------------------
1242 : * select_ltp_fx:
1243 : *
1244 : * selects best of (gain1, gain2)
1245 : * with gain1 = num1 * 2** sh_num1 / den1 * 2** sh_den1
1246 : * and gain2 = num2 * 2** sh_num2 / den2 * 2** sh_den2
1247 : *----------------------------------------------------------------------------*/
1248 0 : static Word16 select_ltp_fx( /* o : 1 = 1st gain, 2 = 2nd gain */
1249 : Word16 num1, /* i : numerator of gain1 Q(sh_num1) */
1250 : Word16 den1, /* i : denominator of gain1 Q(sh_den1) */
1251 : Word16 sh_num1, /* i : just. factor for num1 */
1252 : Word16 sh_den1, /* i : just. factor for den1 */
1253 : Word16 num2, /* i : numerator of gain2 Q(sh_num2) */
1254 : Word16 den2, /* i : denominator of gain2 Q(sh_den2) */
1255 : Word16 sh_num2, /* i : just. factor for num2 */
1256 : Word16 sh_den2 /* i : just. factor for den2 */
1257 : )
1258 : {
1259 : Word32 L_temp1, L_temp2;
1260 : Word32 L_temp;
1261 :
1262 : Word16 temp1, temp2;
1263 :
1264 :
1265 0 : IF( den2 == 0 )
1266 : {
1267 0 : return 1;
1268 : }
1269 :
1270 : /* compares criteria = num**2/den */
1271 0 : L_temp1 = L_mult( num1, num1 );
1272 0 : L_temp1 = Mpy_32_16_1( L_temp1, den2 );
1273 :
1274 0 : L_temp2 = L_mult( num2, num2 );
1275 0 : L_temp2 = Mpy_32_16_1( L_temp2, den1 );
1276 :
1277 : /* temp1 = sh_den2 + 2 * sh_num1 */
1278 0 : temp1 = shl( sh_num1, 1 );
1279 0 : temp1 = add( temp1, sh_den2 );
1280 : /* temp2 = sh_den1 + 2 * sh_num2; */
1281 0 : temp2 = shl( sh_num2, 1 );
1282 0 : temp2 = add( temp2, sh_den1 );
1283 :
1284 0 : temp2 = sub( temp2, temp1 );
1285 0 : IF( temp2 > 0 )
1286 : {
1287 0 : L_temp1 = L_shr( L_temp1, temp2 ); /* temp2 > 0 */
1288 : }
1289 0 : IF( temp2 < 0 )
1290 : {
1291 0 : L_temp2 = L_shl( L_temp2, temp2 ); /* temp2 < 0 */
1292 : }
1293 :
1294 0 : L_temp = L_sub( L_temp2, L_temp1 );
1295 0 : temp1 = 1;
1296 0 : move16();
1297 0 : if ( L_temp > 0L )
1298 : {
1299 0 : temp1 = 2;
1300 0 : move16();
1301 : }
1302 :
1303 0 : return temp1;
1304 : }
1305 :
1306 : /*----------------------------------------------------------------------------
1307 : * calc_st_filt_local_fx
1308 : *
1309 : * computes impulse response of A(gamma2) / A(gamma1)
1310 : * controls gain : computation of energy impulse response as
1311 : * SUMn (abs (h[n])) and computes parcor0
1312 : *---------------------------------------------------------------------------- */
1313 0 : static void calc_st_filt_local_fx(
1314 : Word16 *apond2, /* i : coefficients of numerator Q12 */
1315 : Word16 *apond1, /* i : coefficients of denominator Q12 */
1316 : Word16 *parcor0, /* o : 1st parcor calcul. on composed filter Q15*/
1317 : Word16 *sig_ltp_ptr, /* i/o: i of 1/A(gamma1) : scaled by 1/g0 Qx */
1318 : Word16 *mem_zero /* i : All zero memory */
1319 : )
1320 : {
1321 : Word32 L_g0;
1322 :
1323 : Word16 h[LONG_H_ST];
1324 :
1325 : Word16 g0, temp;
1326 : Word16 i;
1327 :
1328 :
1329 0 : temp = sub( 2, norm_s( apond2[0] ) );
1330 :
1331 : /* compute i.r. of composed filter apond2 / apond1 */
1332 0 : E_UTIL_synthesis( temp, apond1, apond2, h, LONG_H_ST, mem_zero, 0, M );
1333 :
1334 : /* compute 1st parcor */
1335 0 : Calc_rc0_h( h, parcor0 );
1336 :
1337 : /* compute g0 */
1338 0 : L_g0 = L_mult0( 1, abs_s( h[0] ) ); // Q12
1339 0 : FOR( i = 1; i < LONG_H_ST; i++ )
1340 : {
1341 0 : L_g0 = L_mac0( L_g0, 1, abs_s( h[i] ) ); // Q12
1342 : }
1343 0 : g0 = extract_h( L_shl( L_g0, 14 ) ); // Q10
1344 :
1345 : /* Scale signal i of 1/A(gamma1) */
1346 0 : IF( GT_16( g0, 1024 ) ) /*1024 = 1.Q10*/
1347 : {
1348 0 : temp = div_s( 1024, g0 ); /* temp => Q15 / gain0 */ /*1024 = 1.Q10*/
1349 0 : FOR( i = 0; i < L_SUBFR; i++ )
1350 : {
1351 0 : sig_ltp_ptr[i] = mult_r( sig_ltp_ptr[i], temp ); // Qx
1352 0 : move16();
1353 : }
1354 : }
1355 :
1356 :
1357 0 : return;
1358 : }
1359 :
1360 684385 : static void calc_st_filt_ivas_fx(
1361 : Word16 *apond2, /* i : coefficients of numerator Q12 */
1362 : Word16 *apond1, /* i : coefficients of denominator Q12 */
1363 : Word16 *parcor0, /* o : 1st parcor calcul. on composed filter Q15 */
1364 : Word16 *sig_ltp_ptr, /* i/o: i of 1/A(gamma1) : scaled by 1/g0 Qx*/
1365 : Word16 *mem_zero, /* i : All zero memory */
1366 : const Word16 extl /* i : extension layer info */
1367 : )
1368 : {
1369 : Word32 L_g0;
1370 :
1371 : Word16 h[LONG_H_ST]; // Q12
1372 :
1373 : Word16 g0, temp;
1374 : Word16 i;
1375 :
1376 :
1377 684385 : temp = sub( 2, norm_s( apond2[0] ) );
1378 :
1379 : /* compute i.r. of composed filter apond2 / apond1 */
1380 684385 : IF( EQ_16( extl, SWB_TBE ) )
1381 : {
1382 0 : E_UTIL_synthesis( temp, apond1, apond2, h, LONG_H_ST, mem_zero, 0, LPC_SHB_ORDER );
1383 : }
1384 : ELSE
1385 : {
1386 684385 : E_UTIL_synthesis( temp, apond1, apond2, h, LONG_H_ST, mem_zero, 0, M );
1387 : }
1388 :
1389 : /* compute 1st parcor */
1390 684385 : Calc_rc0_h( h, parcor0 );
1391 :
1392 : /* compute g0 */
1393 684385 : L_g0 = L_mult0( 1, abs_s( h[0] ) ); // Q12
1394 13687700 : FOR( i = 1; i < LONG_H_ST; i++ )
1395 : {
1396 13003315 : L_g0 = L_mac0( L_g0, 1, abs_s( h[i] ) ); // Q12
1397 : }
1398 684385 : g0 = extract_h( L_shl( L_g0, 14 ) ); // Q10
1399 :
1400 : /* Scale signal i of 1/A(gamma1) */
1401 684385 : IF( GT_16( g0, 1024 ) ) /*1024 = 1.Q10*/
1402 : {
1403 324864 : temp = div_s( 1024, g0 ); /* temp => Q15 / gain0 */ /*1024 = 1.Q10*/
1404 21116160 : FOR( i = 0; i < L_SUBFR; i++ )
1405 : {
1406 20791296 : sig_ltp_ptr[i] = mult_r( sig_ltp_ptr[i], temp ); // Qx
1407 20791296 : move16();
1408 : }
1409 : }
1410 :
1411 :
1412 684385 : return;
1413 : }
1414 : /*----------------------------------------------------------------------------
1415 : * filt_mu
1416 : *
1417 : * tilt filtering with : (1 + mu z-1) * (1/1-|mu|)
1418 : * computes y[n] = (1/1-|mu|) (x[n]+mu*x[n-1])
1419 : *---------------------------------------------------------------------------*/
1420 0 : void Filt_mu_fx(
1421 : Word16 *sig_in, /* i : signal (beginning at sample -1) */
1422 : Word16 *sig_out, /* o : signal with tilt */
1423 : Word16 parcor0, /* i : parcor0 (mu = parcor0 * gamma3) */
1424 : Word16 L_subfr /* i : the length of subframe */
1425 : )
1426 : {
1427 : Word32 L_acc, L_temp, L_fact;
1428 :
1429 : Word16 *ptrs;
1430 :
1431 : Word16 n;
1432 : Word16 mu, mu2, ga, temp;
1433 : Word16 fact, sh_fact;
1434 : #ifndef ISSUE_1866_replace_overflow_libdec
1435 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1436 : Flag Overflow = 0;
1437 : move16();
1438 : #endif
1439 : #endif
1440 :
1441 :
1442 0 : IF( parcor0 > 0 )
1443 : {
1444 0 : mu = mult_r( parcor0, GAMMA3_PLUS_FX ); // Q15
1445 : /* GAMMA3_PLUS_FX < 0.5 */
1446 0 : sh_fact = 14;
1447 0 : move16(); /* sh_fact */
1448 0 : fact = (Word16) 0x4000;
1449 0 : move16(); /* Q(sh_fact) */
1450 0 : L_fact = (Word32) L_deposit_l( 0x2000 ); /* fact >> 1 */
1451 : }
1452 : ELSE
1453 : {
1454 0 : mu = mult_r( parcor0, GAMMA3_MINUS_FX ); // Q15
1455 : /* GAMMA3_MINUS_FX < 0.9375 */
1456 0 : sh_fact = 11;
1457 0 : move16(); /* sh_fact */
1458 0 : fact = (Word16) 0x0800;
1459 0 : move16(); /* Q(sh_fact) */
1460 0 : L_fact = (Word32) L_deposit_l( 0x0400 ); /* fact >> 1 */
1461 : }
1462 :
1463 0 : temp = sub( 1, abs_s( mu ) );
1464 : BASOP_SATURATE_WARNING_OFF_EVS;
1465 : #ifdef ISSUE_1866_replace_overflow_libdec
1466 0 : mu2 = add_sat( 32767, temp ); /* Q15 (1 - |mu|) */
1467 : #else
1468 : mu2 = add_o( 32767, temp, &Overflow ); /* Q15 (1 - |mu|) */
1469 : #endif
1470 : BASOP_SATURATE_WARNING_ON_EVS;
1471 0 : ga = div_s( fact, mu2 ); /* Q(sh_fact) / (1 - |mu|) */
1472 :
1473 0 : ptrs = sig_in; /* points on sig_in(-1) */
1474 :
1475 0 : sh_fact = sub( sh_fact, 16 ); /* to remove the saturate(), should shl by 16 before rounding */
1476 :
1477 0 : FOR( n = 0; n < L_subfr; n++ )
1478 : {
1479 0 : L_acc = L_mult0( mu, *ptrs++ );
1480 0 : L_temp = L_mac( L_acc, 16384, *ptrs ); /* sig_in(n) * 2**15 */
1481 :
1482 0 : L_temp = Madd_32_16( L_fact, L_temp, ga );
1483 0 : L_temp = L_shr_sat( L_temp, sh_fact ); /* mult. temp x ga */
1484 : BASOP_SATURATE_WARNING_OFF_EVS;
1485 : /*sig_out[n] = saturate(L_temp); move16();*/
1486 0 : sig_out[n] = round_fx_sat( L_temp );
1487 0 : move16();
1488 : BASOP_SATURATE_WARNING_ON_EVS;
1489 : }
1490 :
1491 :
1492 0 : return;
1493 : }
1494 :
1495 684385 : void Filt_mu_ivas_fx(
1496 : Word16 *sig_in, /* i : signal (beginning at sample -1) */
1497 : Word16 *sig_out, /* o : signal with tilt */
1498 : Word16 parcor0, /* i : parcor0 (mu = parcor0 * gamma3) Q15 */
1499 : Word16 L_subfr, /* i : the length of subframe */
1500 : const Word16 extl )
1501 : {
1502 : Word32 L_acc, L_temp, L_fact;
1503 :
1504 : Word16 *ptrs;
1505 :
1506 : Word16 n;
1507 : Word16 mu, mu2, ga, temp;
1508 : Word16 fact, sh_fact;
1509 : #ifndef ISSUE_1866_replace_overflow_libdec
1510 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1511 : Flag Overflow = 0;
1512 : move16();
1513 : #endif
1514 : #endif
1515 :
1516 684385 : IF( EQ_16( extl, SWB_TBE ) )
1517 : {
1518 0 : IF( parcor0 > 0 )
1519 : {
1520 0 : mu = mult_r( parcor0, GAMMA3_PLUS_WB_FX ); // Q15
1521 : /* GAMMA3_PLUS_FX < 0.5 */
1522 0 : sh_fact = 14;
1523 0 : move16(); /* sh_fact */
1524 0 : fact = (Word16) 0x4000;
1525 0 : move16(); /* Q(sh_fact) */
1526 0 : L_fact = L_deposit_l( 0x2000 ); /* fact >> 1 */
1527 : }
1528 : ELSE
1529 : {
1530 0 : mu = mult_r( parcor0, GAMMA3_MINUS_WB_FX ); // Q15
1531 : /* GAMMA3_MINUS_FX < 0.9375 */
1532 0 : sh_fact = 11;
1533 0 : move16(); /* sh_fact */
1534 0 : fact = (Word16) 0x0800;
1535 0 : move16(); /* Q(sh_fact) */
1536 0 : L_fact = L_deposit_l( 0x0400 ); /* fact >> 1 */
1537 : }
1538 : }
1539 : ELSE
1540 : {
1541 684385 : IF( parcor0 > 0 )
1542 : {
1543 49441 : mu = mult_r( parcor0, GAMMA3_PLUS_FX ); // Q15
1544 : /* GAMMA3_PLUS_FX < 0.5 */
1545 49441 : sh_fact = 14;
1546 49441 : move16(); /* sh_fact */
1547 49441 : fact = (Word16) 0x4000;
1548 49441 : move16(); /* Q(sh_fact) */
1549 49441 : L_fact = L_deposit_l( 0x2000 ); /* fact >> 1 */
1550 : }
1551 : ELSE
1552 : {
1553 634944 : mu = mult_r( parcor0, GAMMA3_MINUS_FX ); // Q15
1554 : /* GAMMA3_MINUS_FX < 0.9375 */
1555 634944 : sh_fact = 11;
1556 634944 : move16(); /* sh_fact */
1557 634944 : fact = (Word16) 0x0800;
1558 634944 : move16(); /* Q(sh_fact) */
1559 634944 : L_fact = L_deposit_l( 0x0400 ); /* fact >> 1 */
1560 : }
1561 : }
1562 :
1563 684385 : temp = sub( 1, abs_s( mu ) );
1564 : BASOP_SATURATE_WARNING_OFF_EVS;
1565 : #ifdef ISSUE_1866_replace_overflow_libdec
1566 684385 : mu2 = add_sat( 32767, temp ); /* Q15 (1 - |mu|) */
1567 : #else
1568 : mu2 = add_o( 32767, temp, &Overflow ); /* Q15 (1 - |mu|) */
1569 : #endif
1570 : BASOP_SATURATE_WARNING_ON_EVS;
1571 684385 : ga = div_s( fact, mu2 ); /* Q(sh_fact) / (1 - |mu|) */
1572 :
1573 684385 : ptrs = sig_in; /* points on sig_in(-1) */
1574 :
1575 684385 : sh_fact = sub( sh_fact, 16 ); /* to remove the saturate(), should shl by 16 before rounding */
1576 :
1577 44485025 : FOR( n = 0; n < L_subfr; n++ )
1578 : {
1579 43800640 : L_acc = L_mult0( mu, *ptrs++ );
1580 43800640 : L_temp = L_mac( L_acc, 16384, *ptrs ); /* sig_in(n) * 2**15 */
1581 :
1582 43800640 : L_temp = Madd_32_16( L_fact, L_temp, ga );
1583 43800640 : L_temp = L_shr( L_temp, sh_fact ); /* mult. temp x ga */
1584 :
1585 : BASOP_SATURATE_WARNING_OFF_EVS;
1586 : /*sig_out[n] = saturate(L_temp); move16();*/
1587 43800640 : sig_out[n] = round_fx_sat( L_temp );
1588 : BASOP_SATURATE_WARNING_ON_EVS;
1589 : }
1590 :
1591 :
1592 684385 : return;
1593 : }
1594 : /*----------------------------------------------------------------------------
1595 : * scale_st_fx()
1596 : *
1597 : * control of the subframe gain
1598 : * gain[n] = AGC_FAC_FX * gain[n-1] + (1 - AGC_FAC_FX) g_in/g_out
1599 : *---------------------------------------------------------------------------*/
1600 685623 : void scale_st_fx(
1601 : const Word16 *sig_in, /* i : postfilter i signal Qx */
1602 : Word16 *sig_out, /* i/o: postfilter o signal Qx */
1603 : Word16 *gain_prec, /* i/o: last value of gain for subframe Q14*/
1604 : Word16 L_subfr )
1605 : {
1606 : Word32 L_acc, L_temp;
1607 :
1608 : Word16 i;
1609 : Word16 scal_in, scal_out;
1610 : Word16 s_g_in, s_g_out, temp, sh_g0, g0;
1611 685623 : Word16 gain = 0;
1612 :
1613 :
1614 : /* compute i gain */
1615 685623 : L_acc = L_deposit_l( 0 );
1616 44565495 : FOR( i = 0; i < L_subfr; i++ )
1617 : {
1618 43879872 : IF( sig_in[i] > 0 )
1619 : {
1620 21901830 : L_acc = L_mac0( L_acc, 1, sig_in[i] );
1621 : }
1622 43879872 : IF( sig_in[i] < 0 )
1623 : {
1624 21739138 : L_acc = L_msu0( L_acc, 1, sig_in[i] );
1625 : }
1626 : }
1627 :
1628 685623 : g0 = 0;
1629 685623 : move16();
1630 685623 : IF( L_acc != 0L )
1631 : {
1632 684537 : scal_in = norm_l( L_acc );
1633 684537 : L_acc = L_shl( L_acc, scal_in );
1634 684537 : s_g_in = extract_h( L_acc ); /* normalized */
1635 :
1636 : /* Compute o gain */
1637 : {
1638 684537 : Word64 acc64 = 0;
1639 44494905 : FOR( i = 0; i < L_subfr; i++ )
1640 : {
1641 43810368 : acc64 = W_mac0_16_16( acc64, 1, abs_s( sig_out[i] ) );
1642 : }
1643 684537 : L_acc = W_sat_l( acc64 );
1644 : }
1645 684537 : IF( L_acc == 0L )
1646 : {
1647 379 : *gain_prec = 0;
1648 379 : move16();
1649 :
1650 379 : return;
1651 : }
1652 684158 : scal_out = norm_l( L_acc );
1653 684158 : L_acc = L_shl( L_acc, scal_out );
1654 684158 : s_g_out = extract_h( L_acc ); /* normalized */
1655 :
1656 684158 : sh_g0 = add( scal_in, 1 );
1657 684158 : sh_g0 = sub( sh_g0, scal_out ); /* scal_in - scal_out + 1 */
1658 684158 : IF( LT_16( s_g_in, s_g_out ) )
1659 : {
1660 217202 : g0 = div_s( s_g_in, s_g_out ); /* s_g_in/s_g_out in Q15 */
1661 : }
1662 : ELSE
1663 : {
1664 466956 : temp = sub( s_g_in, s_g_out ); /* sufficient since normalized */
1665 466956 : g0 = shr( div_s( temp, s_g_out ), 1 );
1666 466956 : g0 = add( g0, (Word16) 0x4000 ); /* s_g_in/s_g_out in Q14 */
1667 466956 : sh_g0 = sub( sh_g0, 1 );
1668 : }
1669 : /* L_gain_in/L_gain_out in Q14 */
1670 : /* overflows if L_gain_in > 2 * L_gain_out */
1671 684158 : g0 = shr_sat( g0, sh_g0 ); /* sh_g0 may be >0, <0, or =0 */
1672 684158 : g0 = mult_r( g0, AGC_FAC1_FX ); /* L_gain_in/L_gain_out * AGC_FAC1_FX */
1673 : }
1674 :
1675 : /* gain(n) = AGC_FAC gain(n-1) + AGC_FAC1 gain_in/gain_out */
1676 : /* sig_out(n) = gain(n) sig_out(n) */
1677 685244 : gain = *gain_prec;
1678 685244 : move16();
1679 44540860 : FOR( i = 0; i < L_subfr; i++ )
1680 : {
1681 43855616 : temp = mult_r( AGC_FAC_FX, gain );
1682 43855616 : gain = add( temp, g0 ); /* in Q14 */
1683 43855616 : L_temp = L_mult( gain, sig_out[i] );
1684 43855616 : L_temp = L_shl_sat( L_temp, 1 );
1685 43855616 : sig_out[i] = round_fx_sat( L_temp );
1686 43855616 : move16();
1687 : }
1688 685244 : *gain_prec = gain;
1689 685244 : move16();
1690 :
1691 :
1692 685244 : return;
1693 : }
1694 :
1695 : /*----------------------------------------------------------------------------
1696 : * blend_subfr2_fx()
1697 : *
1698 : *
1699 : *---------------------------------------------------------------------------*/
1700 :
1701 1238 : void blend_subfr2_fx(
1702 : Word16 *sigIn1, // Qx
1703 : Word16 *sigIn2, // Qx
1704 : Word16 *sigOut // Qx
1705 : )
1706 : {
1707 1238 : Word16 fac1 = 32768 - 512; // 1.Q15 - ( 1.Q15 / L_SUBFR );
1708 1238 : Word16 fac2 = 0 + 512; // 0.Q15 + ( 1.Q15 / L_SUBFR );
1709 1238 : Word16 step = 1024; // 1.Q15 / ( L_SUBFR / 2 );
1710 : Word16 i;
1711 : #ifndef ISSUE_1866_replace_overflow_libdec
1712 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1713 : Flag Overflow = 0;
1714 : move16();
1715 : #endif
1716 : #endif
1717 1238 : move16();
1718 1238 : move16();
1719 1238 : move16();
1720 40854 : FOR( i = 0; i < L_SUBFR / 2; i++ )
1721 : {
1722 : #ifdef ISSUE_1866_replace_overflow_libdec
1723 39616 : sigOut[i] = mac_r_sat( L_mult_sat( fac1, sigIn1[i] ), fac2, sigIn2[i] ); // Qx
1724 39616 : fac1 = sub_sat( fac1, step );
1725 39616 : fac2 = add_sat( fac2, step );
1726 : #else
1727 : sigOut[i] = mac_ro( L_mult_o( fac1, sigIn1[i], &Overflow ), fac2, sigIn2[i], &Overflow ); // Qx
1728 : fac1 = sub_o( fac1, step, &Overflow );
1729 : fac2 = add_o( fac2, step, &Overflow );
1730 : #endif
1731 39616 : move16();
1732 : }
1733 :
1734 1238 : return;
1735 : }
|