Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
4 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
5 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
6 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
7 : contributors to this repository. All Rights Reserved.
8 :
9 : This software is protected by copyright law and by international treaties.
10 : The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
11 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
12 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
13 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
14 : contributors to this repository retain full ownership rights in their respective contributions in
15 : the software. This notice grants no license of any kind, including but not limited to patent
16 : license, nor is any license granted by implication, estoppel or otherwise.
17 :
18 : Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
19 : contributions.
20 :
21 : This software is provided "AS IS", without any express or implied warranties. The software is in the
22 : development stage. It is intended exclusively for experts who have experience with such software and
23 : solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
24 : and fitness for a particular purpose are hereby disclaimed and excluded.
25 :
26 : Any dispute, controversy or claim arising under or in relation to providing this software shall be
27 : submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
28 : accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
29 : the United Nations Convention on Contracts on the International Sales of Goods.
30 :
31 : *******************************************************************************************************/
32 :
33 : /*====================================================================================
34 : EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
35 : ====================================================================================*/
36 :
37 : #include <stdint.h>
38 : #include "options.h"
39 : #ifdef DEBUGGING
40 : #include "debug.h"
41 : #endif
42 : #include <math.h>
43 : #include "cnst.h"
44 : #include "rom_com.h"
45 : #include "prot.h"
46 : #include "wmc_auto.h"
47 :
48 : /*---------------------------------------------------------------------*
49 : * Local constants
50 : *---------------------------------------------------------------------*/
51 :
52 : #define FORMAT_POST_FILT_G1 0.75f /*0.75f*/ /*denominator 0.9,0.75,0.15,0.9*/
53 :
54 :
55 : /*--------------------------------------------------------------------------
56 : * Local function prototypes
57 : *--------------------------------------------------------------------------*/
58 :
59 : static void Dec_postfilt( const int16_t L_subfr, PFSTAT *pfstat, const int16_t t0, const float *signal_ptr, const float *coeff, float *sig_out, const float gamma1, const float gamma2, const float gain_factor, const int16_t disable_hpf );
60 :
61 : static void pst_ltp( const int16_t t0, const float *ptr_sig_in, float *ptr_sig_pst0, float gain_factor, const int16_t L_subfr );
62 :
63 : static void search_del( const int16_t t0, const float *ptr_sig_in, int16_t *ltpdel, int16_t *phase, float *num_gltp, float *den_gltp, float *y_up, int16_t *off_yup, const int16_t L_subfr );
64 :
65 : static void filt_plt( const float *s_in, const float *s_ltp, float *s_out, const float gain_plt, const int16_t L_subfr );
66 :
67 : static void compute_ltp_l( const float *s_in, const int16_t ltpdel, const int16_t phase, float *y_up, float *num, float *den, const int16_t L_subfr );
68 :
69 : static int16_t select_ltp( const float num1, const float den1, const float num2, const float den2 );
70 :
71 : static void modify_pst_param( const float psf_lp_noise, float *g1, float *g2, const int16_t coder_type, float *gain_factor );
72 :
73 : static void Dec_formant_postfilt( PFSTAT *pfstat, const float *signal_ptr, const float *coeff, float *sig_out, const float gamma1, const float gamma2, const int16_t l_subfr );
74 :
75 :
76 : /*--------------------------------------------------------------------------*
77 : * Function Init_post_filter()
78 : *
79 : * Post-filter initialization
80 : *--------------------------------------------------------------------------*/
81 :
82 166027 : void Init_post_filter(
83 : PFSTAT_HANDLE hPFstat /* i/o: post-filter state memories handle */
84 : )
85 : {
86 : /* It is off by default */
87 166027 : hPFstat->on = 0;
88 :
89 : /* Reset */
90 166027 : hPFstat->reset = 0;
91 :
92 : /* Initialize arrays and pointers */
93 166027 : set_zero( hPFstat->mem_pf_in, L_SUBFR );
94 :
95 : /* res2 = A(gamma2) residual */
96 166027 : set_zero( hPFstat->mem_res2, DECMEM_RES2 );
97 :
98 : /* 1/A(gamma1) memory */
99 166027 : set_zero( hPFstat->mem_stp, L_SUBFR );
100 :
101 : /* null memory to compute i.r. of A(gamma2)/A(gamma1) */
102 166027 : set_zero( hPFstat->mem_zero, M );
103 :
104 : /* for gain adjustment */
105 166027 : hPFstat->gain_prec = 1.0f;
106 :
107 166027 : return;
108 : }
109 :
110 :
111 : /*--------------------------------------------------------------------------
112 : * nb_post_filt()
113 : *
114 : * Main routine to perform post filtering of NB signals
115 : *--------------------------------------------------------------------------*/
116 :
117 115627 : void nb_post_filt(
118 : const int16_t L_frame, /* i : frame length */
119 : const int16_t L_subfr, /* i : sub-frame length */
120 : PFSTAT_HANDLE hPFstat, /* i/o: Post filter related memories */
121 : float *psf_lp_noise, /* i/o: long term noise energy */
122 : const float tmp_noise, /* i : noise energy */
123 : float *synth, /* i/o: synthesis */
124 : const float *Aq, /* i : LP filter coefficient */
125 : const float *pitch_buf, /* i : floating pitch for each subframe */
126 : const int16_t coder_type, /* i : coder_type */
127 : const int16_t BER_detect, /* i : BER detect flag */
128 : const int16_t disable_hpf /* i : flag to disabled HPF */
129 : )
130 : {
131 : int16_t t0_first, i, j;
132 : const float *p_Aq;
133 : float *pf_in, post_G1, post_G2, gain_factor;
134 : float pf_in_buffer[M + L_FRAME16k];
135 :
136 115627 : if ( !BER_detect )
137 : {
138 : /* update long-term background noise energy during inactive frames */
139 115627 : if ( coder_type == INACTIVE )
140 : {
141 807 : *psf_lp_noise = 0.95f * *psf_lp_noise + 0.05f * tmp_noise;
142 : }
143 : }
144 :
145 : /* set post-filter input */
146 115627 : modify_pst_param( *psf_lp_noise, &post_G1, &post_G2, coder_type, &gain_factor );
147 :
148 115627 : if ( hPFstat->reset )
149 : {
150 106948 : set_zero( hPFstat->mem_res2, DECMEM_RES2 );
151 106948 : mvr2r( &synth[L_frame - L_SYN_MEM], hPFstat->mem_pf_in, L_SYN_MEM );
152 106948 : mvr2r( &synth[L_frame - L_SYN_MEM], hPFstat->mem_stp, L_SYN_MEM );
153 106948 : hPFstat->gain_prec = 1.0f;
154 106948 : hPFstat->reset = 0;
155 106948 : return;
156 : }
157 :
158 8679 : pf_in = &pf_in_buffer[M];
159 8679 : mvr2r( hPFstat->mem_pf_in + L_SYN_MEM - M, &pf_in[-M], M );
160 8679 : mvr2r( synth, pf_in, L_frame );
161 8679 : mvr2r( &synth[L_frame - L_SYN_MEM], hPFstat->mem_pf_in, L_SYN_MEM );
162 :
163 : /* deactivation of the post filter in case of AUDIO because it causes problems to singing sequences */
164 8679 : if ( coder_type == AUDIO )
165 : {
166 299 : post_G1 = 1.f;
167 299 : post_G2 = 1.f;
168 299 : gain_factor = 1.f;
169 : }
170 :
171 : /* run the post filter */
172 8679 : p_Aq = Aq;
173 43379 : for ( i = 0, j = 0; i < L_frame; i += L_subfr, j++ )
174 : {
175 34700 : t0_first = (int16_t) ( pitch_buf[j] + 0.5f );
176 :
177 34700 : Dec_postfilt( L_subfr, hPFstat, t0_first, &pf_in[i], p_Aq, &synth[i], post_G1, post_G2, gain_factor, disable_hpf );
178 :
179 34700 : p_Aq += ( M + 1 );
180 : }
181 :
182 8679 : return;
183 : }
184 :
185 :
186 : /*--------------------------------------------------------------------------
187 : * formant_post_filt:
188 : *
189 : * WB and SWB formant post-filtering
190 : *--------------------------------------------------------------------------*/
191 :
192 7273089 : void formant_post_filt(
193 : PFSTAT_HANDLE hPFstat, /* i/o: Post filter related memories */
194 : float *synth_in, /* i : 12k8 synthesis */
195 : const float *Aq, /* i : LP filter coefficient */
196 : float *synth_out, /* i/o: input signal */
197 : const int16_t L_frame, /* i : frame length */
198 : const int16_t L_subfr, /* i : sub-frame length */
199 : const float lp_noise, /* i : background noise energy */
200 : const int32_t brate, /* i : bitrate */
201 : const int16_t off_flag /* i : off flag */
202 : )
203 : {
204 : int16_t i_subfr;
205 : const float *p_Aq;
206 : float post_G1, post_G2;
207 :
208 : /*default parameter for noisy speech and high bitrates*/
209 7273089 : if ( L_frame == L_FRAME )
210 : {
211 2967682 : post_G2 = 0.7f;
212 2967682 : if ( lp_noise < LP_NOISE_THRESH ) /* Clean speech */
213 : {
214 2518796 : if ( brate < ACELP_13k20 ) /*Low rates*/
215 : {
216 1649356 : post_G1 = 0.8f;
217 : }
218 869440 : else if ( brate < ACELP_24k40 )
219 : {
220 868737 : post_G1 = 0.75f;
221 : }
222 : else
223 : {
224 703 : post_G1 = 0.72f;
225 : }
226 : }
227 : else /*Noisy speech*/
228 : {
229 448886 : if ( brate < ACELP_15k85 ) /*Low rates*/
230 : {
231 416317 : post_G1 = 0.75f;
232 : }
233 : else /*High rates*/
234 : {
235 32569 : post_G1 = 0.7f;
236 : }
237 : }
238 : }
239 : else
240 : {
241 4305407 : post_G2 = 0.76f;
242 4305407 : if ( lp_noise >= LP_NOISE_THRESH )
243 : {
244 1314284 : post_G1 = 0.76f;
245 : }
246 2991123 : else if ( brate == ACELP_13k20 )
247 : {
248 0 : post_G1 = 0.82f;
249 : }
250 2991123 : else if ( brate == ACELP_16k40 )
251 : {
252 12493 : post_G1 = 0.80f;
253 : }
254 2978630 : else if ( brate == ACELP_24k40 || brate == ACELP_32k )
255 : {
256 29811 : post_G1 = 0.78f;
257 : }
258 : else
259 : {
260 2948819 : post_G1 = 0.76f;
261 : }
262 : }
263 :
264 : /* Switch off post-filter*/
265 7273089 : if ( off_flag )
266 : {
267 987 : post_G1 = post_G2;
268 : }
269 :
270 : /* Reset post filter */
271 7273089 : if ( hPFstat->reset )
272 : {
273 3862352 : hPFstat->reset = 0;
274 3862352 : mvr2r( &synth_in[L_frame - L_SYN_MEM], hPFstat->mem_pf_in, L_SYN_MEM );
275 3862352 : mvr2r( &synth_in[L_frame - L_SYN_MEM], hPFstat->mem_stp, L_SYN_MEM );
276 3862352 : hPFstat->gain_prec = 1.f;
277 3862352 : mvr2r( synth_in, synth_out, L_frame );
278 :
279 3862352 : return;
280 : }
281 :
282 : /* input memory*/
283 3410737 : mvr2r( hPFstat->mem_pf_in, synth_in - L_SYN_MEM, L_SYN_MEM );
284 3410737 : mvr2r( &synth_in[L_frame - L_SYN_MEM], hPFstat->mem_pf_in, L_SYN_MEM );
285 :
286 : /* run the post filter */
287 3410737 : p_Aq = Aq;
288 18709645 : for ( i_subfr = 0; i_subfr < L_frame; i_subfr += L_subfr )
289 : {
290 15298908 : Dec_formant_postfilt( hPFstat, &synth_in[i_subfr], p_Aq, &synth_out[i_subfr], post_G1, post_G2, L_subfr );
291 :
292 15298908 : p_Aq += ( M + 1 );
293 : }
294 :
295 3410737 : return;
296 : }
297 :
298 :
299 : /*----------------------------------------------------------------------------
300 : * Dec_postfilt()
301 : *
302 : * Adaptive postfilter main function
303 : * Short-term postfilter :
304 : * Hst(z) = Hst0(z) Hst1(z)
305 : * Hst0(z) = 1/g0 A(gamma2)(z) / A(gamma1)(z)
306 : * if {hi} = i.r. filter A(gamma2)/A(gamma1) (truncated)
307 : * g0 = SUM(|hi|) if > 1
308 : * g0 = 1. else
309 : * Hst1(z) = 1/(1 - |mu|) (1 + mu z-1)
310 : * with mu = k1 * gamma3
311 : * k1 = 1st parcor calculated on {hi}
312 : * gamma3 = gamma3_minus if k1<0, gamma3_plus if k1>0
313 : * Long-term postfilter :
314 : * harmonic postfilter : H0(z) = gl * (1 + b * z-p)
315 : * b = gamma_g * gain_ltp
316 : * gl = 1 / 1 + b
317 : * computation of delay p on A(gamma2)(z) s(z)
318 : * sub optimal search
319 : * 1. search around 1st subframe delay (3 integer values)
320 : * 2. search around best integer with fract. delays (1/8)
321 : *----------------------------------------------------------------------------*/
322 :
323 34700 : static void Dec_postfilt(
324 : const int16_t L_subfr, /* i : sub-frame length */
325 : PFSTAT *pfstat, /* i/o: Post filter related memories */
326 : const int16_t t0, /* i : pitch delay given by coder */
327 : const float *signal_ptr, /* i : input signal (pointer to current subframe */
328 : const float *coeff, /* i : LPC coefficients for current subframe */
329 : float *sig_out, /* o : postfiltered output */
330 : const float gamma1, /* i : short term postfilt. den. weighting factor*/
331 : const float gamma2, /* i : short term postfilt. num. weighting factor*/
332 : const float gain_factor, /* i : Gain Factor */
333 : const int16_t disable_hpf /* i : flag to disable HPF */
334 : )
335 : {
336 : float apond1[M + 1]; /* s.t. denominator coeff. */
337 : float apond2[LONG_H_ST];
338 : float sig_ltp[L_SUBFR + 1]; /* H0 output signal */
339 : float res2[SIZ_RES2];
340 : float *sig_ltp_ptr;
341 : float *res2_ptr;
342 : float *ptr_mem_stp;
343 : float parcor0;
344 :
345 : /* Init pointers and restore memories */
346 34700 : res2_ptr = res2 + DECMEM_RES2;
347 34700 : ptr_mem_stp = pfstat->mem_stp + L_SYN_MEM - 1;
348 34700 : mvr2r( pfstat->mem_res2, res2, DECMEM_RES2 );
349 :
350 : /* Compute weighted LPC coefficients */
351 34700 : weight_a( coeff, apond1, gamma1, M );
352 34700 : weight_a( coeff, apond2, gamma2, M );
353 34700 : set_f( &apond2[M + 1], 0, LONG_H_ST - ( M + 1 ) );
354 :
355 : /* Compute A(gamma2) residual */
356 34700 : residu( apond2, M, signal_ptr, res2_ptr, L_subfr );
357 :
358 : /* Harmonic filtering */
359 34700 : sig_ltp_ptr = sig_ltp + 1;
360 :
361 34700 : if ( !disable_hpf )
362 : {
363 25655 : pst_ltp( t0, res2_ptr, sig_ltp_ptr, gain_factor, L_subfr );
364 : }
365 : else
366 : {
367 9045 : mvr2r( res2_ptr, sig_ltp_ptr, L_subfr );
368 : }
369 :
370 : /* Save last output of 1/A(gamma1) */
371 : /* (from preceding subframe) */
372 34700 : sig_ltp[0] = *ptr_mem_stp;
373 :
374 : /* Controls short term pst filter gain and compute parcor0 */
375 34700 : calc_st_filt( apond2, apond1, &parcor0, sig_ltp_ptr, pfstat->mem_zero, L_subfr, -1 );
376 :
377 34700 : syn_filt( apond1, M, sig_ltp_ptr, sig_ltp_ptr, L_subfr, pfstat->mem_stp + L_SYN_MEM - M, 0 );
378 34700 : mvr2r( sig_ltp_ptr + L_SUBFR - L_SYN_MEM, pfstat->mem_stp, L_SYN_MEM );
379 :
380 : /* Tilt filtering */
381 34700 : filt_mu( sig_ltp, sig_out, parcor0, L_subfr, -1 );
382 :
383 : /* Gain control */
384 34700 : scale_st( signal_ptr, sig_out, &( pfstat->gain_prec ), L_subfr, -1 );
385 :
386 : /* Update for next subframe */
387 34700 : mvr2r( &res2[L_subfr], pfstat->mem_res2, DECMEM_RES2 );
388 :
389 34700 : return;
390 : }
391 :
392 :
393 : /*----------------------------------------------------------------------------
394 : * Dec_formant_postfilt
395 : *
396 : * Post - adaptive postfilter main function
397 : * Short term postfilter :
398 : * Hst(z) = Hst0(z) Hst1(z)
399 : * Hst0(z) = 1/g0 A(gamma2)(z) / A(gamma1)(z)
400 : * if {hi} = i.r. filter A(gamma2)/A(gamma1) (truncated)
401 : * g0 = SUM(|hi|) if > 1
402 : * g0 = 1. else
403 : * Hst1(z) = 1/(1 - |mu|) (1 + mu z-1)
404 : * with mu = k1 * gamma3
405 : * k1 = 1st parcor calculated on {hi}
406 : * gamma3 = gamma3_minus if k1<0, gamma3_plus if k1>0
407 : *----------------------------------------------------------------------------*/
408 :
409 15298908 : static void Dec_formant_postfilt(
410 : PFSTAT_HANDLE hPFstat, /* i/o: states strucure */
411 : const float *signal_ptr, /* i : input signal (pointer to current subframe */
412 : const float *coeff, /* i : LPC coefficients for current subframe */
413 : float *sig_out, /* o : postfiltered output */
414 : const float gamma1, /* i : short term postfilt. den. weighting factor*/
415 : const float gamma2, /* i : short term postfilt. num. weighting factor*/
416 : const int16_t l_subfr /* i : subframe length */
417 : )
418 : {
419 : /* Local variables and arrays */
420 : float apond1[M + 1]; /* s.t. denominator coeff. */
421 : float apond2[LONG_H_ST];
422 : float res2[L_SUBFR];
423 : float resynth[L_SUBFR + 1];
424 : float parcor0;
425 :
426 : /* Compute weighted LPC coefficients */
427 15298908 : weight_a( coeff, apond1, gamma1, M );
428 15298908 : weight_a( coeff, apond2, gamma2, M );
429 :
430 15298908 : set_zero( &apond2[M + 1], LONG_H_ST - ( M + 1 ) );
431 :
432 : /* Compute A(gamma2) residual */
433 15298908 : residu( apond2, M, signal_ptr, res2, l_subfr );
434 :
435 : /* Controls short term pst filter gain and compute parcor0 */
436 15298908 : calc_st_filt( apond2, apond1, &parcor0, res2, hPFstat->mem_zero, l_subfr, -1 );
437 :
438 : /* 1/A(gamma1) filtering, mem_stp is updated */
439 15298908 : resynth[0] = *( hPFstat->mem_stp + L_SYN_MEM - 1 );
440 :
441 15298908 : syn_filt( apond1, M, res2, &( resynth[1] ), l_subfr, hPFstat->mem_stp + L_SYN_MEM - M, 0 );
442 :
443 15298908 : mvr2r( &( resynth[1] ) + l_subfr - L_SYN_MEM, hPFstat->mem_stp, L_SYN_MEM );
444 :
445 : /* Tilt filtering */
446 15298908 : filt_mu( resynth, sig_out, parcor0, l_subfr, -1 );
447 :
448 : /* Gain control */
449 15298908 : scale_st( signal_ptr, sig_out, &hPFstat->gain_prec, l_subfr, -1 );
450 :
451 15298908 : return;
452 : }
453 :
454 :
455 : /*----------------------------------------------------------------------------
456 : * pst_ltp()
457 : *
458 : * Perform harmonic postfilter
459 : *----------------------------------------------------------------------------*/
460 :
461 25655 : static void pst_ltp(
462 : const int16_t t0, /* i : pitch delay given by coder */
463 : const float *ptr_sig_in, /* i : postfilter input filter (residu2) */
464 : float *ptr_sig_pst0, /* o : harmonic postfilter output */
465 : float gain_factor, /* i : gain factor */
466 : const int16_t L_subfr /* i : sub-frame length */
467 : )
468 : {
469 : int16_t ltpdel, phase;
470 : float num_gltp, den_gltp;
471 : float num2_gltp, den2_gltp;
472 : float gain_plt;
473 : float y_up[SIZ_Y_UP];
474 : const float *ptr_y_up;
475 : int16_t off_yup;
476 :
477 : /* Suboptimal delay search */
478 25655 : search_del( t0, ptr_sig_in, <pdel, &phase, &num_gltp, &den_gltp, y_up, &off_yup, L_subfr );
479 :
480 25655 : if ( num_gltp == 0.0f )
481 : {
482 12814 : mvr2r( ptr_sig_in, ptr_sig_pst0, L_subfr );
483 : }
484 : else
485 : {
486 12841 : if ( phase == 0 )
487 : {
488 584 : ptr_y_up = ptr_sig_in - ltpdel;
489 : }
490 : else
491 : {
492 : /* filtering with long filter */
493 12257 : compute_ltp_l( ptr_sig_in, ltpdel, phase, ptr_sig_pst0, &num2_gltp, &den2_gltp, L_subfr );
494 :
495 12257 : if ( select_ltp( num_gltp, den_gltp, num2_gltp, den2_gltp ) == 1 )
496 : {
497 : /* select short filter */
498 9983 : ptr_y_up = y_up + ( ( phase - 1 ) * ( L_subfr + 1 ) + off_yup );
499 : }
500 : else
501 : {
502 : /* select long filter */
503 2274 : num_gltp = num2_gltp;
504 2274 : den_gltp = den2_gltp;
505 2274 : ptr_y_up = ptr_sig_pst0;
506 : }
507 : }
508 :
509 12841 : if ( num_gltp >= den_gltp )
510 : {
511 : /* beta bounded to 1 */
512 3929 : gain_plt = MIN_GPLT;
513 : }
514 : else
515 : {
516 8912 : gain_plt = den_gltp / ( den_gltp + ( (float) 0.5 ) * num_gltp );
517 : }
518 :
519 : /* decrease gain in noisy condition */
520 12841 : gain_plt += ( ( 1.0f - gain_plt ) * gain_factor );
521 :
522 : /* filtering by H0(z) = harmonic filter */
523 12841 : filt_plt( ptr_sig_in, ptr_y_up, ptr_sig_pst0, gain_plt, L_subfr );
524 : }
525 :
526 25655 : return;
527 : }
528 :
529 : /*----------------------------------------------------------------------------
530 : * search_del()
531 : *
532 : * Computes best (shortest) integer LTP delay + fine search
533 : *---------------------------------------------------------------------------*/
534 :
535 25655 : static void search_del(
536 : const int16_t t0, /* i : pitch delay given by coder */
537 : const float *ptr_sig_in, /* i : input signal (with delay line) */
538 : int16_t *ltpdel, /* o : delay = *ltpdel - *phase / f_up */
539 : int16_t *phase, /* o : phase */
540 : float *num_gltp, /* o : numerator of LTP gain */
541 : float *den_gltp, /* o : denominator of LTP gain */
542 : float *y_up, /* o : LT delayed signal if fract. delay*/
543 : int16_t *off_yup, /* o : offset in y_up */
544 : const int16_t L_subfr /* i : sub-frame length */
545 : )
546 : {
547 : const float *ptr_h;
548 : float tab_den0[F_UP_PST - 1], tab_den1[F_UP_PST - 1];
549 : float *ptr_den0, *ptr_den1;
550 : const float *ptr_sig_past, *ptr_sig_past0;
551 : const float *ptr1;
552 : int16_t i, n, ioff, i_max;
553 : float ener, num, numsq, den0, den1;
554 : float den_int, num_int;
555 : float den_max, num_max, numsq_max;
556 : int16_t phi_max;
557 : int16_t lambda, phi;
558 : float temp0, temp1;
559 : float *ptr_y_up;
560 :
561 : /*-------------------------------------
562 : * Computes energy of current signal
563 : *-------------------------------------*/
564 :
565 25655 : ener = 0.0f;
566 1667575 : for ( i = 0; i < L_subfr; i++ )
567 : {
568 1641920 : ener += ptr_sig_in[i] * ptr_sig_in[i];
569 : }
570 :
571 25655 : if ( ener < 0.1f )
572 : {
573 12 : *num_gltp = 0.0f;
574 12 : *den_gltp = 1.0f;
575 12 : *ltpdel = 0;
576 12 : *phase = 0;
577 :
578 12 : return;
579 : }
580 :
581 : /*-------------------------------------
582 : * Selects best of 3 integer delays
583 : * Maximum of 3 numerators around t0
584 : *-------------------------------------*/
585 :
586 25643 : lambda = t0 - 1;
587 25643 : ptr_sig_past = ptr_sig_in - lambda;
588 25643 : num_int = -1.0e30f;
589 25643 : i_max = 0;
590 :
591 102572 : for ( i = 0; i < 3; i++ )
592 : {
593 76929 : num = 0.0f;
594 5000385 : for ( n = 0; n < L_subfr; n++ )
595 : {
596 4923456 : num += ptr_sig_in[n] * ptr_sig_past[n];
597 : }
598 76929 : if ( num > num_int )
599 : {
600 46571 : i_max = i;
601 46571 : num_int = num;
602 : }
603 76929 : ptr_sig_past--;
604 : }
605 :
606 25643 : if ( num_int <= 0.0f )
607 : {
608 2796 : *num_gltp = 0.0f;
609 2796 : *den_gltp = 1.0f;
610 2796 : *ltpdel = 0;
611 2796 : *phase = 0;
612 :
613 2796 : return;
614 : }
615 :
616 : /* Calculates denominator for i_max */
617 22847 : lambda += i_max;
618 22847 : ptr_sig_past = ptr_sig_in - lambda;
619 22847 : den_int = (float) 0.;
620 1485055 : for ( n = 0; n < L_subfr; n++ )
621 : {
622 1462208 : den_int += ptr_sig_past[n] * ptr_sig_past[n];
623 : }
624 :
625 22847 : if ( den_int < (float) 0.1 )
626 : {
627 0 : *num_gltp = (float) 0.;
628 0 : *den_gltp = (float) 1.;
629 0 : *ltpdel = 0;
630 0 : *phase = 0;
631 0 : return;
632 : }
633 :
634 : /*----------------------------------
635 : * Select best phase around lambda
636 : * Compute y_up & denominators
637 : *----------------------------------*/
638 :
639 22847 : ptr_y_up = y_up;
640 22847 : den_max = den_int;
641 22847 : ptr_den0 = tab_den0;
642 22847 : ptr_den1 = tab_den1;
643 22847 : ptr_h = tab_hup_s;
644 22847 : ptr_sig_past0 = ptr_sig_in + LH_UP_S - 1 - lambda; /* points on lambda_max+1 */
645 :
646 : /* loop on phase */
647 182776 : for ( phi = 1; phi < F_UP_PST; phi++ )
648 : {
649 : /* Computes criterion for (lambda+1) - phi/F_UP_PST */
650 : /* and lambda - phi/F_UP_PST */
651 159929 : ptr_sig_past = ptr_sig_past0;
652 : /* computes y_up[n] */
653 10555314 : for ( n = 0; n <= L_subfr; n++ )
654 : {
655 10395385 : ptr1 = ptr_sig_past++;
656 10395385 : temp0 = (float) 0.;
657 51976925 : for ( i = 0; i < LH2_S; i++ )
658 : {
659 41581540 : temp0 += ptr_h[i] * ptr1[-i];
660 : }
661 10395385 : ptr_y_up[n] = temp0;
662 : }
663 :
664 : /* compute den0 (lambda+1) and den1 (lambda) */
665 : /* part common to den0 and den1 */
666 159929 : temp0 = (float) 0.;
667 10235456 : for ( n = 1; n < L_subfr; n++ )
668 : {
669 10075527 : temp0 += ptr_y_up[n] * ptr_y_up[n];
670 : }
671 :
672 : /* den0 */
673 159929 : den0 = temp0 + ptr_y_up[0] * ptr_y_up[0];
674 159929 : *ptr_den0++ = den0;
675 :
676 : /* den1 */
677 159929 : den1 = temp0 + ptr_y_up[L_subfr] * ptr_y_up[L_subfr];
678 159929 : *ptr_den1++ = den1;
679 159929 : if ( fabs( ptr_y_up[0] ) > fabs( ptr_y_up[L_subfr] ) )
680 : {
681 79876 : if ( den0 > den_max )
682 : {
683 11357 : den_max = den0;
684 : }
685 : }
686 : else
687 : {
688 80053 : if ( den1 > den_max )
689 : {
690 18146 : den_max = den1;
691 : }
692 : }
693 159929 : ptr_y_up += ( L_subfr + 1 );
694 159929 : ptr_h += LH2_S;
695 : }
696 22847 : if ( den_max < 0.1f )
697 : {
698 0 : *num_gltp = 0.0f;
699 0 : *den_gltp = 1.0f;
700 0 : *ltpdel = 0;
701 0 : *phase = 0;
702 0 : return;
703 : }
704 :
705 : /* Computation of the numerators */
706 : /* and selection of best num*num/den */
707 : /* for non null phases */
708 :
709 : /* Initialize with null phase */
710 22847 : num_max = num_int;
711 22847 : den_max = den_int;
712 22847 : numsq_max = num_max * num_max;
713 22847 : phi_max = 0;
714 22847 : ioff = 1;
715 :
716 22847 : ptr_den0 = tab_den0;
717 22847 : ptr_den1 = tab_den1;
718 22847 : ptr_y_up = y_up;
719 :
720 : /* if den_max = 0 : will be selected and declared unvoiced */
721 : /* if num!=0 & den=0 : will be selected and declared unvoiced */
722 : /* degenerated seldom cases, switch off LT is OK */
723 :
724 : /* Loop on phase */
725 182776 : for ( phi = 1; phi < F_UP_PST; phi++ )
726 : {
727 :
728 : /* computes num for lambda+1 - phi/F_UP_PST */
729 159929 : num = 0.0f;
730 10395385 : for ( n = 0; n < L_subfr; n++ )
731 : {
732 10235456 : num += ptr_sig_in[n] * ptr_y_up[n];
733 : }
734 159929 : if ( num < 0.0f )
735 : {
736 3026 : num = 0.0f;
737 : }
738 159929 : numsq = num * num;
739 :
740 : /* selection if num/sqrt(den0) max */
741 159929 : den0 = *ptr_den0++;
742 159929 : temp0 = numsq * den_max;
743 159929 : temp1 = numsq_max * den0;
744 159929 : if ( temp0 > temp1 )
745 : {
746 27372 : num_max = num;
747 27372 : numsq_max = numsq;
748 27372 : den_max = den0;
749 27372 : ioff = 0;
750 27372 : phi_max = phi;
751 : }
752 :
753 : /* computes num for lambda_max - phi/F_UP_PST */
754 159929 : ptr_y_up++;
755 159929 : num = (float) 0.;
756 10395385 : for ( n = 0; n < L_subfr; n++ )
757 : {
758 10235456 : num += ptr_sig_in[n] * ptr_y_up[n];
759 : }
760 159929 : if ( num < (float) 0. )
761 : {
762 3226 : num = (float) 0.;
763 : }
764 159929 : numsq = num * num;
765 :
766 : /* selection if num/sqrt(den1) max */
767 159929 : den1 = *ptr_den1++;
768 159929 : temp0 = numsq * den_max;
769 159929 : temp1 = numsq_max * den1;
770 159929 : if ( temp0 > temp1 )
771 : {
772 36982 : num_max = num;
773 36982 : numsq_max = numsq;
774 36982 : den_max = den1;
775 36982 : ioff = 1;
776 36982 : phi_max = phi;
777 : }
778 159929 : ptr_y_up += L_subfr;
779 : }
780 :
781 : /*---------------------------------------------------
782 : * test if normalized crit0[iopt] > THRESHCRIT
783 : *--------------------------------------------------*/
784 :
785 22847 : if ( ( num_max == 0.0f ) || ( den_max <= 0.1f ) )
786 : {
787 1 : *num_gltp = 0.0f;
788 1 : *den_gltp = 1.0f;
789 1 : *ltpdel = 0;
790 1 : *phase = 0;
791 1 : return;
792 : }
793 :
794 : /* comparison num * num */
795 : /* with ener * den x THRESCRIT */
796 22846 : temp1 = den_max * ener * THRESCRIT;
797 22846 : if ( numsq_max >= temp1 )
798 : {
799 12841 : *ltpdel = lambda + 1 - ioff;
800 12841 : *off_yup = ioff;
801 12841 : *phase = phi_max;
802 12841 : *num_gltp = num_max;
803 12841 : *den_gltp = den_max;
804 : }
805 : else
806 : {
807 10005 : *num_gltp = 0.0f;
808 10005 : *den_gltp = 1.0f;
809 10005 : *ltpdel = 0;
810 10005 : *phase = 0;
811 : }
812 :
813 22846 : return;
814 : }
815 :
816 : /*----------------------------------------------------------------------------
817 : * filt_plt()
818 : *
819 : * Perform long term postfilter
820 : *----------------------------------------------------------------------------*/
821 :
822 12841 : static void filt_plt(
823 : const float *s_in, /* i : input signal with past */
824 : const float *s_ltp, /* i : filtered signal with gain 1 */
825 : float *s_out, /* o : output signal */
826 : const float gain_plt, /* i : filter gain */
827 : const int16_t L_subfr /* i : the length of subframe */
828 : )
829 : {
830 : int16_t n;
831 : float gain_plt_1;
832 :
833 12841 : gain_plt_1 = (float) 1. - gain_plt;
834 :
835 834665 : for ( n = 0; n < L_subfr; n++ )
836 : {
837 821824 : s_out[n] = gain_plt * s_in[n] + gain_plt_1 * s_ltp[n];
838 : }
839 :
840 12841 : return;
841 : }
842 :
843 : /*----------------------------------------------------------------------------
844 : * compute_ltp_l()
845 : *
846 : * compute delayed signal, num & den of gain for fractional delay
847 : * with long interpolation filter
848 : *----------------------------------------------------------------------------*/
849 :
850 12257 : static void compute_ltp_l(
851 : const float *s_in, /* i : input signal with past */
852 : const int16_t ltpdel, /* i : delay factor */
853 : const int16_t phase, /* i : phase factor */
854 : float *y_up, /* o : delayed signal */
855 : float *num, /* o : numerator of LTP gain */
856 : float *den, /* o : denominator of LTP gain */
857 : const int16_t L_subfr /* i : the length of subframe */
858 : )
859 : {
860 : const float *ptr_h;
861 : int16_t n, i;
862 : const float *ptr2;
863 : float temp;
864 :
865 : /* Filtering with long filter */
866 12257 : ptr_h = tab_hup_l + ( phase - 1 ) * LH2_L;
867 12257 : ptr2 = s_in - ltpdel + LH_UP_L;
868 :
869 : /* Compute y_up */
870 796705 : for ( n = 0; n < L_subfr; n++ )
871 : {
872 784448 : temp = 0.0f;
873 13335616 : for ( i = 0; i < LH2_L; i++ )
874 : {
875 12551168 : temp += ptr_h[i] * *ptr2--;
876 : }
877 784448 : y_up[n] = temp;
878 784448 : ptr2 += LH2_L_P1;
879 : }
880 :
881 : /* Compute num */
882 12257 : *num = 0.0f;
883 796705 : for ( n = 0; n < L_subfr; n++ )
884 : {
885 784448 : *num += y_up[n] * s_in[n];
886 : }
887 :
888 12257 : if ( *num < 0.0f )
889 : {
890 0 : *num = 0.0f;
891 : }
892 :
893 : /* Compute den */
894 12257 : *den = 0.0f;
895 796705 : for ( n = 0; n < L_subfr; n++ )
896 : {
897 784448 : *den += y_up[n] * y_up[n];
898 : }
899 :
900 12257 : return;
901 : }
902 :
903 : /*----------------------------------------------------------------------------
904 : * select_ltp()
905 : *
906 : * selects best of (gain1, gain2)
907 : * with gain1 = num1 * 2** sh_num1 / den1 * 2** sh_den1
908 : * and gain2 = num2 * 2** sh_num2 / den2 * 2** sh_den2
909 : *----------------------------------------------------------------------------*/
910 :
911 : /*! r: 1 = 1st gain, 2 = 2nd gain */
912 12257 : static int16_t select_ltp(
913 : const float num1, /* i : numerator of gain1 */
914 : const float den1, /* i : denominator of gain1 */
915 : const float num2, /* i : numerator of gain2 */
916 : const float den2 /* i : denominator of gain2 */
917 : )
918 : {
919 12257 : if ( den2 == (float) 0. )
920 : {
921 0 : return ( 1 );
922 : }
923 :
924 12257 : if ( num2 * num2 * den1 > num1 * num1 * den2 )
925 : {
926 2274 : return ( 2 );
927 : }
928 : else
929 : {
930 9983 : return ( 1 );
931 : }
932 : }
933 :
934 :
935 : /*------------------------------------------------------------------------------------
936 : * modify_pst_param()
937 : *
938 : * Modify gamma1 and gamma2 values in function of the long-term noise level
939 : *-----------------------------------------------------------------------------------*/
940 :
941 115627 : static void modify_pst_param(
942 : const float psf_lp_noise, /* i : Long term noise energy */
943 : float *g1, /* o : Gamma1 used in post filter */
944 : float *g2, /* o : Gamma2 used in post filter */
945 : const int16_t coder_type, /* i : coder type */
946 : float *gain_factor /* o : Gain factor applied in post filtering */
947 : )
948 : {
949 : float ftmp;
950 :
951 115627 : if ( coder_type != INACTIVE && psf_lp_noise < LP_NOISE_THR )
952 : {
953 114820 : ftmp = psf_lp_noise * BG1 + CG1;
954 114820 : if ( ftmp > POST_G1 )
955 : {
956 114539 : ftmp = POST_G1;
957 : }
958 281 : else if ( ftmp < POST_G1_MIN )
959 : {
960 0 : ftmp = POST_G1_MIN;
961 : }
962 114820 : *g1 = ftmp;
963 :
964 114820 : ftmp = psf_lp_noise * BG2 + CG2;
965 114820 : if ( ftmp > POST_G2 )
966 : {
967 114539 : ftmp = POST_G2;
968 : }
969 281 : else if ( ftmp < POST_G2_MIN )
970 : {
971 156 : ftmp = POST_G2_MIN;
972 : }
973 114820 : *g2 = ftmp;
974 : }
975 : else
976 : {
977 807 : *g1 = POST_G1_NOIS;
978 807 : *g2 = POST_G2_NOIS;
979 : }
980 :
981 : /* Set gain_factor of the harmonic filtering */
982 115627 : ftmp = ( psf_lp_noise - K_LP_NOISE ) * C_LP_NOISE;
983 :
984 115627 : if ( ftmp >= 0.25f )
985 : {
986 : /* the noise is really high */
987 0 : *gain_factor = 0.25f;
988 : }
989 115627 : else if ( ftmp < 0 )
990 : {
991 115340 : *gain_factor = 0.0f;
992 : }
993 : else
994 : {
995 287 : *gain_factor = ftmp;
996 : }
997 :
998 115627 : return;
999 : }
|