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 11598 : void Init_post_filter(
83 : PFSTAT_HANDLE hPFstat /* i/o: post-filter state memories handle */
84 : )
85 : {
86 : /* It is off by default */
87 11598 : hPFstat->on = 0;
88 :
89 : /* Reset */
90 11598 : hPFstat->reset = 0;
91 :
92 : /* Initialize arrays and pointers */
93 11598 : set_zero( hPFstat->mem_pf_in, L_SUBFR );
94 :
95 : /* res2 = A(gamma2) residual */
96 11598 : set_zero( hPFstat->mem_res2, DECMEM_RES2 );
97 :
98 : /* 1/A(gamma1) memory */
99 11598 : set_zero( hPFstat->mem_stp, L_SUBFR );
100 :
101 : /* null memory to compute i.r. of A(gamma2)/A(gamma1) */
102 11598 : set_zero( hPFstat->mem_zero, M );
103 :
104 : /* for gain adjustment */
105 11598 : hPFstat->gain_prec = 1.0f;
106 :
107 11598 : return;
108 : }
109 :
110 :
111 : /*--------------------------------------------------------------------------
112 : * nb_post_filt()
113 : *
114 : * Main routine to perform post filtering of NB signals
115 : *--------------------------------------------------------------------------*/
116 :
117 7773 : 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 7773 : if ( !BER_detect )
137 : {
138 : /* update long-term background noise energy during inactive frames */
139 7773 : if ( coder_type == INACTIVE )
140 : {
141 0 : *psf_lp_noise = 0.95f * *psf_lp_noise + 0.05f * tmp_noise;
142 : }
143 : }
144 :
145 : /* set post-filter input */
146 7773 : modify_pst_param( *psf_lp_noise, &post_G1, &post_G2, coder_type, &gain_factor );
147 :
148 7773 : if ( hPFstat->reset )
149 : {
150 7773 : set_zero( hPFstat->mem_res2, DECMEM_RES2 );
151 7773 : mvr2r( &synth[L_frame - L_SYN_MEM], hPFstat->mem_pf_in, L_SYN_MEM );
152 7773 : mvr2r( &synth[L_frame - L_SYN_MEM], hPFstat->mem_stp, L_SYN_MEM );
153 7773 : hPFstat->gain_prec = 1.0f;
154 7773 : hPFstat->reset = 0;
155 7773 : return;
156 : }
157 :
158 0 : pf_in = &pf_in_buffer[M];
159 0 : mvr2r( hPFstat->mem_pf_in + L_SYN_MEM - M, &pf_in[-M], M );
160 0 : mvr2r( synth, pf_in, L_frame );
161 0 : 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 0 : if ( coder_type == AUDIO )
165 : {
166 0 : post_G1 = 1.f;
167 0 : post_G2 = 1.f;
168 0 : gain_factor = 1.f;
169 : }
170 :
171 : /* run the post filter */
172 0 : p_Aq = Aq;
173 0 : for ( i = 0, j = 0; i < L_frame; i += L_subfr, j++ )
174 : {
175 0 : t0_first = (int16_t) ( pitch_buf[j] + 0.5f );
176 :
177 0 : Dec_postfilt( L_subfr, hPFstat, t0_first, &pf_in[i], p_Aq, &synth[i], post_G1, post_G2, gain_factor, disable_hpf );
178 :
179 0 : p_Aq += ( M + 1 );
180 : }
181 :
182 0 : return;
183 : }
184 :
185 :
186 : /*--------------------------------------------------------------------------
187 : * formant_post_filt:
188 : *
189 : * WB and SWB formant post-filtering
190 : *--------------------------------------------------------------------------*/
191 :
192 857526 : 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 857526 : if ( L_frame == L_FRAME )
210 : {
211 426978 : post_G2 = 0.7f;
212 426978 : if ( lp_noise < LP_NOISE_THRESH ) /* Clean speech */
213 : {
214 362643 : if ( brate < ACELP_13k20 ) /*Low rates*/
215 : {
216 246849 : post_G1 = 0.8f;
217 : }
218 115794 : else if ( brate < ACELP_24k40 )
219 : {
220 115794 : post_G1 = 0.75f;
221 : }
222 : else
223 : {
224 0 : post_G1 = 0.72f;
225 : }
226 : }
227 : else /*Noisy speech*/
228 : {
229 64335 : if ( brate < ACELP_15k85 ) /*Low rates*/
230 : {
231 60510 : post_G1 = 0.75f;
232 : }
233 : else /*High rates*/
234 : {
235 3825 : post_G1 = 0.7f;
236 : }
237 : }
238 : }
239 : else
240 : {
241 430548 : post_G2 = 0.76f;
242 430548 : if ( lp_noise >= LP_NOISE_THRESH )
243 : {
244 56952 : post_G1 = 0.76f;
245 : }
246 373596 : else if ( brate == ACELP_13k20 )
247 : {
248 0 : post_G1 = 0.82f;
249 : }
250 373596 : else if ( brate == ACELP_16k40 )
251 : {
252 549 : post_G1 = 0.80f;
253 : }
254 373047 : else if ( brate == ACELP_24k40 || brate == ACELP_32k )
255 : {
256 4347 : post_G1 = 0.78f;
257 : }
258 : else
259 : {
260 368700 : post_G1 = 0.76f;
261 : }
262 : }
263 :
264 : /* Switch off post-filter*/
265 857526 : if ( off_flag )
266 : {
267 0 : post_G1 = post_G2;
268 : }
269 :
270 : /* Reset post filter */
271 857526 : if ( hPFstat->reset )
272 : {
273 369042 : hPFstat->reset = 0;
274 369042 : mvr2r( &synth_in[L_frame - L_SYN_MEM], hPFstat->mem_pf_in, L_SYN_MEM );
275 369042 : mvr2r( &synth_in[L_frame - L_SYN_MEM], hPFstat->mem_stp, L_SYN_MEM );
276 369042 : hPFstat->gain_prec = 1.f;
277 369042 : mvr2r( synth_in, synth_out, L_frame );
278 :
279 369042 : return;
280 : }
281 :
282 : /* input memory*/
283 488484 : mvr2r( hPFstat->mem_pf_in, synth_in - L_SYN_MEM, L_SYN_MEM );
284 488484 : mvr2r( &synth_in[L_frame - L_SYN_MEM], hPFstat->mem_pf_in, L_SYN_MEM );
285 :
286 : /* run the post filter */
287 488484 : p_Aq = Aq;
288 2664462 : for ( i_subfr = 0; i_subfr < L_frame; i_subfr += L_subfr )
289 : {
290 2175978 : Dec_formant_postfilt( hPFstat, &synth_in[i_subfr], p_Aq, &synth_out[i_subfr], post_G1, post_G2, L_subfr );
291 :
292 2175978 : p_Aq += ( M + 1 );
293 : }
294 :
295 488484 : 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 0 : 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 0 : res2_ptr = res2 + DECMEM_RES2;
347 0 : ptr_mem_stp = pfstat->mem_stp + L_SYN_MEM - 1;
348 0 : mvr2r( pfstat->mem_res2, res2, DECMEM_RES2 );
349 :
350 : /* Compute weighted LPC coefficients */
351 0 : weight_a( coeff, apond1, gamma1, M );
352 0 : weight_a( coeff, apond2, gamma2, M );
353 0 : set_f( &apond2[M + 1], 0, LONG_H_ST - ( M + 1 ) );
354 :
355 : /* Compute A(gamma2) residual */
356 0 : residu( apond2, M, signal_ptr, res2_ptr, L_subfr );
357 :
358 : /* Harmonic filtering */
359 0 : sig_ltp_ptr = sig_ltp + 1;
360 :
361 0 : if ( !disable_hpf )
362 : {
363 0 : pst_ltp( t0, res2_ptr, sig_ltp_ptr, gain_factor, L_subfr );
364 : }
365 : else
366 : {
367 0 : mvr2r( res2_ptr, sig_ltp_ptr, L_subfr );
368 : }
369 :
370 : /* Save last output of 1/A(gamma1) */
371 : /* (from preceding subframe) */
372 0 : sig_ltp[0] = *ptr_mem_stp;
373 :
374 : /* Controls short term pst filter gain and compute parcor0 */
375 0 : calc_st_filt( apond2, apond1, &parcor0, sig_ltp_ptr, pfstat->mem_zero, L_subfr, -1 );
376 :
377 0 : syn_filt( apond1, M, sig_ltp_ptr, sig_ltp_ptr, L_subfr, pfstat->mem_stp + L_SYN_MEM - M, 0 );
378 0 : mvr2r( sig_ltp_ptr + L_SUBFR - L_SYN_MEM, pfstat->mem_stp, L_SYN_MEM );
379 :
380 : /* Tilt filtering */
381 0 : filt_mu( sig_ltp, sig_out, parcor0, L_subfr, -1 );
382 :
383 : /* Gain control */
384 0 : scale_st( signal_ptr, sig_out, &( pfstat->gain_prec ), L_subfr, -1 );
385 :
386 : /* Update for next subframe */
387 0 : mvr2r( &res2[L_subfr], pfstat->mem_res2, DECMEM_RES2 );
388 :
389 0 : 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 2175978 : 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 2175978 : weight_a( coeff, apond1, gamma1, M );
428 2175978 : weight_a( coeff, apond2, gamma2, M );
429 :
430 2175978 : set_zero( &apond2[M + 1], LONG_H_ST - ( M + 1 ) );
431 :
432 : /* Compute A(gamma2) residual */
433 2175978 : residu( apond2, M, signal_ptr, res2, l_subfr );
434 :
435 : /* Controls short term pst filter gain and compute parcor0 */
436 2175978 : calc_st_filt( apond2, apond1, &parcor0, res2, hPFstat->mem_zero, l_subfr, -1 );
437 :
438 : /* 1/A(gamma1) filtering, mem_stp is updated */
439 2175978 : resynth[0] = *( hPFstat->mem_stp + L_SYN_MEM - 1 );
440 :
441 2175978 : syn_filt( apond1, M, res2, &( resynth[1] ), l_subfr, hPFstat->mem_stp + L_SYN_MEM - M, 0 );
442 :
443 2175978 : mvr2r( &( resynth[1] ) + l_subfr - L_SYN_MEM, hPFstat->mem_stp, L_SYN_MEM );
444 :
445 : /* Tilt filtering */
446 2175978 : filt_mu( resynth, sig_out, parcor0, l_subfr, -1 );
447 :
448 : /* Gain control */
449 2175978 : scale_st( signal_ptr, sig_out, &hPFstat->gain_prec, l_subfr, -1 );
450 :
451 2175978 : return;
452 : }
453 :
454 :
455 : /*----------------------------------------------------------------------------
456 : * pst_ltp()
457 : *
458 : * Perform harmonic postfilter
459 : *----------------------------------------------------------------------------*/
460 :
461 0 : 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 0 : search_del( t0, ptr_sig_in, <pdel, &phase, &num_gltp, &den_gltp, y_up, &off_yup, L_subfr );
479 :
480 0 : if ( num_gltp == 0.0f )
481 : {
482 0 : mvr2r( ptr_sig_in, ptr_sig_pst0, L_subfr );
483 : }
484 : else
485 : {
486 0 : if ( phase == 0 )
487 : {
488 0 : ptr_y_up = ptr_sig_in - ltpdel;
489 : }
490 : else
491 : {
492 : /* filtering with long filter */
493 0 : compute_ltp_l( ptr_sig_in, ltpdel, phase, ptr_sig_pst0, &num2_gltp, &den2_gltp, L_subfr );
494 :
495 0 : if ( select_ltp( num_gltp, den_gltp, num2_gltp, den2_gltp ) == 1 )
496 : {
497 : /* select short filter */
498 0 : ptr_y_up = y_up + ( ( phase - 1 ) * ( L_subfr + 1 ) + off_yup );
499 : }
500 : else
501 : {
502 : /* select long filter */
503 0 : num_gltp = num2_gltp;
504 0 : den_gltp = den2_gltp;
505 0 : ptr_y_up = ptr_sig_pst0;
506 : }
507 : }
508 :
509 0 : if ( num_gltp >= den_gltp )
510 : {
511 : /* beta bounded to 1 */
512 0 : gain_plt = MIN_GPLT;
513 : }
514 : else
515 : {
516 0 : gain_plt = den_gltp / ( den_gltp + ( (float) 0.5 ) * num_gltp );
517 : }
518 :
519 : /* decrease gain in noisy condition */
520 0 : gain_plt += ( ( 1.0f - gain_plt ) * gain_factor );
521 :
522 : /* filtering by H0(z) = harmonic filter */
523 0 : filt_plt( ptr_sig_in, ptr_y_up, ptr_sig_pst0, gain_plt, L_subfr );
524 : }
525 :
526 0 : return;
527 : }
528 :
529 : /*----------------------------------------------------------------------------
530 : * search_del()
531 : *
532 : * Computes best (shortest) integer LTP delay + fine search
533 : *---------------------------------------------------------------------------*/
534 :
535 0 : 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 0 : ener = 0.0f;
566 0 : for ( i = 0; i < L_subfr; i++ )
567 : {
568 0 : ener += ptr_sig_in[i] * ptr_sig_in[i];
569 : }
570 :
571 0 : if ( ener < 0.1f )
572 : {
573 0 : *num_gltp = 0.0f;
574 0 : *den_gltp = 1.0f;
575 0 : *ltpdel = 0;
576 0 : *phase = 0;
577 :
578 0 : return;
579 : }
580 :
581 : /*-------------------------------------
582 : * Selects best of 3 integer delays
583 : * Maximum of 3 numerators around t0
584 : *-------------------------------------*/
585 :
586 0 : lambda = t0 - 1;
587 0 : ptr_sig_past = ptr_sig_in - lambda;
588 0 : num_int = -1.0e30f;
589 0 : i_max = 0;
590 :
591 0 : for ( i = 0; i < 3; i++ )
592 : {
593 0 : num = 0.0f;
594 0 : for ( n = 0; n < L_subfr; n++ )
595 : {
596 0 : num += ptr_sig_in[n] * ptr_sig_past[n];
597 : }
598 0 : if ( num > num_int )
599 : {
600 0 : i_max = i;
601 0 : num_int = num;
602 : }
603 0 : ptr_sig_past--;
604 : }
605 :
606 0 : if ( num_int <= 0.0f )
607 : {
608 0 : *num_gltp = 0.0f;
609 0 : *den_gltp = 1.0f;
610 0 : *ltpdel = 0;
611 0 : *phase = 0;
612 :
613 0 : return;
614 : }
615 :
616 : /* Calculates denominator for i_max */
617 0 : lambda += i_max;
618 0 : ptr_sig_past = ptr_sig_in - lambda;
619 0 : den_int = (float) 0.;
620 0 : for ( n = 0; n < L_subfr; n++ )
621 : {
622 0 : den_int += ptr_sig_past[n] * ptr_sig_past[n];
623 : }
624 :
625 0 : 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 0 : ptr_y_up = y_up;
640 0 : den_max = den_int;
641 0 : ptr_den0 = tab_den0;
642 0 : ptr_den1 = tab_den1;
643 0 : ptr_h = tab_hup_s;
644 0 : ptr_sig_past0 = ptr_sig_in + LH_UP_S - 1 - lambda; /* points on lambda_max+1 */
645 :
646 : /* loop on phase */
647 0 : 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 0 : ptr_sig_past = ptr_sig_past0;
652 : /* computes y_up[n] */
653 0 : for ( n = 0; n <= L_subfr; n++ )
654 : {
655 0 : ptr1 = ptr_sig_past++;
656 0 : temp0 = (float) 0.;
657 0 : for ( i = 0; i < LH2_S; i++ )
658 : {
659 0 : temp0 += ptr_h[i] * ptr1[-i];
660 : }
661 0 : ptr_y_up[n] = temp0;
662 : }
663 :
664 : /* compute den0 (lambda+1) and den1 (lambda) */
665 : /* part common to den0 and den1 */
666 0 : temp0 = (float) 0.;
667 0 : for ( n = 1; n < L_subfr; n++ )
668 : {
669 0 : temp0 += ptr_y_up[n] * ptr_y_up[n];
670 : }
671 :
672 : /* den0 */
673 0 : den0 = temp0 + ptr_y_up[0] * ptr_y_up[0];
674 0 : *ptr_den0++ = den0;
675 :
676 : /* den1 */
677 0 : den1 = temp0 + ptr_y_up[L_subfr] * ptr_y_up[L_subfr];
678 0 : *ptr_den1++ = den1;
679 0 : if ( fabs( ptr_y_up[0] ) > fabs( ptr_y_up[L_subfr] ) )
680 : {
681 0 : if ( den0 > den_max )
682 : {
683 0 : den_max = den0;
684 : }
685 : }
686 : else
687 : {
688 0 : if ( den1 > den_max )
689 : {
690 0 : den_max = den1;
691 : }
692 : }
693 0 : ptr_y_up += ( L_subfr + 1 );
694 0 : ptr_h += LH2_S;
695 : }
696 0 : 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 0 : num_max = num_int;
711 0 : den_max = den_int;
712 0 : numsq_max = num_max * num_max;
713 0 : phi_max = 0;
714 0 : ioff = 1;
715 :
716 0 : ptr_den0 = tab_den0;
717 0 : ptr_den1 = tab_den1;
718 0 : 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 0 : for ( phi = 1; phi < F_UP_PST; phi++ )
726 : {
727 :
728 : /* computes num for lambda+1 - phi/F_UP_PST */
729 0 : num = 0.0f;
730 0 : for ( n = 0; n < L_subfr; n++ )
731 : {
732 0 : num += ptr_sig_in[n] * ptr_y_up[n];
733 : }
734 0 : if ( num < 0.0f )
735 : {
736 0 : num = 0.0f;
737 : }
738 0 : numsq = num * num;
739 :
740 : /* selection if num/sqrt(den0) max */
741 0 : den0 = *ptr_den0++;
742 0 : temp0 = numsq * den_max;
743 0 : temp1 = numsq_max * den0;
744 0 : if ( temp0 > temp1 )
745 : {
746 0 : num_max = num;
747 0 : numsq_max = numsq;
748 0 : den_max = den0;
749 0 : ioff = 0;
750 0 : phi_max = phi;
751 : }
752 :
753 : /* computes num for lambda_max - phi/F_UP_PST */
754 0 : ptr_y_up++;
755 0 : num = (float) 0.;
756 0 : for ( n = 0; n < L_subfr; n++ )
757 : {
758 0 : num += ptr_sig_in[n] * ptr_y_up[n];
759 : }
760 0 : if ( num < (float) 0. )
761 : {
762 0 : num = (float) 0.;
763 : }
764 0 : numsq = num * num;
765 :
766 : /* selection if num/sqrt(den1) max */
767 0 : den1 = *ptr_den1++;
768 0 : temp0 = numsq * den_max;
769 0 : temp1 = numsq_max * den1;
770 0 : if ( temp0 > temp1 )
771 : {
772 0 : num_max = num;
773 0 : numsq_max = numsq;
774 0 : den_max = den1;
775 0 : ioff = 1;
776 0 : phi_max = phi;
777 : }
778 0 : ptr_y_up += L_subfr;
779 : }
780 :
781 : /*---------------------------------------------------
782 : * test if normalized crit0[iopt] > THRESHCRIT
783 : *--------------------------------------------------*/
784 :
785 0 : if ( ( num_max == 0.0f ) || ( den_max <= 0.1f ) )
786 : {
787 0 : *num_gltp = 0.0f;
788 0 : *den_gltp = 1.0f;
789 0 : *ltpdel = 0;
790 0 : *phase = 0;
791 0 : return;
792 : }
793 :
794 : /* comparison num * num */
795 : /* with ener * den x THRESCRIT */
796 0 : temp1 = den_max * ener * THRESCRIT;
797 0 : if ( numsq_max >= temp1 )
798 : {
799 0 : *ltpdel = lambda + 1 - ioff;
800 0 : *off_yup = ioff;
801 0 : *phase = phi_max;
802 0 : *num_gltp = num_max;
803 0 : *den_gltp = den_max;
804 : }
805 : else
806 : {
807 0 : *num_gltp = 0.0f;
808 0 : *den_gltp = 1.0f;
809 0 : *ltpdel = 0;
810 0 : *phase = 0;
811 : }
812 :
813 0 : return;
814 : }
815 :
816 : /*----------------------------------------------------------------------------
817 : * filt_plt()
818 : *
819 : * Perform long term postfilter
820 : *----------------------------------------------------------------------------*/
821 :
822 0 : 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 0 : gain_plt_1 = (float) 1. - gain_plt;
834 :
835 0 : for ( n = 0; n < L_subfr; n++ )
836 : {
837 0 : s_out[n] = gain_plt * s_in[n] + gain_plt_1 * s_ltp[n];
838 : }
839 :
840 0 : 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 0 : 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 0 : ptr_h = tab_hup_l + ( phase - 1 ) * LH2_L;
867 0 : ptr2 = s_in - ltpdel + LH_UP_L;
868 :
869 : /* Compute y_up */
870 0 : for ( n = 0; n < L_subfr; n++ )
871 : {
872 0 : temp = 0.0f;
873 0 : for ( i = 0; i < LH2_L; i++ )
874 : {
875 0 : temp += ptr_h[i] * *ptr2--;
876 : }
877 0 : y_up[n] = temp;
878 0 : ptr2 += LH2_L_P1;
879 : }
880 :
881 : /* Compute num */
882 0 : *num = 0.0f;
883 0 : for ( n = 0; n < L_subfr; n++ )
884 : {
885 0 : *num += y_up[n] * s_in[n];
886 : }
887 :
888 0 : if ( *num < 0.0f )
889 : {
890 0 : *num = 0.0f;
891 : }
892 :
893 : /* Compute den */
894 0 : *den = 0.0f;
895 0 : for ( n = 0; n < L_subfr; n++ )
896 : {
897 0 : *den += y_up[n] * y_up[n];
898 : }
899 :
900 0 : 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 0 : 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 0 : if ( den2 == (float) 0. )
920 : {
921 0 : return ( 1 );
922 : }
923 :
924 0 : if ( num2 * num2 * den1 > num1 * num1 * den2 )
925 : {
926 0 : return ( 2 );
927 : }
928 : else
929 : {
930 0 : 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 7773 : 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 7773 : if ( coder_type != INACTIVE && psf_lp_noise < LP_NOISE_THR )
952 : {
953 7773 : ftmp = psf_lp_noise * BG1 + CG1;
954 7773 : if ( ftmp > POST_G1 )
955 : {
956 7773 : ftmp = POST_G1;
957 : }
958 0 : else if ( ftmp < POST_G1_MIN )
959 : {
960 0 : ftmp = POST_G1_MIN;
961 : }
962 7773 : *g1 = ftmp;
963 :
964 7773 : ftmp = psf_lp_noise * BG2 + CG2;
965 7773 : if ( ftmp > POST_G2 )
966 : {
967 7773 : ftmp = POST_G2;
968 : }
969 0 : else if ( ftmp < POST_G2_MIN )
970 : {
971 0 : ftmp = POST_G2_MIN;
972 : }
973 7773 : *g2 = ftmp;
974 : }
975 : else
976 : {
977 0 : *g1 = POST_G1_NOIS;
978 0 : *g2 = POST_G2_NOIS;
979 : }
980 :
981 : /* Set gain_factor of the harmonic filtering */
982 7773 : ftmp = ( psf_lp_noise - K_LP_NOISE ) * C_LP_NOISE;
983 :
984 7773 : if ( ftmp >= 0.25f )
985 : {
986 : /* the noise is really high */
987 0 : *gain_factor = 0.25f;
988 : }
989 7773 : else if ( ftmp < 0 )
990 : {
991 7773 : *gain_factor = 0.0f;
992 : }
993 : else
994 : {
995 0 : *gain_factor = ftmp;
996 : }
997 :
998 7773 : return;
999 : }
|