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 3448 : void Init_post_filter_fx(
47 : PFSTAT_HANDLE hPFstat /* i : core decoder parameters */
48 : )
49 : {
50 : /* It is off by default */
51 3448 : hPFstat->on = 0;
52 3448 : move16();
53 : /* Reset */
54 3448 : hPFstat->reset = 0;
55 3448 : move16();
56 : /* Initialize arrays and pointers */
57 3448 : set16_fx( hPFstat->mem_pf_in, 0, L_SUBFR );
58 :
59 : /* res2 = A(gamma2) residual */
60 3448 : set16_fx( hPFstat->mem_res2, 0, DECMEM_RES2 );
61 :
62 : /* 1/A(gamma1) memory */
63 3448 : set16_fx( hPFstat->mem_stp, 0, L_SUBFR );
64 :
65 : /* null memory to compute i.r. of A(gamma2)/A(gamma1) */
66 3448 : set16_fx( hPFstat->mem_zero, 0, M );
67 :
68 : /* for gain adjustment */
69 3448 : hPFstat->gain_prec = 16384; /*Q14*/
70 3448 : move16();
71 :
72 3448 : return;
73 : }
74 :
75 : /*--------------------------------------------------------------------------
76 : * NB_post_filt:
77 : *
78 : * Main routine to perform post filtering on NB synthesis
79 : *--------------------------------------------------------------------------*/
80 2203 : 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 2203 : IF( BER_detect == 0 )
99 : {
100 : /* update long-term background noise energy during inactive frames */
101 2203 : 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 2203 : modify_pst_param_fx( *psf_lp_noise, &Post_G1, &Post_G2, coder_type, &Gain_factor );
108 :
109 2203 : IF( hPFstat->reset )
110 : {
111 2203 : set16_fx( hPFstat->mem_res2, 0, DECMEM_RES2 );
112 2203 : Copy( &Synth[L_frame - L_SYN_MEM], hPFstat->mem_pf_in, L_SYN_MEM ); // Qsyn
113 2203 : Copy( &Synth[L_frame - L_SYN_MEM], hPFstat->mem_stp, L_SYN_MEM );
114 2203 : hPFstat->gain_prec = 16384; // 1.Q14
115 2203 : move16();
116 2203 : hPFstat->reset = 0;
117 2203 : move16();
118 2203 : 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 265329 : 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 265329 : IF( EQ_16( L_frame, L_FRAME ) )
274 : {
275 126840 : post_G2 = 22938 /*0.7f Q15*/;
276 126840 : move16();
277 126840 : IF( LT_32( lp_noise, LP_NOISE_THRESH ) )
278 : {
279 : /*Clean speech*/
280 106357 : IF( LT_32( brate, ACELP_13k20 ) )
281 : {
282 : /*Low rates*/
283 :
284 69740 : post_G1 = 26214 /*0.8f Q15*/;
285 69740 : move16();
286 : }
287 36617 : ELSE IF( LT_32( brate, ACELP_24k40 ) )
288 : {
289 : /*Low rates*/
290 :
291 36617 : post_G1 = 24576 /*0.75f Q15*/;
292 36617 : move16();
293 : }
294 : ELSE
295 : {
296 0 : post_G1 = 23593 /*0.72f Q15*/;
297 0 : move16();
298 : }
299 : }
300 : ELSE /*Noisy speech*/
301 : {
302 20483 : post_G1 = 22938 /*0.7f Q15*/;
303 20483 : move16();
304 20483 : if ( LT_32( brate, ACELP_15k85 ) )
305 : {
306 : /*Low rates*/
307 19212 : post_G1 = 24576 /*0.75f Q15*/;
308 19212 : move16();
309 : }
310 : }
311 : }
312 : ELSE
313 : {
314 138489 : post_G2 = 24904 /*0.76f Q15*/;
315 138489 : move16();
316 138489 : test();
317 138489 : IF( GE_32( lp_noise, LP_NOISE_THRESH ) )
318 : {
319 18418 : post_G1 = 24904 /*0.76f Q15*/;
320 : }
321 120071 : ELSE IF( EQ_32( brate, ACELP_13k20 ) )
322 : {
323 0 : post_G1 = 26870 /*0.82f Q15*/;
324 0 : move16();
325 : }
326 120071 : ELSE IF( EQ_32( brate, ACELP_16k40 ) )
327 : {
328 187 : post_G1 = 26214 /*0.80f Q15*/;
329 187 : move16();
330 : }
331 119884 : ELSE IF( EQ_32( brate, ACELP_24k40 ) || EQ_32( brate, ACELP_32k ) )
332 : {
333 1441 : post_G1 = 25559 /*0.78f Q15*/;
334 1441 : move16();
335 : }
336 : ELSE
337 : {
338 118443 : post_G1 = 24904 /*0.76f Q15*/;
339 118443 : move16();
340 : }
341 : }
342 :
343 : /* Switch off post-filter */
344 265329 : if ( off_flag != 0 )
345 : {
346 0 : post_G1 = post_G2;
347 0 : move16();
348 : }
349 :
350 : /* Reset post filter */
351 265329 : IF( hPFstat->reset != 0 )
352 : {
353 112757 : post_G1 = MAX16B;
354 112757 : move16();
355 112757 : post_G2 = MAX16B;
356 112757 : move16();
357 112757 : hPFstat->reset = 0;
358 112757 : move16();
359 112757 : Copy( &synth_in[L_frame - L_SYN_MEM], hPFstat->mem_pf_in, L_SYN_MEM );
360 112757 : Copy( &synth_in[L_frame - L_SYN_MEM], hPFstat->mem_stp, L_SYN_MEM );
361 112757 : hPFstat->gain_prec = 16384; // 1.Q14
362 112757 : move16();
363 112757 : Copy( synth_in, synth_out, L_frame );
364 :
365 112757 : return;
366 : }
367 :
368 : /* input memory*/
369 152572 : Copy( hPFstat->mem_pf_in, synth_in - L_SYN_MEM, L_SYN_MEM );
370 152572 : Copy( &synth_in[L_frame - L_SYN_MEM], hPFstat->mem_pf_in, L_SYN_MEM );
371 :
372 152572 : move16();
373 152572 : p_Aq = Aq; // Q12
374 834453 : FOR( i_subfr = 0; i_subfr < L_frame; i_subfr += L_SUBFR )
375 : {
376 681881 : Dec_formant_postfilt_fx( hPFstat, &synth_in[i_subfr], p_Aq, &synth_out[i_subfr], post_G1, post_G2 );
377 681881 : p_Aq += ( M + 1 );
378 : }
379 :
380 152572 : 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 681881 : 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 681881 : weight_a_fx( coeff, apond1, gamma1, M );
420 681881 : weight_a_fx( coeff, apond2, gamma2, M );
421 681881 : set16_fx( &apond2[M + 1], 0, LONG_H_ST - ( M + 1 ) );
422 :
423 681881 : max = abs_s( signal_ptr[0] ); // Q14
424 43640384 : FOR( i = 1; i < L_SUBFR; i++ )
425 : {
426 42958503 : max = s_max( max, abs_s( signal_ptr[i] ) );
427 : }
428 681881 : scale_down = 0;
429 681881 : move16();
430 681881 : if ( GT_16( max, 16384 /*1.Q14*/ ) )
431 : {
432 684 : scale_down = 1;
433 684 : move16();
434 : }
435 :
436 : /* Compute A(gamma2) residual */
437 681881 : IF( !scale_down )
438 : {
439 681197 : Residu3_fx( apond2, signal_ptr, res2, L_SUBFR, 1 );
440 : }
441 : ELSE
442 : {
443 684 : Residu3_fx( apond2, signal_ptr, res2, L_SUBFR, 0 );
444 684 : Scale_sig( hPFstat->mem_stp, L_SYN_MEM, -1 );
445 : }
446 :
447 : /* Controls short term pst filter gain and compute parcor0 */
448 681881 : calc_st_filt_ivas_fx( apond2, apond1, &parcor0, res2, hPFstat->mem_zero, -1 );
449 :
450 : /* 1/A(gamma1) filtering, mem_stp is updated */
451 681881 : resynth[0] = *( hPFstat->mem_stp + sub( L_SYN_MEM, 1 ) );
452 681881 : move16();
453 :
454 681881 : E_UTIL_synthesis( 1, apond1, res2, &( resynth[1] ), L_SUBFR, hPFstat->mem_stp + L_SYN_MEM - M, 0, M );
455 :
456 681881 : IF( !scale_down )
457 : {
458 681197 : Copy( &( resynth[1] ) + L_SUBFR - L_SYN_MEM, hPFstat->mem_stp, L_SYN_MEM );
459 : }
460 : ELSE
461 : {
462 684 : Copy_Scale_sig( &( resynth[1] ) + L_SUBFR - L_SYN_MEM, hPFstat->mem_stp, L_SYN_MEM, 1 );
463 : }
464 :
465 : /* Tilt filtering */
466 681881 : Filt_mu_ivas_fx( resynth, sig_out, parcor0, L_SUBFR, -1 );
467 681881 : IF( scale_down )
468 : {
469 684 : Scale_sig( sig_out, L_SUBFR, 1 );
470 : }
471 :
472 : /* Gain control */
473 681881 : scale_st_fx( signal_ptr, sig_out, &hPFstat->gain_prec, L_SUBFR );
474 :
475 :
476 681881 : 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 2203 : 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 :
497 :
498 2203 : test();
499 2203 : IF( NE_16( coder_type, INACTIVE ) && LT_16( lp_noise, LP_NOISE_THR_FX ) )
500 : {
501 2203 : lp_noiseQ12 = shl_sat( lp_noise, 4 ); /* to go from Q8 to Q12 */
502 :
503 : /* ftmp = lp_noise*BG1_FX + CG1_FX */
504 2203 : tmp = mac_r( CG1_FX * 65536L, lp_noiseQ12, BG1_FX * 8 ); /* x8 to go from Q12 to Q15 */
505 2203 : tmp = s_min( tmp, POST_G1_FX );
506 2203 : tmp = s_max( tmp, GAMMA1_PST12K_MIN_FX );
507 :
508 2203 : *g1 = tmp;
509 2203 : move16();
510 :
511 : /* ftmp = lp_noise*BG2_FX + CG2_FX */
512 2203 : L_tmp = L_mac0( CG2_FX / 2 * 65536L, lp_noiseQ12, BG2_FX * 8 ); /* L_mac0 and /2 to go from Q12 to Q14 */
513 : /* we go to Q30 to avoid overflow CG2_FX*/
514 :
515 2203 : L_tmp = L_min( L_tmp, POST_G2_FX * 65536L / 2 ); /* /2 because L_tmp is Q30 */
516 2203 : L_tmp = L_max( L_tmp, GAMMA2_PST12K_MIN_FX * 65536L / 2 );
517 :
518 2203 : *g2 = extract_h( L_shl( L_tmp, 1 ) ); /* Q30=>Q31=>Q15 */
519 : }
520 : ELSE
521 : {
522 0 : *g1 = GAMMA1_PST12K_NOIS_FX;
523 0 : move16();
524 0 : *g2 = GAMMA2_PST12K_NOIS_FX;
525 0 : move16();
526 : }
527 :
528 : /* Set gain_factor of the harmonic filtering*/
529 : /* ftmp = (lp_noise - K_LP_NOISE)*C_LP_NOISE_FX */
530 2203 : L_tmp = L_mac( -CK_LP_NOISE_FX, lp_noise, C_LP_NOISE_FX ); /* tmp is in Q24 (from Q8) */
531 :
532 2203 : L_tmp = L_min( L_tmp, 64 * 65536L ); /* 0.25 in Q24 */
533 2203 : L_tmp = L_max( L_tmp, 0 );
534 :
535 2203 : *gain_factor = extract_h( L_shl( L_tmp, 7 ) ); /* Q24=>Q31=>Q15 */
536 :
537 :
538 2203 : return;
539 : }
540 :
541 : /*----------------------------------------------------------------------------
542 : * pst_ltp_fx
543 : *
544 : * Perform harmonic postfilter
545 : *----------------------------------------------------------------------------*/
546 0 : static void pst_ltp_fx(
547 : Word16 t0, /* i : pitch delay given by coder Q0 */
548 : Word16 *ptr_sig_in, /* i : postfilter i filter (residu2) Qx */
549 : Word16 *ptr_sig_pst0, /* o : harmonic postfilter o Qx */
550 : Word16 gain_factor /* i : Gain Factor (Q15) */
551 : )
552 : {
553 : Word32 L_temp;
554 :
555 : Word16 y_up[SIZ_Y_UP];
556 : Word16 sig_cadr[SIZ_RES2];
557 :
558 : Word16 *ptr_y_up;
559 : Word16 *ptr_sig;
560 : Word16 *ptr_sig_cadr;
561 :
562 : Word16 i;
563 : Word16 temp;
564 : Word16 ltpdel, phase;
565 : Word16 num_gltp, den_gltp;
566 : Word16 num2_gltp, den2_gltp;
567 : Word16 sh_num, sh_den;
568 : Word16 sh_num2, sh_den2;
569 : Word16 gain_plt;
570 : Word16 off_yup;
571 : Word16 nb_sh_sig;
572 :
573 :
574 : /* i signal justified on 13 bits */
575 0 : ptr_sig = ptr_sig_in - DECMEM_RES2; // Qx
576 0 : nb_sh_sig = getScaleFactor16( ptr_sig, DECMEM_RES2 + L_SUBFR );
577 0 : nb_sh_sig = sub( 3, nb_sh_sig );
578 :
579 0 : FOR( i = 0; i < DECMEM_RES2 + L_SUBFR; i++ )
580 : {
581 : /* nb_sh_sig may be >0, <0 or =0 */
582 0 : sig_cadr[i] = shr( ptr_sig[i], nb_sh_sig );
583 0 : move16();
584 : }
585 0 : ptr_sig_cadr = sig_cadr + DECMEM_RES2;
586 :
587 : /* Sub optimal delay search */
588 0 : search_del_fx( t0, ptr_sig_cadr, <pdel, &phase, &num_gltp, &den_gltp, &sh_num, &sh_den, y_up, &off_yup );
589 :
590 :
591 0 : IF( num_gltp == 0 )
592 : {
593 0 : Copy( ptr_sig_in, ptr_sig_pst0, L_SUBFR );
594 : }
595 : ELSE
596 : {
597 0 : IF( phase == 0 )
598 : {
599 0 : ptr_y_up = ptr_sig_in - ltpdel; // Qx
600 : }
601 : ELSE
602 : {
603 : /* Filtering with long filter */
604 0 : compute_ltp_l_fx( ptr_sig_cadr, ltpdel, phase, ptr_sig_pst0, &num2_gltp, &den2_gltp, &sh_num2, &sh_den2 );
605 :
606 :
607 0 : IF( EQ_16( select_ltp_fx( num_gltp, den_gltp, sh_num, sh_den, num2_gltp, den2_gltp, sh_num2, sh_den2 ), 1 ) )
608 : {
609 : /* select short filter */
610 0 : temp = sub( phase, 1 );
611 0 : L_temp = L_mult0( temp, L_SUBFR + 1 );
612 0 : temp = extract_l( L_temp );
613 0 : temp = add( temp, off_yup );
614 :
615 : /* ptr_y_up = y_up + (phase-1) * (L_SUBFR+1) + off_yup */
616 0 : ptr_y_up = y_up + temp;
617 : }
618 : ELSE
619 : {
620 : /* select long filter */
621 0 : num_gltp = num2_gltp;
622 0 : move16();
623 0 : den_gltp = den2_gltp;
624 0 : move16();
625 0 : sh_num = sh_num2;
626 0 : move16();
627 0 : sh_den = sh_den2;
628 0 : move16();
629 0 : ptr_y_up = ptr_sig_pst0;
630 : }
631 :
632 : /* rescale y_up */
633 0 : FOR( i = 0; i < L_SUBFR; i++ )
634 : {
635 : /* nb_sh_sig may be >0, <0 or =0 */
636 0 : ptr_y_up[i] = shl_sat( ptr_y_up[i], nb_sh_sig );
637 0 : move16();
638 : }
639 : }
640 :
641 0 : temp = sub( sh_num, sh_den );
642 0 : IF( temp >= 0 )
643 : {
644 0 : den_gltp = shr( den_gltp, temp );
645 : }
646 : ELSE
647 : {
648 0 : num_gltp = shl( num_gltp, temp ); /* >> (-temp) */
649 : }
650 0 : IF( GE_16( num_gltp, den_gltp ) )
651 : {
652 : /* beta bounded to 1 */
653 0 : gain_plt = MIN_GPLT_FX;
654 0 : move16();
655 : }
656 : ELSE
657 : {
658 : /* GAMMA_G = 0.5 */
659 : /* gain_plt = den_gltp x 2**15 / (den_gltp + 0.5 num_gltp) */
660 : /* shift 1 bit to avoid overflows in add */
661 0 : num_gltp = shr( num_gltp, 2 );
662 0 : den_gltp = shr( den_gltp, 1 );
663 0 : temp = add( den_gltp, num_gltp );
664 0 : gain_plt = div_s( den_gltp, temp ); /* Q15 */
665 : }
666 :
667 : /* decrease gain in noisy condition */
668 : /* gain_plt += (1.0f-gain_plt) * gain_factor */
669 : /* gain_plt = gain_plt + gain_factor - gain_plt*gain_factor */
670 0 : gain_plt = msu_r_sat( L_msu( L_deposit_h( gain_plt ), gain_plt, gain_factor ), -32768, gain_factor ); // Q15
671 :
672 : /** filtering by H0(z) = harmonic filter **/
673 0 : filt_plt_fx( ptr_sig_in, ptr_y_up, ptr_sig_pst0, gain_plt );
674 : }
675 0 : }
676 :
677 : /*----------------------------------------------------------------------------
678 : * search_del_fx:
679 : *
680 : * Computes best (shortest) integer LTP delay + fine search
681 : *---------------------------------------------------------------------------*/
682 0 : static void search_del_fx(
683 : Word16 t0, /* i : pitch delay given by coder Q0 */
684 : Word16 *ptr_sig_in, /* i : i signal (with delay line) */
685 : Word16 *ltpdel, /* o : delay = *ltpdel - *phase / f_up */
686 : Word16 *phase, /* o : phase */
687 : Word16 *num_gltp, /* o : 16 bits numerator of LTP gain Q(sh_num_gltp) */
688 : Word16 *den_gltp, /* o : 16 bits denominator of LTP gain Q(sh_den_gltp) */
689 : Word16 *sh_num_gltp, /* o : justification for num_gltp */
690 : Word16 *sh_den_gltp, /* o : justification for den_gltp */
691 : Word16 *y_up, /* o : LT delayed signal if fract. delay */
692 : Word16 *off_yup /* o : offset in y_up */
693 : )
694 : {
695 : Word32 L_den0[F_UP_PST - 1];
696 : Word32 L_den1[F_UP_PST - 1];
697 :
698 : Word32 *ptr_L_den0, *ptr_L_den1;
699 :
700 : Word32 L_num_int, L_den_int, L_den_max;
701 : Word32 L_temp0, L_temp1;
702 : Word32 L_acc;
703 : Word32 L_temp;
704 :
705 : const Word16 *ptr_h;
706 : Word16 *ptr_sig_past, *ptr_sig_past0;
707 : Word16 *ptr1, *ptr_y_up;
708 :
709 : Word16 i, n;
710 : Word16 num /*Q(sh_num)*/, den0 /*Q(sh_den)*/, den1 /*Q(sh_den)*/;
711 : Word16 den_max, num_max;
712 : Word32 L_numsq_max;
713 : Word16 ener; // Q(sh_ener)
714 : Word16 sh_num, sh_den, sh_ener;
715 : Word16 i_max, lambda, phi, phi_max, ioff;
716 : Word16 temp;
717 :
718 :
719 : /*-------------------------------------
720 : * Computes energy of current signal
721 : *-------------------------------------*/
722 :
723 0 : L_acc = L_mult( ptr_sig_in[0], ptr_sig_in[0] );
724 0 : FOR( i = 1; i < L_SUBFR; i++ )
725 : {
726 0 : L_acc = L_mac_sat( L_acc, ptr_sig_in[i], ptr_sig_in[i] );
727 : }
728 0 : IF( L_acc == 0 )
729 : {
730 0 : *num_gltp = 0;
731 0 : move16();
732 0 : *den_gltp = 1;
733 0 : move16();
734 0 : *ltpdel = 0;
735 0 : move16();
736 0 : *phase = 0;
737 0 : move16();
738 :
739 0 : return;
740 : }
741 0 : sh_ener = sub( 16, norm_l( L_acc ) );
742 : /* save energy for final decision */
743 0 : sh_ener = s_max( 0, sh_ener );
744 0 : ener = extract_l( L_shr( L_acc, sh_ener ) );
745 :
746 : /*-------------------------------------
747 : * Selects best of 3 integer delays
748 : * Maximum of 3 numerators around t0
749 : *-------------------------------------*/
750 0 : lambda = sub( t0, 1 );
751 0 : ptr_sig_past = ptr_sig_in - lambda;
752 0 : L_num_int = L_deposit_l( -1 );
753 :
754 : /* initialization used only to suppress Microsoft Visual C++ warnings */
755 0 : i_max = (Word16) 0;
756 0 : move16();
757 :
758 0 : FOR( i = 0; i < 3; i++ )
759 : {
760 0 : L_acc = L_mult( ptr_sig_in[0], ptr_sig_past[0] );
761 0 : FOR( n = 1; n < L_SUBFR; n++ )
762 : {
763 0 : L_acc = L_mac_sat( L_acc, ptr_sig_in[n], ptr_sig_past[n] );
764 : }
765 :
766 :
767 0 : L_acc = L_max( L_acc, 0 );
768 0 : L_temp = L_sub_sat( L_acc, L_num_int );
769 0 : if ( L_temp > 0L )
770 : {
771 0 : i_max = (Word16) i;
772 0 : move16();
773 : }
774 0 : L_num_int = L_max( L_num_int, L_acc );
775 0 : ptr_sig_past--;
776 : }
777 :
778 0 : IF( L_num_int == 0 )
779 : {
780 0 : *num_gltp = 0;
781 0 : move16();
782 0 : *den_gltp = 1;
783 0 : move16();
784 0 : *ltpdel = 0;
785 0 : move16();
786 0 : *phase = 0;
787 0 : move16();
788 :
789 0 : return;
790 : }
791 :
792 : /* Compute den for i_max */
793 0 : lambda = add( lambda, (Word16) i_max );
794 0 : ptr_sig_past = ptr_sig_in - lambda;
795 0 : temp = *ptr_sig_past++;
796 0 : move16();
797 0 : L_acc = L_mult( temp, temp );
798 0 : FOR( i = 1; i < L_SUBFR; i++ )
799 : {
800 0 : temp = *ptr_sig_past++;
801 0 : move16();
802 0 : L_acc = L_mac_sat( L_acc, temp, temp );
803 : }
804 0 : IF( L_acc == 0L )
805 : {
806 0 : *num_gltp = 0;
807 0 : move16();
808 0 : *den_gltp = 1;
809 0 : move16();
810 0 : *ltpdel = 0;
811 0 : move16();
812 0 : *phase = 0;
813 0 : move16();
814 :
815 0 : return;
816 : }
817 0 : L_den_int = L_acc; /* sets to 'L_acc' in 1 clock */
818 0 : move32();
819 :
820 : /*----------------------------------
821 : * Select best phase around lambda
822 : *----------------------------------
823 : * Compute y_up & denominators
824 : *----------------------------------*/
825 :
826 0 : ptr_y_up = y_up;
827 0 : L_den_max = L_den_int; /* sets to 'L_acc' in 1 clock */
828 0 : move32();
829 0 : ptr_L_den0 = L_den0;
830 0 : ptr_L_den1 = L_den1;
831 0 : ptr_h = tab_hup_s_fx;
832 0 : temp = sub( lambda, LH_UP_S - 1 );
833 0 : ptr_sig_past0 = ptr_sig_in - temp;
834 :
835 : /* Loop on phase */
836 0 : FOR( phi = 1; phi < F_UP_PST; phi++ )
837 : {
838 : /* Compute y_up for lambda+1 - phi/F_UP_PST */
839 : /* and lambda - phi/F_UP_PST */
840 :
841 0 : ptr_sig_past = ptr_sig_past0;
842 0 : FOR( n = 0; n <= L_SUBFR; n++ )
843 : {
844 0 : ptr1 = ptr_sig_past++;
845 :
846 0 : L_acc = L_mult( ptr_h[0], ptr1[0] );
847 0 : FOR( i = 1; i < LH2_S; i++ )
848 : {
849 0 : L_acc = L_mac( L_acc, ptr_h[i], ptr1[-i] );
850 : }
851 0 : ptr_y_up[n] = round_fx( L_acc );
852 : }
853 :
854 : /* compute den0 (lambda+1) and den1 (lambda) */
855 :
856 : /* part common to den0 and den1 */
857 0 : L_acc = L_mult( ptr_y_up[1], ptr_y_up[1] );
858 0 : FOR( n = 2; n < L_SUBFR; n++ )
859 : {
860 0 : L_acc = L_mac_sat( L_acc, ptr_y_up[n], ptr_y_up[n] );
861 : }
862 0 : L_temp0 = L_acc; /* sets to 'L_acc' in 1 clock (saved for den1) */
863 0 : move32();
864 :
865 : /* den0 */
866 0 : L_acc = L_mac_sat( L_acc, ptr_y_up[0], ptr_y_up[0] );
867 0 : *ptr_L_den0 = L_acc;
868 0 : move32();
869 :
870 : /* den1 */
871 0 : L_acc = L_mac_sat( L_temp0, ptr_y_up[L_SUBFR], ptr_y_up[L_SUBFR] );
872 0 : *ptr_L_den1 = L_acc;
873 0 : move32();
874 :
875 0 : IF( GT_16( abs_s( ptr_y_up[0] ), abs_s( ptr_y_up[L_SUBFR] ) ) )
876 : {
877 0 : L_den_max = L_max( *ptr_L_den0, L_den_max );
878 : }
879 : ELSE
880 : {
881 0 : L_den_max = L_max( *ptr_L_den1, L_den_max );
882 : }
883 0 : ptr_L_den0++;
884 0 : ptr_L_den1++;
885 0 : ptr_y_up += ( L_SUBFR + 1 );
886 0 : ptr_h += LH2_S;
887 : }
888 :
889 0 : IF( L_den_max == 0 )
890 : {
891 0 : *num_gltp = 0;
892 0 : move16();
893 0 : *den_gltp = 1;
894 0 : move16();
895 0 : *ltpdel = 0;
896 0 : move16();
897 0 : *phase = 0;
898 0 : move16();
899 :
900 0 : return;
901 : }
902 :
903 0 : sh_den = sub( 16, norm_l( L_den_max ) );
904 : /* if sh_den <= 0 : dynamic between current frame */
905 : /* and delay line too high */
906 0 : IF( sh_den <= 0 )
907 : {
908 0 : *num_gltp = 0;
909 0 : move16();
910 0 : *den_gltp = 1;
911 0 : move16();
912 0 : *ltpdel = 0;
913 0 : move16();
914 0 : *phase = 0;
915 0 : move16();
916 :
917 0 : return;
918 : }
919 :
920 : /* search sh_num to justify correlations */
921 : /* sh_num = Max(sh_den, sh_ener) */
922 0 : sh_num = sh_ener;
923 0 : move16();
924 0 : if ( GE_16( sh_den, sh_ener ) )
925 : {
926 0 : sh_num = sh_den;
927 0 : move16();
928 : }
929 :
930 : /* Computation of the numerators */
931 : /* and selection of best num*num/den */
932 : /* for non null phases */
933 :
934 : /* Initialize with null phase */
935 0 : L_acc = L_shr( L_den_int, sh_den ); /* sh_den > 0 */
936 0 : den_max = extract_l( L_acc );
937 0 : L_acc = L_shr( L_num_int, sh_num ); /* sh_num > 0 */
938 0 : num_max = extract_l( L_acc );
939 0 : L_numsq_max = L_mult( num_max, num_max );
940 :
941 0 : phi_max = 0;
942 0 : move16();
943 0 : ioff = 1;
944 0 : move16();
945 :
946 0 : ptr_L_den0 = L_den0;
947 0 : ptr_L_den1 = L_den1;
948 0 : ptr_y_up = y_up;
949 :
950 :
951 : /* if den_max = 0 : will be selected and declared unvoiced */
952 : /* if num!=0 & den=0 : will be selected and declared unvoiced */
953 : /* degenerated seldom cases, switch off LT is OK */
954 :
955 : /* Loop on phase */
956 0 : FOR( phi = 1; phi < F_UP_PST; phi++ )
957 : {
958 : /* compute num for lambda+1 - phi/F_UP_PST */
959 0 : L_acc = L_mult( ptr_sig_in[0], ptr_y_up[0] );
960 0 : FOR( n = 1; n < L_SUBFR; n++ )
961 : {
962 0 : L_acc = L_mac_sat( L_acc, ptr_sig_in[n], ptr_y_up[n] );
963 : }
964 0 : L_acc = L_shr( L_acc, sh_num ); /* sh_num > 0 */
965 0 : L_acc = L_max( 0, L_acc );
966 0 : num = extract_l( L_acc );
967 :
968 : /* selection if num**2/den0 max */
969 0 : L_temp1 = L_mult( num, num );
970 0 : L_temp0 = Mpy_32_16_1( L_temp1, den_max );
971 0 : L_acc = L_add( *ptr_L_den0++, 0 );
972 0 : L_acc = L_shr( L_acc, sh_den ); /* sh_den > 0 */
973 0 : den0 = extract_l( L_acc );
974 0 : L_temp = Msub_32_16( L_temp0, L_numsq_max, den0 );
975 0 : IF( L_temp > 0L )
976 : {
977 0 : num_max = num;
978 0 : move16();
979 0 : L_numsq_max = L_temp1; /* sets to 'L_temp1' in 1 clock */
980 0 : move32();
981 0 : den_max = den0;
982 0 : move16();
983 0 : ioff = 0;
984 0 : move16();
985 0 : phi_max = phi;
986 0 : move16();
987 : }
988 :
989 : /* compute num for lambda - phi/F_UP_PST */
990 0 : ptr_y_up++;
991 :
992 0 : L_acc = L_mult( ptr_sig_in[0], ptr_y_up[0] );
993 0 : FOR( n = 1; n < L_SUBFR; n++ )
994 : {
995 0 : L_acc = L_mac_sat( L_acc, ptr_sig_in[n], ptr_y_up[n] );
996 : }
997 0 : L_acc = L_shr( L_acc, sh_num ); /* sh_num > 0 */
998 0 : L_acc = L_max( 0, L_acc );
999 0 : num = extract_l( L_acc );
1000 :
1001 : /* selection if num**2/den1 max */
1002 0 : L_temp1 = L_mult( num, num );
1003 0 : L_temp0 = Mpy_32_16_1( L_temp1, den_max );
1004 0 : L_acc = L_add( *ptr_L_den1++, 0 );
1005 0 : L_acc = L_shr( L_acc, sh_den ); /* sh_den > 0 */
1006 0 : den1 = extract_l( L_acc );
1007 0 : L_temp = Msub_32_16( L_temp0, L_numsq_max, den1 );
1008 0 : IF( L_temp > 0L )
1009 : {
1010 0 : num_max = num;
1011 0 : move16();
1012 0 : L_numsq_max = L_temp1; /* sets to 'L_temp1' in 1 clock */
1013 0 : move32();
1014 0 : den_max = den1;
1015 0 : move16();
1016 0 : ioff = 1;
1017 0 : move16();
1018 0 : phi_max = phi;
1019 0 : move16();
1020 : }
1021 :
1022 0 : ptr_y_up += L_SUBFR;
1023 : }
1024 :
1025 : /*---------------------------------------------------
1026 : * test if normalized crit0[iopt] > THRESHCRIT
1027 : *--------------------------------------------------*/
1028 0 : test();
1029 0 : IF( num_max == 0 || LE_16( den_max, 1 ) )
1030 : {
1031 0 : *num_gltp = 0;
1032 0 : move16();
1033 0 : *den_gltp = 1;
1034 0 : move16();
1035 0 : *ltpdel = 0;
1036 0 : move16();
1037 0 : *phase = 0;
1038 0 : move16();
1039 :
1040 0 : return;
1041 : }
1042 :
1043 : /* compare num**2 */
1044 : /* to ener * den * 0.5 */
1045 : /* (THRESHCRIT = 0.5) */
1046 0 : L_temp1 = L_mult( den_max, ener );
1047 :
1048 : /* temp = 2 * sh_num - sh_den - sh_ener + 1 */
1049 : /* 16 bits with no overflows */
1050 0 : temp = shl( sh_num, 1 );
1051 0 : temp = sub( temp, sh_den );
1052 0 : temp = sub( temp, sh_ener );
1053 0 : temp = add( temp, 1 );
1054 0 : IF( temp < 0 )
1055 : {
1056 0 : temp = negate( temp ); /* no overflow */
1057 0 : L_numsq_max = L_shr( L_numsq_max, temp );
1058 : }
1059 : ELSE
1060 : {
1061 0 : IF( temp > 0 )
1062 : {
1063 0 : L_temp1 = L_shr( L_temp1, temp );
1064 : }
1065 : }
1066 0 : L_temp = L_sub( L_numsq_max, L_temp1 );
1067 0 : IF( L_temp >= 0L )
1068 : {
1069 0 : temp = add( lambda, 1 );
1070 0 : *ltpdel = sub( temp, ioff );
1071 0 : *off_yup = ioff;
1072 0 : move16();
1073 0 : *phase = phi_max;
1074 0 : move16();
1075 0 : *num_gltp = num_max;
1076 0 : move16();
1077 0 : *den_gltp = den_max;
1078 0 : move16();
1079 0 : *sh_den_gltp = sh_den;
1080 0 : move16();
1081 0 : *sh_num_gltp = sh_num;
1082 0 : move16();
1083 : }
1084 : ELSE
1085 : {
1086 0 : *num_gltp = 0;
1087 0 : move16();
1088 0 : *den_gltp = 1;
1089 0 : move16();
1090 0 : *ltpdel = 0;
1091 0 : move16();
1092 0 : *phase = 0;
1093 0 : move16();
1094 : }
1095 :
1096 :
1097 0 : return;
1098 : }
1099 :
1100 : /*----------------------------------------------------------------------------
1101 : * filt_plt_fx:
1102 : *
1103 : * Perform long term postfilter
1104 : *----------------------------------------------------------------------------*/
1105 0 : static void filt_plt_fx(
1106 : Word16 *s_in, /* i : i signal with past Qx */
1107 : Word16 *s_ltp, /* i : filtered signal with gain 1 Qx*/
1108 : Word16 *s_out, /* o : signal Qx */
1109 : Word16 gain_plt /* i : filter gain Q15 */
1110 : )
1111 : {
1112 :
1113 : /* Local variables */
1114 : Word32 L_acc;
1115 :
1116 : Word16 n;
1117 : Word16 gain_plt_1;
1118 :
1119 :
1120 0 : gain_plt_1 = sub( 32767, gain_plt ); // Q15
1121 0 : gain_plt_1 = add( gain_plt_1, 1 ); /* 2**15 (1 - g) */
1122 :
1123 0 : FOR( n = 0; n < L_SUBFR; n++ )
1124 : {
1125 : /* s_out(n) = gain_plt x s_in(n) + gain_plt_1 x s_ltp(n) */
1126 0 : L_acc = L_mult( gain_plt, s_in[n] ); // Qx + Q15 + 1
1127 0 : s_out[n] = mac_r( L_acc, gain_plt_1, s_ltp[n] ); // Qx
1128 0 : move16(); /* no overflow */
1129 : }
1130 :
1131 :
1132 0 : return;
1133 : }
1134 :
1135 :
1136 : /*----------------------------------------------------------------------------
1137 : * compute_ltp_l_fx :
1138 : *
1139 : * compute delayed signal, num & den of gain for fractional delay
1140 : * with long interpolation filter
1141 : *----------------------------------------------------------------------------*/
1142 0 : static void compute_ltp_l_fx(
1143 : Word16 *s_in, /* i/o: signal with past */
1144 : Word16 ltpdel, /* i : delay factor */
1145 : Word16 phase, /* i : phase factor */
1146 : Word16 *y_up, /* i : delayed signal */
1147 : Word16 *num, /* i : numerator of LTP gain Q(sh_num) */
1148 : Word16 *den, /* i : denominator of LTP gain Q(sh_den) */
1149 : Word16 *sh_num, /* i : justification factor of num */
1150 : Word16 *sh_den /* i : justification factor of den */
1151 : )
1152 : {
1153 : Word32 L_acc;
1154 : Word16 *ptr2;
1155 : const Word16 *ptr_h;
1156 : Word16 n, i;
1157 : Word16 temp;
1158 :
1159 0 : temp = sub( phase, 1 );
1160 0 : temp = shl( temp, L2_LH2_L );
1161 0 : ptr_h = tab_hup_l_fx + temp; /* tab_hup_l_fx + LH2_L * (phase-1) */ // Q15
1162 :
1163 0 : temp = sub( LH_UP_L, ltpdel );
1164 0 : ptr2 = s_in + temp;
1165 :
1166 : /* Compute y_up */
1167 0 : FOR( n = 0; n < L_SUBFR; n++ )
1168 : {
1169 0 : L_acc = L_mult( ptr_h[0], *ptr2-- );
1170 :
1171 0 : FOR( i = 1; i < LH2_L; i++ )
1172 : {
1173 0 : L_acc = L_mac( L_acc, ptr_h[i], *ptr2-- );
1174 : }
1175 0 : y_up[n] = round_fx( L_acc );
1176 0 : ptr2 += LH2_L_P1;
1177 : }
1178 :
1179 : /* Compute num */
1180 0 : L_acc = L_mult( y_up[0], s_in[0] );
1181 0 : FOR( n = 1; n < L_SUBFR; n++ )
1182 : {
1183 0 : L_acc = L_mac( L_acc, y_up[n], s_in[n] );
1184 : }
1185 0 : IF( L_acc < 0L )
1186 : {
1187 0 : *num = 0;
1188 0 : move16();
1189 0 : *sh_num = 0;
1190 0 : move16();
1191 : }
1192 : ELSE
1193 : {
1194 0 : temp = sub( 16, norm_l( L_acc ) );
1195 0 : temp = s_max( temp, 0 );
1196 0 : L_acc = L_shr( L_acc, temp ); /* with temp >= 0 */
1197 0 : *num = extract_l( L_acc );
1198 0 : *sh_num = temp;
1199 0 : move16();
1200 0 : move16();
1201 : }
1202 :
1203 : /* Compute den */
1204 0 : L_acc = L_mult( y_up[0], y_up[0] );
1205 0 : FOR( n = 1; n < L_SUBFR; n++ )
1206 : {
1207 0 : L_acc = L_mac_sat( L_acc, y_up[n], y_up[n] );
1208 : }
1209 0 : temp = sub( 16, norm_l( L_acc ) );
1210 0 : temp = s_max( temp, 0 );
1211 0 : L_acc = L_shr( L_acc, temp ); /* with temp >= 0 */
1212 0 : *den = extract_l( L_acc );
1213 0 : *sh_den = temp;
1214 0 : move16();
1215 0 : move16();
1216 :
1217 :
1218 0 : return;
1219 : }
1220 :
1221 : /*----------------------------------------------------------------------------
1222 : * select_ltp_fx:
1223 : *
1224 : * selects best of (gain1, gain2)
1225 : * with gain1 = num1 * 2** sh_num1 / den1 * 2** sh_den1
1226 : * and gain2 = num2 * 2** sh_num2 / den2 * 2** sh_den2
1227 : *----------------------------------------------------------------------------*/
1228 0 : static Word16 select_ltp_fx( /* o : 1 = 1st gain, 2 = 2nd gain */
1229 : Word16 num1, /* i : numerator of gain1 Q(sh_num1) */
1230 : Word16 den1, /* i : denominator of gain1 Q(sh_den1) */
1231 : Word16 sh_num1, /* i : just. factor for num1 */
1232 : Word16 sh_den1, /* i : just. factor for den1 */
1233 : Word16 num2, /* i : numerator of gain2 Q(sh_num2) */
1234 : Word16 den2, /* i : denominator of gain2 Q(sh_den2) */
1235 : Word16 sh_num2, /* i : just. factor for num2 */
1236 : Word16 sh_den2 /* i : just. factor for den2 */
1237 : )
1238 : {
1239 : Word32 L_temp1, L_temp2;
1240 : Word32 L_temp;
1241 :
1242 : Word16 temp1, temp2;
1243 :
1244 :
1245 0 : IF( den2 == 0 )
1246 : {
1247 0 : return 1;
1248 : }
1249 :
1250 : /* compares criteria = num**2/den */
1251 0 : L_temp1 = L_mult( num1, num1 );
1252 0 : L_temp1 = Mpy_32_16_1( L_temp1, den2 );
1253 :
1254 0 : L_temp2 = L_mult( num2, num2 );
1255 0 : L_temp2 = Mpy_32_16_1( L_temp2, den1 );
1256 :
1257 : /* temp1 = sh_den2 + 2 * sh_num1 */
1258 0 : temp1 = shl( sh_num1, 1 );
1259 0 : temp1 = add( temp1, sh_den2 );
1260 : /* temp2 = sh_den1 + 2 * sh_num2; */
1261 0 : temp2 = shl( sh_num2, 1 );
1262 0 : temp2 = add( temp2, sh_den1 );
1263 :
1264 0 : temp2 = sub( temp2, temp1 );
1265 0 : IF( temp2 > 0 )
1266 : {
1267 0 : L_temp1 = L_shr( L_temp1, temp2 ); /* temp2 > 0 */
1268 : }
1269 0 : IF( temp2 < 0 )
1270 : {
1271 0 : L_temp2 = L_shl( L_temp2, temp2 ); /* temp2 < 0 */
1272 : }
1273 :
1274 0 : L_temp = L_sub( L_temp2, L_temp1 );
1275 0 : temp1 = 1;
1276 0 : move16();
1277 0 : if ( L_temp > 0L )
1278 : {
1279 0 : temp1 = 2;
1280 0 : move16();
1281 : }
1282 :
1283 0 : return temp1;
1284 : }
1285 :
1286 : /*----------------------------------------------------------------------------
1287 : * calc_st_filt_local_fx
1288 : *
1289 : * computes impulse response of A(gamma2) / A(gamma1)
1290 : * controls gain : computation of energy impulse response as
1291 : * SUMn (abs (h[n])) and computes parcor0
1292 : *---------------------------------------------------------------------------- */
1293 0 : static void calc_st_filt_local_fx(
1294 : Word16 *apond2, /* i : coefficients of numerator Q12 */
1295 : Word16 *apond1, /* i : coefficients of denominator Q12 */
1296 : Word16 *parcor0, /* o : 1st parcor calcul. on composed filter Q15*/
1297 : Word16 *sig_ltp_ptr, /* i/o: i of 1/A(gamma1) : scaled by 1/g0 Qx */
1298 : Word16 *mem_zero /* i : All zero memory */
1299 : )
1300 : {
1301 : Word32 L_g0;
1302 :
1303 : Word16 h[LONG_H_ST];
1304 :
1305 : Word16 g0, temp;
1306 : Word16 i;
1307 :
1308 :
1309 0 : temp = sub( 2, norm_s( apond2[0] ) );
1310 :
1311 : /* compute i.r. of composed filter apond2 / apond1 */
1312 0 : E_UTIL_synthesis( temp, apond1, apond2, h, LONG_H_ST, mem_zero, 0, M );
1313 :
1314 : /* compute 1st parcor */
1315 0 : Calc_rc0_h( h, parcor0 );
1316 :
1317 : /* compute g0 */
1318 0 : L_g0 = L_mult0( 1, abs_s( h[0] ) ); // Q12
1319 0 : FOR( i = 1; i < LONG_H_ST; i++ )
1320 : {
1321 0 : L_g0 = L_mac0( L_g0, 1, abs_s( h[i] ) ); // Q12
1322 : }
1323 0 : g0 = extract_h( L_shl( L_g0, 14 ) ); // Q10
1324 :
1325 : /* Scale signal i of 1/A(gamma1) */
1326 0 : IF( GT_16( g0, 1024 ) ) /*1024 = 1.Q10*/
1327 : {
1328 0 : temp = div_s( 1024, g0 ); /* temp => Q15 / gain0 */ /*1024 = 1.Q10*/
1329 0 : FOR( i = 0; i < L_SUBFR; i++ )
1330 : {
1331 0 : sig_ltp_ptr[i] = mult_r( sig_ltp_ptr[i], temp ); // Qx
1332 0 : move16();
1333 : }
1334 : }
1335 :
1336 :
1337 0 : return;
1338 : }
1339 :
1340 681881 : static void calc_st_filt_ivas_fx(
1341 : Word16 *apond2, /* i : coefficients of numerator Q12 */
1342 : Word16 *apond1, /* i : coefficients of denominator Q12 */
1343 : Word16 *parcor0, /* o : 1st parcor calcul. on composed filter Q15 */
1344 : Word16 *sig_ltp_ptr, /* i/o: i of 1/A(gamma1) : scaled by 1/g0 Qx*/
1345 : Word16 *mem_zero, /* i : All zero memory */
1346 : const Word16 extl /* i : extension layer info */
1347 : )
1348 : {
1349 : Word32 L_g0;
1350 :
1351 : Word16 h[LONG_H_ST]; // Q12
1352 :
1353 : Word16 g0, temp;
1354 : Word16 i;
1355 :
1356 :
1357 681881 : temp = sub( 2, norm_s( apond2[0] ) );
1358 :
1359 : /* compute i.r. of composed filter apond2 / apond1 */
1360 681881 : IF( EQ_16( extl, SWB_TBE ) )
1361 : {
1362 0 : E_UTIL_synthesis( temp, apond1, apond2, h, LONG_H_ST, mem_zero, 0, LPC_SHB_ORDER );
1363 : }
1364 : ELSE
1365 : {
1366 681881 : E_UTIL_synthesis( temp, apond1, apond2, h, LONG_H_ST, mem_zero, 0, M );
1367 : }
1368 :
1369 : /* compute 1st parcor */
1370 681881 : Calc_rc0_h( h, parcor0 );
1371 :
1372 : /* compute g0 */
1373 681881 : L_g0 = L_mult0( 1, abs_s( h[0] ) ); // Q12
1374 13637620 : FOR( i = 1; i < LONG_H_ST; i++ )
1375 : {
1376 12955739 : L_g0 = L_mac0( L_g0, 1, abs_s( h[i] ) ); // Q12
1377 : }
1378 681881 : g0 = extract_h( L_shl( L_g0, 14 ) ); // Q10
1379 :
1380 : /* Scale signal i of 1/A(gamma1) */
1381 681881 : IF( GT_16( g0, 1024 ) ) /*1024 = 1.Q10*/
1382 : {
1383 324992 : temp = div_s( 1024, g0 ); /* temp => Q15 / gain0 */ /*1024 = 1.Q10*/
1384 21124480 : FOR( i = 0; i < L_SUBFR; i++ )
1385 : {
1386 20799488 : sig_ltp_ptr[i] = mult_r( sig_ltp_ptr[i], temp ); // Qx
1387 20799488 : move16();
1388 : }
1389 : }
1390 :
1391 :
1392 681881 : return;
1393 : }
1394 : /*----------------------------------------------------------------------------
1395 : * filt_mu
1396 : *
1397 : * tilt filtering with : (1 + mu z-1) * (1/1-|mu|)
1398 : * computes y[n] = (1/1-|mu|) (x[n]+mu*x[n-1])
1399 : *---------------------------------------------------------------------------*/
1400 0 : void Filt_mu_fx(
1401 : Word16 *sig_in, /* i : signal (beginning at sample -1) */
1402 : Word16 *sig_out, /* o : signal with tilt */
1403 : Word16 parcor0, /* i : parcor0 (mu = parcor0 * gamma3) */
1404 : Word16 L_subfr /* i : the length of subframe */
1405 : )
1406 : {
1407 : Word32 L_acc, L_temp, L_fact;
1408 :
1409 : Word16 *ptrs;
1410 :
1411 : Word16 n;
1412 : Word16 mu, mu2, ga, temp;
1413 : Word16 fact, sh_fact;
1414 :
1415 :
1416 0 : IF( parcor0 > 0 )
1417 : {
1418 0 : mu = mult_r( parcor0, GAMMA3_PLUS_FX ); // Q15
1419 : /* GAMMA3_PLUS_FX < 0.5 */
1420 0 : sh_fact = 14;
1421 0 : move16(); /* sh_fact */
1422 0 : fact = (Word16) 0x4000;
1423 0 : move16(); /* Q(sh_fact) */
1424 0 : L_fact = (Word32) L_deposit_l( 0x2000 ); /* fact >> 1 */
1425 : }
1426 : ELSE
1427 : {
1428 0 : mu = mult_r( parcor0, GAMMA3_MINUS_FX ); // Q15
1429 : /* GAMMA3_MINUS_FX < 0.9375 */
1430 0 : sh_fact = 11;
1431 0 : move16(); /* sh_fact */
1432 0 : fact = (Word16) 0x0800;
1433 0 : move16(); /* Q(sh_fact) */
1434 0 : L_fact = (Word32) L_deposit_l( 0x0400 ); /* fact >> 1 */
1435 : }
1436 :
1437 0 : temp = sub( 1, abs_s( mu ) );
1438 : BASOP_SATURATE_WARNING_OFF_EVS;
1439 0 : mu2 = add_sat( 32767, temp ); /* Q15 (1 - |mu|) */
1440 : BASOP_SATURATE_WARNING_ON_EVS;
1441 0 : ga = div_s( fact, mu2 ); /* Q(sh_fact) / (1 - |mu|) */
1442 :
1443 0 : ptrs = sig_in; /* points on sig_in(-1) */
1444 :
1445 0 : sh_fact = sub( sh_fact, 16 ); /* to remove the saturate(), should shl by 16 before rounding */
1446 :
1447 0 : FOR( n = 0; n < L_subfr; n++ )
1448 : {
1449 0 : L_acc = L_mult0( mu, *ptrs++ );
1450 0 : L_temp = L_mac( L_acc, 16384, *ptrs ); /* sig_in(n) * 2**15 */
1451 :
1452 0 : L_temp = Madd_32_16( L_fact, L_temp, ga );
1453 0 : L_temp = L_shr_sat( L_temp, sh_fact ); /* mult. temp x ga */
1454 : BASOP_SATURATE_WARNING_OFF_EVS;
1455 : /*sig_out[n] = saturate(L_temp); move16();*/
1456 0 : sig_out[n] = round_fx_sat( L_temp );
1457 0 : move16();
1458 : BASOP_SATURATE_WARNING_ON_EVS;
1459 : }
1460 :
1461 :
1462 0 : return;
1463 : }
1464 :
1465 681881 : void Filt_mu_ivas_fx(
1466 : Word16 *sig_in, /* i : signal (beginning at sample -1) */
1467 : Word16 *sig_out, /* o : signal with tilt */
1468 : Word16 parcor0, /* i : parcor0 (mu = parcor0 * gamma3) Q15 */
1469 : Word16 L_subfr, /* i : the length of subframe */
1470 : const Word16 extl )
1471 : {
1472 : Word32 L_acc, L_temp, L_fact;
1473 :
1474 : Word16 *ptrs;
1475 :
1476 : Word16 n;
1477 : Word16 mu, mu2, ga, temp;
1478 : Word16 fact, sh_fact;
1479 :
1480 681881 : IF( EQ_16( extl, SWB_TBE ) )
1481 : {
1482 0 : IF( parcor0 > 0 )
1483 : {
1484 0 : mu = mult_r( parcor0, GAMMA3_PLUS_WB_FX ); // Q15
1485 : /* GAMMA3_PLUS_FX < 0.5 */
1486 0 : sh_fact = 14;
1487 0 : move16(); /* sh_fact */
1488 0 : fact = (Word16) 0x4000;
1489 0 : move16(); /* Q(sh_fact) */
1490 0 : L_fact = L_deposit_l( 0x2000 ); /* fact >> 1 */
1491 : }
1492 : ELSE
1493 : {
1494 0 : mu = mult_r( parcor0, GAMMA3_MINUS_WB_FX ); // Q15
1495 : /* GAMMA3_MINUS_FX < 0.9375 */
1496 0 : sh_fact = 11;
1497 0 : move16(); /* sh_fact */
1498 0 : fact = (Word16) 0x0800;
1499 0 : move16(); /* Q(sh_fact) */
1500 0 : L_fact = L_deposit_l( 0x0400 ); /* fact >> 1 */
1501 : }
1502 : }
1503 : ELSE
1504 : {
1505 681881 : IF( parcor0 > 0 )
1506 : {
1507 58331 : mu = mult_r( parcor0, GAMMA3_PLUS_FX ); // Q15
1508 : /* GAMMA3_PLUS_FX < 0.5 */
1509 58331 : sh_fact = 14;
1510 58331 : move16(); /* sh_fact */
1511 58331 : fact = (Word16) 0x4000;
1512 58331 : move16(); /* Q(sh_fact) */
1513 58331 : L_fact = L_deposit_l( 0x2000 ); /* fact >> 1 */
1514 : }
1515 : ELSE
1516 : {
1517 623550 : mu = mult_r( parcor0, GAMMA3_MINUS_FX ); // Q15
1518 : /* GAMMA3_MINUS_FX < 0.9375 */
1519 623550 : sh_fact = 11;
1520 623550 : move16(); /* sh_fact */
1521 623550 : fact = (Word16) 0x0800;
1522 623550 : move16(); /* Q(sh_fact) */
1523 623550 : L_fact = L_deposit_l( 0x0400 ); /* fact >> 1 */
1524 : }
1525 : }
1526 :
1527 681881 : temp = sub( 1, abs_s( mu ) );
1528 : BASOP_SATURATE_WARNING_OFF_EVS;
1529 681881 : mu2 = add_sat( 32767, temp ); /* Q15 (1 - |mu|) */
1530 : BASOP_SATURATE_WARNING_ON_EVS;
1531 681881 : ga = div_s( fact, mu2 ); /* Q(sh_fact) / (1 - |mu|) */
1532 :
1533 681881 : ptrs = sig_in; /* points on sig_in(-1) */
1534 :
1535 681881 : sh_fact = sub( sh_fact, 16 ); /* to remove the saturate(), should shl by 16 before rounding */
1536 :
1537 44322265 : FOR( n = 0; n < L_subfr; n++ )
1538 : {
1539 43640384 : L_acc = L_mult0( mu, *ptrs++ );
1540 43640384 : L_temp = L_mac( L_acc, 16384, *ptrs ); /* sig_in(n) * 2**15 */
1541 :
1542 43640384 : L_temp = Madd_32_16( L_fact, L_temp, ga );
1543 43640384 : L_temp = L_shr( L_temp, sh_fact ); /* mult. temp x ga */
1544 :
1545 : BASOP_SATURATE_WARNING_OFF_EVS;
1546 : /*sig_out[n] = saturate(L_temp); move16();*/
1547 43640384 : sig_out[n] = round_fx_sat( L_temp );
1548 : BASOP_SATURATE_WARNING_ON_EVS;
1549 : }
1550 :
1551 :
1552 681881 : return;
1553 : }
1554 : /*----------------------------------------------------------------------------
1555 : * scale_st_fx()
1556 : *
1557 : * control of the subframe gain
1558 : * gain[n] = AGC_FAC_FX * gain[n-1] + (1 - AGC_FAC_FX) g_in/g_out
1559 : *---------------------------------------------------------------------------*/
1560 683108 : void scale_st_fx(
1561 : const Word16 *sig_in, /* i : postfilter i signal Qx */
1562 : Word16 *sig_out, /* i/o: postfilter o signal Qx */
1563 : Word16 *gain_prec, /* i/o: last value of gain for subframe Q14*/
1564 : Word16 L_subfr )
1565 : {
1566 : Word32 L_acc, L_temp;
1567 :
1568 : Word16 i;
1569 : Word16 scal_in, scal_out;
1570 : Word16 s_g_in, s_g_out, temp, sh_g0, g0;
1571 683108 : Word16 gain = 0;
1572 :
1573 :
1574 : /* compute i gain */
1575 683108 : L_acc = L_deposit_l( 0 );
1576 44402020 : FOR( i = 0; i < L_subfr; i++ )
1577 : {
1578 43718912 : IF( sig_in[i] > 0 )
1579 : {
1580 21573238 : L_acc = L_mac0( L_acc, 1, sig_in[i] );
1581 : }
1582 43718912 : IF( sig_in[i] < 0 )
1583 : {
1584 21920553 : L_acc = L_msu0( L_acc, 1, sig_in[i] );
1585 : }
1586 : }
1587 :
1588 683108 : g0 = 0;
1589 683108 : move16();
1590 683108 : IF( L_acc != 0L )
1591 : {
1592 682062 : scal_in = norm_l( L_acc );
1593 682062 : L_acc = L_shl( L_acc, scal_in );
1594 682062 : s_g_in = extract_h( L_acc ); /* normalized */
1595 :
1596 : /* Compute o gain */
1597 : {
1598 682062 : Word64 acc64 = 0;
1599 44334030 : FOR( i = 0; i < L_subfr; i++ )
1600 : {
1601 43651968 : acc64 = W_mac0_16_16( acc64, 1, abs_s( sig_out[i] ) );
1602 : }
1603 682062 : L_acc = W_sat_l( acc64 );
1604 : }
1605 682062 : IF( L_acc == 0L )
1606 : {
1607 763 : *gain_prec = 0;
1608 763 : move16();
1609 :
1610 763 : return;
1611 : }
1612 681299 : scal_out = norm_l( L_acc );
1613 681299 : L_acc = L_shl( L_acc, scal_out );
1614 681299 : s_g_out = extract_h( L_acc ); /* normalized */
1615 :
1616 681299 : sh_g0 = add( scal_in, 1 );
1617 681299 : sh_g0 = sub( sh_g0, scal_out ); /* scal_in - scal_out + 1 */
1618 681299 : IF( LT_16( s_g_in, s_g_out ) )
1619 : {
1620 212966 : g0 = div_s( s_g_in, s_g_out ); /* s_g_in/s_g_out in Q15 */
1621 : }
1622 : ELSE
1623 : {
1624 468333 : temp = sub( s_g_in, s_g_out ); /* sufficient since normalized */
1625 468333 : g0 = shr( div_s( temp, s_g_out ), 1 );
1626 468333 : g0 = add( g0, (Word16) 0x4000 ); /* s_g_in/s_g_out in Q14 */
1627 468333 : sh_g0 = sub( sh_g0, 1 );
1628 : }
1629 : /* L_gain_in/L_gain_out in Q14 */
1630 : /* overflows if L_gain_in > 2 * L_gain_out */
1631 681299 : g0 = shr_sat( g0, sh_g0 ); /* sh_g0 may be >0, <0, or =0 */
1632 681299 : g0 = mult_r( g0, AGC_FAC1_FX ); /* L_gain_in/L_gain_out * AGC_FAC1_FX */
1633 : }
1634 :
1635 : /* gain(n) = AGC_FAC gain(n-1) + AGC_FAC1 gain_in/gain_out */
1636 : /* sig_out(n) = gain(n) sig_out(n) */
1637 682345 : gain = *gain_prec;
1638 682345 : move16();
1639 44352425 : FOR( i = 0; i < L_subfr; i++ )
1640 : {
1641 43670080 : temp = mult_r( AGC_FAC_FX, gain );
1642 43670080 : gain = add( temp, g0 ); /* in Q14 */
1643 43670080 : L_temp = L_mult( gain, sig_out[i] );
1644 43670080 : L_temp = L_shl_sat( L_temp, 1 );
1645 43670080 : sig_out[i] = round_fx_sat( L_temp );
1646 43670080 : move16();
1647 : }
1648 682345 : *gain_prec = gain;
1649 682345 : move16();
1650 :
1651 :
1652 682345 : return;
1653 : }
1654 :
1655 : /*----------------------------------------------------------------------------
1656 : * blend_subfr2_fx()
1657 : *
1658 : *
1659 : *---------------------------------------------------------------------------*/
1660 :
1661 1227 : void blend_subfr2_fx(
1662 : Word16 *sigIn1, // Qx
1663 : Word16 *sigIn2, // Qx
1664 : Word16 *sigOut // Qx
1665 : )
1666 : {
1667 1227 : Word16 fac1 = 32768 - 512; // 1.Q15 - ( 1.Q15 / L_SUBFR );
1668 1227 : Word16 fac2 = 0 + 512; // 0.Q15 + ( 1.Q15 / L_SUBFR );
1669 1227 : Word16 step = 1024; // 1.Q15 / ( L_SUBFR / 2 );
1670 : Word16 i;
1671 1227 : move16();
1672 1227 : move16();
1673 1227 : move16();
1674 40491 : FOR( i = 0; i < L_SUBFR / 2; i++ )
1675 : {
1676 39264 : sigOut[i] = mac_r_sat( L_mult_sat( fac1, sigIn1[i] ), fac2, sigIn2[i] ); // Qx
1677 39264 : fac1 = sub_sat( fac1, step );
1678 39264 : fac2 = add_sat( fac2, step );
1679 39264 : move16();
1680 : }
1681 :
1682 1227 : return;
1683 : }
|