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