Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 : #include <assert.h>
6 : #include <stdint.h>
7 : #include "options.h"
8 : #include "prot_fx.h"
9 : #include "basop_util.h"
10 :
11 : /*---------------------------------------------------------------------*
12 : * Function prototypes
13 : *---------------------------------------------------------------------*/
14 :
15 : static void bass_pf_1sf_delay( Word16 *syn, Word16 *T_sf, Word16 *gainT_sf, Word16 l_frame, Word16 l_subfr, Word16 *bpf_noise_buf, Word16 *gain_factor_param, Word8 disable_bpf, Word32 *lp_error_ener, Word32 *mem_error );
16 :
17 : /*---------------------------------------------------------------------*
18 : * post_decoder()
19 : *
20 : * Perform post-processing
21 : *---------------------------------------------------------------------*/
22 :
23 216499 : void post_decoder(
24 : Decoder_State *st,
25 : Word16 synth_buf[], /* Q0 */
26 : Word16 pit_gain[], /* Q14 */
27 : Word16 pitch[], /* Q0 */
28 : Word16 signal_out[], /* Q0 */
29 : Word16 *bpf_noise_buf /* Q0 */
30 : )
31 : {
32 : Word16 L_frame, nb_subfr;
33 : Word16 *synth, *synth2;
34 : Word16 pfstat_on_previous;
35 : Word16 pitch_gain_adjust[NB_SUBFR16k];
36 : Word16 tmp, tmp_noise;
37 : Word16 synth2_pe[L_FRAME_MAX];
38 : Word16 synth_buf2[PIT_MAX_16k + 1 + L_FRAME_MAX + M];
39 : Word32 bitrate;
40 : Word8 tmp8;
41 : BPF_DEC_HANDLE hBPF;
42 216499 : Word16 coder_type = st->coder_type;
43 :
44 216499 : move16();
45 216499 : hBPF = st->hBPF;
46 216499 : L_frame = st->L_frame;
47 216499 : move16();
48 216499 : nb_subfr = st->nb_subfr;
49 216499 : move16();
50 216499 : pfstat_on_previous = st->hPFstat->on;
51 216499 : move16();
52 216499 : st->hPFstat->on = 0;
53 216499 : move16();
54 :
55 216499 : bitrate = L_add( st->total_brate, 0 );
56 216499 : if ( LE_32( st->core_brate, SID_2k40 ) )
57 : {
58 0 : bitrate = L_add( st->last_active_brate, 0 );
59 : }
60 :
61 :
62 : /*Adapt Bpf: copy old and current adapt bpf parameters*/
63 216499 : set16_fx( pitch_gain_adjust, st->bpf_gain_param, nb_subfr );
64 :
65 216499 : synth = synth_buf + st->hTcxDec->old_synth_len;
66 216499 : synth2 = synth_buf2 + NBPSF_PIT_MAX;
67 216499 : Copy( hBPF->pst_old_syn_fx, synth_buf2, NBPSF_PIT_MAX );
68 :
69 216499 : IF( st->tcxonly != 0 )
70 : {
71 102008 : Copy( synth, synth2, L_frame );
72 102008 : IF( pfstat_on_previous )
73 : {
74 222 : Copy( st->hPFstat->mem_pf_in + L_SYN_MEM - M, synth - M, M );
75 222 : Residu3_fx( st->old_Aq_12_8_fx, synth, synth_buf, L_SUBFR, 1 );
76 222 : E_UTIL_synthesis( 1, st->old_Aq_12_8_fx, synth_buf, synth2, L_SUBFR, st->hPFstat->mem_stp + L_SYN_MEM - M, 0, M );
77 222 : scale_st_fx( synth, synth2, &st->hPFstat->gain_prec, L_SUBFR );
78 222 : blend_subfr2_fx( synth2 + L_SUBFR / 2, synth + L_SUBFR / 2, synth2 + L_SUBFR / 2 );
79 : }
80 : }
81 : ELSE
82 : {
83 : /*Formant enhancement*/
84 114491 : IF( ( st->last_bwidth == NB ) )
85 : {
86 89 : Copy( synth, synth2_pe, L_frame );
87 89 : tmp = synth[-1];
88 89 : move16();
89 :
90 89 : preemph_copy_fx( synth2_pe, synth2_pe, st->preemph_fac, L_frame, &tmp );
91 :
92 89 : tmp = 0;
93 89 : move16();
94 89 : test();
95 89 : test();
96 89 : if ( ( GT_32( st->lp_noise, LP_NOISE_THRESH ) ) ||
97 89 : ( st->core != ACELP_CORE ) ||
98 0 : ( EQ_16( coder_type, UNVOICED ) ) )
99 : {
100 89 : tmp = 1;
101 89 : move16();
102 : }
103 :
104 89 : if ( pfstat_on_previous == 0 )
105 : {
106 89 : st->hPFstat->reset = 1;
107 89 : move16();
108 : }
109 89 : IF( ( st->bwidth == NB ) )
110 : {
111 0 : st->hPFstat->on = 1;
112 0 : move16();
113 0 : tmp_noise = 0;
114 0 : move16();
115 0 : nb_post_filt_fx( L_frame, st->hPFstat, &tmp_noise, 0, synth2_pe, st->mem_Aq, pitch, GENERIC, st->BER_detect, tmp );
116 : }
117 : ELSE
118 : {
119 89 : st->hPFstat->on = 0;
120 89 : move16();
121 89 : tmp_noise = 0;
122 89 : move16();
123 89 : nb_post_filt_fx( L_frame, st->hPFstat, &tmp_noise, 0, synth2_pe, st->mem_Aq, pitch, AUDIO, st->BER_detect, tmp );
124 : }
125 89 : Copy( synth2_pe, synth2, L_frame );
126 :
127 89 : tmp = synth2[-1];
128 89 : move16();
129 89 : deemph_fx( synth2, st->preemph_fac, L_frame, &tmp );
130 : }
131 : ELSE
132 : {
133 114402 : if ( pfstat_on_previous == 0 )
134 : {
135 94962 : st->hPFstat->reset = 1;
136 94962 : move16();
137 : }
138 114402 : IF( GE_16( st->last_bwidth, WB ) )
139 : {
140 114402 : st->hPFstat->on = 1;
141 114402 : move16();
142 : #ifdef REMOVE_EVS_DUPLICATES
143 114402 : formant_post_filt_ivas_fx( st->hPFstat, synth, st->mem_Aq, synth2, L_frame, st->lp_noise, bitrate, 0 );
144 : #else
145 : formant_post_filt_fx( st->hPFstat, synth, st->mem_Aq, synth2, L_frame, st->lp_noise, bitrate, 0 );
146 : #endif
147 : }
148 : ELSE
149 : {
150 0 : st->hPFstat->on = 0;
151 0 : move16();
152 : #ifdef REMOVE_EVS_DUPLICATES
153 0 : formant_post_filt_ivas_fx( st->hPFstat, synth, st->mem_Aq, synth2, L_frame, st->lp_noise, bitrate, 1 );
154 : #else
155 : formant_post_filt_fx( st->hPFstat, synth, st->mem_Aq, synth2, L_frame, st->lp_noise, bitrate, 1 );
156 : #endif
157 : }
158 : }
159 :
160 : /*Bass Post-filter */
161 114491 : tmp8 = 0;
162 114491 : move16();
163 114491 : test();
164 114491 : if ( GT_32( st->lp_noise, LP_NOISE_THRESH ) && st->narrowBand )
165 : {
166 0 : tmp8 = 1;
167 0 : move16();
168 : }
169 114491 : bass_pf_1sf_delay( synth2, pitch, pit_gain, L_frame, L_SUBFR, bpf_noise_buf, pitch_gain_adjust,
170 : tmp8, &( st->lp_error_ener ), &( st->mem_error ) );
171 : }
172 :
173 : /* Output */
174 216499 : Copy( synth2, signal_out, L_frame );
175 :
176 : /* Update synth2 memory */
177 216499 : Copy( synth_buf2 + L_frame, hBPF->pst_old_syn_fx, NBPSF_PIT_MAX );
178 :
179 :
180 216499 : return;
181 : }
182 :
183 639140 : void post_decoder_ivas_fx(
184 : Decoder_State *st,
185 : Word16 synth_buf[], // Q0
186 : Word16 pit_gain[], // Q14
187 : Word16 pitch[], // Q0
188 : Word16 signal_out[], // Q0
189 : Word16 *bpf_noise_buf // Q0
190 : )
191 : {
192 : Word16 L_frame, nb_subfr;
193 : Word16 *synth, *synth2;
194 : Word16 pfstat_on_previous;
195 : Word16 pitch_gain_adjust[NB_SUBFR16k];
196 : Word16 tmp, tmp_noise;
197 : Word16 synth2_pe[L_FRAME_MAX];
198 : Word16 synth_buf2[PIT_MAX_16k + 1 + L_FRAME_MAX + M];
199 : Word32 bitrate;
200 : Word8 tmp8;
201 : BPF_DEC_HANDLE hBPF;
202 639140 : Word16 coder_type = st->coder_type;
203 :
204 639140 : move16();
205 639140 : hBPF = st->hBPF;
206 639140 : L_frame = st->L_frame;
207 639140 : move16();
208 639140 : nb_subfr = st->nb_subfr;
209 639140 : move16();
210 639140 : pfstat_on_previous = 0;
211 639140 : move16();
212 :
213 639140 : IF( st->hPFstat != NULL )
214 : {
215 0 : pfstat_on_previous = st->hPFstat->on;
216 0 : move16();
217 0 : st->hPFstat->on = 0;
218 0 : move16();
219 : }
220 :
221 639140 : bitrate = L_add( st->total_brate, 0 );
222 639140 : if ( LE_32( st->core_brate, SID_2k40 ) )
223 : {
224 0 : bitrate = L_add( st->last_active_brate, 0 );
225 : }
226 :
227 :
228 : /*Adapt Bpf: copy old and current adapt bpf parameters*/
229 639140 : set16_fx( pitch_gain_adjust, st->bpf_gain_param, nb_subfr );
230 :
231 639140 : synth = synth_buf + st->hTcxDec->old_synth_len;
232 639140 : synth2 = synth_buf2 + NBPSF_PIT_MAX;
233 :
234 639140 : IF( st->hBPF != NULL )
235 : {
236 0 : Copy( hBPF->pst_old_syn_fx, synth_buf2, NBPSF_PIT_MAX );
237 : }
238 :
239 639140 : IF( st->tcxonly != 0 )
240 : {
241 639140 : Copy( synth, synth2, L_frame );
242 639140 : IF( pfstat_on_previous )
243 : {
244 0 : Copy( st->hPFstat->mem_pf_in + L_SYN_MEM - M, synth - M, M );
245 0 : Word16 L_subfr = idiv1616( st->L_frame, st->nb_subfr );
246 0 : Residu3_fx( st->old_Aq_12_8_fx, synth, synth_buf, L_subfr, 1 );
247 0 : E_UTIL_synthesis( 1, st->old_Aq_12_8_fx, synth_buf, synth2, L_subfr, st->hPFstat->mem_stp + L_SYN_MEM - M, 0, M );
248 0 : scale_st_fx( synth, synth2, &st->hPFstat->gain_prec, L_subfr );
249 0 : blend_subfr2_fx( synth2 + shr( L_subfr, 1 ), synth + shr( L_subfr, 1 ), synth2 + shr( L_subfr, 1 ) );
250 : }
251 : }
252 : ELSE
253 : {
254 : /*Formant enhancement*/
255 0 : IF( st->last_bwidth == NB )
256 : {
257 0 : Copy( synth, synth2_pe, L_frame );
258 0 : tmp = synth[-1];
259 0 : move16();
260 :
261 0 : preemph_copy_fx( synth2_pe, synth2_pe, st->preemph_fac, L_frame, &tmp );
262 :
263 0 : tmp = 0;
264 0 : move16();
265 0 : test();
266 0 : test();
267 0 : if ( ( GT_32( st->lp_noise, LP_NOISE_THRESH ) ) ||
268 0 : ( st->core != ACELP_CORE ) ||
269 0 : ( EQ_16( coder_type, UNVOICED ) ) )
270 : {
271 0 : tmp = 1;
272 0 : move16();
273 : }
274 :
275 0 : if ( pfstat_on_previous == 0 )
276 : {
277 0 : st->hPFstat->reset = 1;
278 0 : move16();
279 : }
280 0 : IF( ( st->bwidth == NB ) )
281 : {
282 0 : st->hPFstat->on = 1;
283 0 : move16();
284 0 : tmp_noise = 0;
285 0 : move16();
286 0 : nb_post_filt_fx( L_frame, st->hPFstat, &tmp_noise, 0, synth2_pe, st->mem_Aq, pitch, GENERIC, st->BER_detect, tmp );
287 : }
288 : ELSE
289 : {
290 0 : st->hPFstat->on = 0;
291 0 : move16();
292 0 : tmp_noise = 0;
293 0 : move16();
294 0 : nb_post_filt_fx( L_frame, st->hPFstat, &tmp_noise, 0, synth2_pe, st->mem_Aq, pitch, AUDIO, st->BER_detect, tmp );
295 : }
296 0 : Copy( synth2_pe, synth2, L_frame );
297 :
298 0 : tmp = synth2[-1];
299 0 : move16();
300 0 : deemph_fx( synth2, st->preemph_fac, L_frame, &tmp );
301 : }
302 : ELSE
303 : {
304 0 : if ( pfstat_on_previous == 0 )
305 : {
306 0 : st->hPFstat->reset = 1;
307 0 : move16();
308 : }
309 0 : IF( GE_16( st->last_bwidth, WB ) )
310 : {
311 0 : st->hPFstat->on = 1;
312 0 : move16();
313 : #ifdef REMOVE_EVS_DUPLICATES
314 0 : formant_post_filt_ivas_fx( st->hPFstat, synth, st->mem_Aq, synth2, L_frame, st->lp_noise, bitrate, 0 );
315 : #else
316 : formant_post_filt_fx( st->hPFstat, synth, st->mem_Aq, synth2, L_frame, st->lp_noise, bitrate, 0 );
317 : #endif
318 : }
319 : ELSE
320 : {
321 0 : st->hPFstat->on = 0;
322 0 : move16();
323 : #ifdef REMOVE_EVS_DUPLICATES
324 0 : formant_post_filt_ivas_fx( st->hPFstat, synth, st->mem_Aq, synth2, L_frame, st->lp_noise, bitrate, 1 );
325 : #else
326 : formant_post_filt_fx( st->hPFstat, synth, st->mem_Aq, synth2, L_frame, st->lp_noise, bitrate, 1 );
327 : #endif
328 : }
329 : }
330 :
331 : /*Bass Post-filter */
332 0 : tmp8 = 0;
333 0 : move16();
334 0 : test();
335 0 : if ( GT_32( st->lp_noise, LP_NOISE_THRESH ) && st->narrowBand )
336 : {
337 0 : tmp8 = 1;
338 0 : move16();
339 : }
340 0 : bass_pf_1sf_delay( synth2, pitch, pit_gain, L_frame, L_SUBFR, bpf_noise_buf, pitch_gain_adjust,
341 : tmp8, &( st->lp_error_ener ), &( st->mem_error ) );
342 : }
343 :
344 : /* Output */
345 639140 : Copy( synth2, signal_out, L_frame );
346 :
347 : /* Update synth2 memory */
348 639140 : IF( st->hBPF != NULL )
349 : {
350 0 : Copy( synth_buf2 + L_frame, hBPF->pst_old_syn_fx, NBPSF_PIT_MAX );
351 : }
352 :
353 :
354 639140 : return;
355 : }
356 :
357 : /*---------------------------------------------------------------------*
358 : * bass_pf_1sf_delay()
359 : *
360 : * Perform low-frequency postfiltering
361 : *---------------------------------------------------------------------*/
362 :
363 114491 : static void bass_pf_1sf_delay(
364 : Word16 *syn, /* (i) : 12.8kHz synthesis to postfilter Q0 */
365 : Word16 *T_sf, /* (i) : Pitch period for all subframes (T_sf[16]) Q0 */
366 : Word16 *gainT_sf, /* (i) : Pitch gain for all subframes (gainT_sf[16]) Q14 */
367 : Word16 l_frame, /* (i) : frame length (should be multiple of l_subfr) Q0 */
368 : Word16 l_subfr, /* (i) : sub-frame length (60/64) Q0 */
369 : Word16 *bpf_noise_buf, /* (i) : harmoninc filtered signal Q0 */
370 : Word16 *gain_factor_param, /* (i) : gain factor param 0-> no BPF, 3-> full BPF */
371 : Word8 disable_bpf,
372 : Word32 *lp_error_ener,
373 : Word32 *mem_error )
374 : {
375 : Word16 i, sf, i_subfr, T, lg, s1, st, tmp16;
376 : Word16 gain;
377 : Word32 tmp, nrg, lp_error, tmp32;
378 : Word32 ener2;
379 :
380 114491 : assert( bpf_noise_buf != NULL );
381 :
382 114491 : sf = 0;
383 114491 : move16();
384 114491 : lp_error = L_shl( *mem_error, 0 );
385 :
386 640529 : FOR( i_subfr = 0; i_subfr < l_frame; i_subfr += l_subfr )
387 : {
388 526038 : T = T_sf[sf];
389 526038 : move16();
390 :
391 526038 : lg = sub( sub( l_frame, T ), i_subfr );
392 526038 : if ( lg < 0 )
393 : {
394 562 : lg = 0;
395 562 : move16();
396 : }
397 526038 : if ( GT_16( lg, l_subfr ) )
398 : {
399 297073 : lg = l_subfr;
400 297073 : move16();
401 : }
402 :
403 526038 : test();
404 526038 : IF( disable_bpf == 0 && gainT_sf[sf] > 0 )
405 : {
406 : /* get headroom for used part of syn */
407 3046 : tmp16 = add( l_subfr, T );
408 3046 : if ( lg > 0 )
409 : {
410 2449 : tmp16 = add( lg, shl( T, 1 ) );
411 : }
412 3046 : s1 = getScaleFactor16( syn + sub( i_subfr, T ), tmp16 );
413 3046 : s1 = sub( s1, 3 );
414 :
415 3046 : tmp = L_deposit_l( 1 );
416 3046 : nrg = L_deposit_l( 1 );
417 :
418 3046 : IF( lg > 0 )
419 : {
420 :
421 : {
422 2449 : Word64 tmp64 = W_deposit32_l( tmp );
423 2449 : Word64 nrg64 = W_deposit32_l( nrg );
424 141751 : FOR( i = 0; i < lg; i++ )
425 : {
426 139302 : tmp32 = L_mult( syn[( i + i_subfr ) - T], 0x4000 );
427 139302 : tmp32 = L_mac( tmp32, syn[( i + i_subfr ) + T], 0x4000 );
428 139302 : tmp16 = round_fx( L_shl( tmp32, s1 ) ); /* Q0+s1 */
429 :
430 139302 : tmp64 = W_mac0_16_16( tmp64, shl( syn[i + i_subfr], s1 ), tmp16 ); /* Q0+2*s1 */
431 139302 : nrg64 = W_mac0_16_16( nrg64, tmp16, tmp16 ); /* Q0+2*s1 */
432 : }
433 2449 : tmp = W_sat_l( tmp64 );
434 2449 : nrg = W_sat_l( nrg64 );
435 : }
436 : }
437 :
438 3046 : IF( LT_16( lg, l_subfr ) )
439 : {
440 :
441 : {
442 1167 : Word64 tmp64 = W_deposit32_l( tmp );
443 1167 : Word64 nrg64 = W_deposit32_l( nrg );
444 56809 : FOR( i = lg; i < l_subfr; i++ )
445 : {
446 55642 : tmp16 = shl( syn[( i + i_subfr ) - T], s1 ); /* Q0+s1 */
447 55642 : tmp64 = W_mac0_16_16( tmp64, shl( syn[i + i_subfr], s1 ), tmp16 ); /* Q0+2*s1 */
448 55642 : nrg64 = W_mac0_16_16( nrg64, tmp16, tmp16 ); /* Q0+2*s1 */
449 : }
450 1167 : tmp = W_sat_l( tmp64 );
451 1167 : nrg = W_sat_l( nrg64 );
452 : }
453 : }
454 :
455 : /* gain = tmp/nrg; */
456 3046 : gain = BASOP_Util_Divide3232_Scale( tmp, nrg, &tmp16 );
457 : BASOP_SATURATE_WARNING_OFF_EVS;
458 3046 : gain = shl_sat( gain, tmp16 ); /* Q15 */
459 : BASOP_SATURATE_WARNING_ON_EVS;
460 :
461 3046 : if ( gain < 0 )
462 : {
463 80 : gain = 0;
464 80 : move16();
465 : }
466 :
467 3046 : st = sub( norm_l( lp_error ), 3 );
468 3046 : test();
469 3046 : if ( ( LT_16( st, s1 ) ) && ( lp_error != 0 ) )
470 : {
471 0 : s1 = st;
472 0 : move16();
473 : }
474 :
475 3046 : ener2 = L_deposit_l( 0 );
476 :
477 3046 : IF( lg > 0 )
478 : {
479 :
480 : {
481 2449 : Word64 ener2_64 = W_deposit32_l( ener2 );
482 141751 : FOR( i = 0; i < lg; i++ )
483 : {
484 139302 : tmp32 = L_msu0( 0, gain, syn[( i + i_subfr ) - T] );
485 139302 : tmp32 = L_msu0( tmp32, gain, syn[( i + i_subfr ) + T] );
486 139302 : tmp16 = mac_r_sat( tmp32, gain, syn[i + i_subfr] ); /* Q0 */
487 139302 : lp_error = Mpy_32_16_1( lp_error, 29491 /*0.9f Q15*/ );
488 139302 : lp_error = L_mac_sat( lp_error, tmp16, 0x1000 ); /* Q13 */
489 139302 : tmp16 = round_fx_sat( L_shl_sat( lp_error, s1 ) ); /* Q0+s1-3 */
490 139302 : ener2_64 = W_mac0_16_16( ener2_64, tmp16, tmp16 ); /* Q0+(s1-3)*2 */
491 : }
492 2449 : ener2 = W_sat_l( ener2_64 );
493 : }
494 : }
495 :
496 3046 : IF( LT_16( lg, l_subfr ) )
497 : {
498 :
499 : {
500 1167 : Word64 ener2_64 = W_deposit32_l( ener2 );
501 56809 : FOR( i = lg; i < l_subfr; i++ )
502 : {
503 55642 : tmp32 = L_mult0( gain, syn[i + i_subfr] );
504 55642 : tmp32 = L_msu0_sat( tmp32, gain, syn[( i + i_subfr ) - T] ); /* Q0 */
505 55642 : tmp16 = round_fx_sat( tmp32 );
506 :
507 55642 : lp_error = Mpy_32_16_1( lp_error, 29491 /*0.9f Q15*/ );
508 55642 : lp_error = L_mac_sat( lp_error, tmp16, 0x1000 ); /* Q13 */
509 :
510 55642 : tmp16 = round_fx_sat( L_shl_sat( lp_error, s1 ) ); /* Q0+s1-3 */
511 55642 : ener2_64 = W_mac0_16_16( ener2_64, tmp16, tmp16 ); /* Q0+(s1-3)*2 */
512 : }
513 1167 : ener2 = W_sat_l( ener2_64 );
514 : }
515 : }
516 :
517 3046 : st = shl( sub( s1, 3 ), 1 );
518 :
519 3046 : IF( ener2 > 0 )
520 : {
521 3027 : ener2 = L_shr( BASOP_Util_Log2( ener2 ), 9 ); /* 15Q16 */
522 3027 : ener2 = L_add( ener2, L_deposit_h( sub( 31, st ) ) );
523 : }
524 : ELSE
525 : {
526 19 : ener2 = L_add( (Word32) 0xFFF95B2C, 0 ); /* log2(0.01) (15Q16) */
527 : }
528 :
529 3046 : *lp_error_ener = L_add( Mpy_32_16_1( L_sub( *lp_error_ener, ener2 ), 32440 /*0.99f Q15*/ ), ener2 ); /* 15Q16 */
530 3046 : move32();
531 :
532 3046 : st = add( st, 6 );
533 3046 : ener2 = L_sub( *lp_error_ener, L_deposit_h( sub( 31, st ) ) );
534 3046 : IF( ener2 >= 0 )
535 : {
536 187 : tmp16 = add( extract_h( ener2 ), 1 );
537 187 : ener2 = L_sub( ener2, L_deposit_h( tmp16 ) );
538 187 : tmp = L_shr( tmp, tmp16 );
539 187 : nrg = L_shr( nrg, tmp16 );
540 : }
541 3046 : ener2 = BASOP_Util_InvLog2( L_shl( ener2, 9 ) ); /* Q0+2*s1 */
542 :
543 3046 : tmp32 = L_add( L_shr( nrg, 1 ), L_shr( ener2, 1 ) );
544 3046 : if ( tmp32 == 0 )
545 0 : tmp32 = L_deposit_l( 1 );
546 3046 : tmp16 = BASOP_Util_Divide3232_Scale( tmp, tmp32, &st );
547 : BASOP_SATURATE_WARNING_OFF_EVS;
548 3046 : tmp16 = shl_sat( tmp16, sub( st, 2 ) ); /* Q15 */
549 :
550 3046 : if ( GT_16( tmp16, 16384 /*0.5f Q15*/ ) )
551 : {
552 155 : tmp16 = 16384 /*0.5f Q15*/;
553 155 : move16();
554 : }
555 3046 : if ( tmp16 < 0 )
556 : {
557 80 : tmp16 = 0;
558 80 : move16();
559 : }
560 : BASOP_SATURATE_WARNING_ON_EVS;
561 :
562 : /*Adjust gain*/
563 : /* full gain = gainLTP*0.5*/
564 : /* adaptive gain = gainLTP*0.5*max(0.5f*gain_factor_param[sf],0.125f)*/
565 3046 : tmp16 = round_fx( L_shl( L_mult0( tmp16, s_max( shl( gain_factor_param[sf], 2 ), 1 ) ), 13 ) );
566 :
567 :
568 : /* calculate noise based on voiced pitch */
569 3046 : IF( lg > 0 )
570 : {
571 141751 : FOR( i = 0; i < lg; i++ )
572 : {
573 139302 : tmp32 = L_msu0( 0, tmp16, syn[( i + i_subfr ) - T] );
574 139302 : tmp32 = L_msu0_sat( tmp32, tmp16, syn[( i + i_subfr ) + T] );
575 139302 : tmp32 = L_mac_sat( tmp32, tmp16, syn[i + i_subfr] );
576 139302 : bpf_noise_buf[i + i_subfr] = round_fx_sat( tmp32 ); /* Q0 */
577 139302 : move16();
578 : }
579 : }
580 :
581 3046 : IF( LT_16( lg, l_subfr ) )
582 : {
583 56809 : FOR( i = lg; i < l_subfr; i++ )
584 : {
585 55642 : tmp32 = L_mult0( tmp16, syn[i + i_subfr] );
586 55642 : tmp32 = L_msu0_sat( tmp32, tmp16, syn[i + i_subfr - T] );
587 55642 : bpf_noise_buf[i + i_subfr] = round_fx_sat( tmp32 ); /* Q0 */
588 55642 : move16();
589 : }
590 : }
591 : }
592 : ELSE
593 : {
594 522992 : set16_fx( bpf_noise_buf + i_subfr, 0, l_subfr );
595 : }
596 :
597 526038 : sf = add( sf, 1 );
598 : }
599 :
600 114491 : *mem_error = lp_error;
601 114491 : move32();
602 :
603 :
604 114491 : return;
605 : }
606 :
607 : /*---------------------------------------------------------------------*
608 : * cldfb_synth_set_bandsToZero()
609 : *
610 : *
611 : *---------------------------------------------------------------------*/
612 :
613 0 : void cldfb_synth_set_bandsToZero(
614 : Decoder_State *st,
615 : Word32 **rAnalysis,
616 : Word32 **iAnalysis,
617 : const Word16 nTimeSlots,
618 : const CLDFB_SCALE_FACTOR scaleFactor )
619 : {
620 : Word32 nrgQ31;
621 : Word32 nrg_band[CLDFB_NO_CHANNELS_MAX], tempQ31, max_nrg;
622 : Word16 realQ1, imagQ1, flag, offset, WBcnt;
623 : Word16 perc_detect, perc_miss;
624 : Word16 i, k, tmp1, tmp2, tmp3, tmp, update_perc;
625 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
626 0 : Flag Overflow = 0;
627 0 : move32();
628 : #endif
629 :
630 :
631 0 : realQ1 = 0;
632 0 : move16();
633 0 : imagQ1 = 0;
634 0 : move16();
635 :
636 0 : set32_fx( nrg_band, 0, CLDFB_NO_CHANNELS_MAX );
637 0 : max_nrg = 0;
638 0 : move32();
639 :
640 0 : offset = 250;
641 0 : move16();
642 0 : WBcnt = 20;
643 0 : move16();
644 0 : perc_miss = 13107; /*0.80 in Q14*/
645 0 : move16();
646 0 : perc_detect = 14746; /*0.90 in Q14*/
647 0 : move16();
648 :
649 0 : IF( EQ_16( st->VAD, 1 ) )
650 : {
651 0 : st->active_frame_cnt_bwddec = add( st->active_frame_cnt_bwddec, 1 );
652 0 : move16();
653 0 : st->total_frame_cnt_bwddec = add( st->total_frame_cnt_bwddec, 1 );
654 0 : move16();
655 0 : if ( GT_16( st->active_frame_cnt_bwddec, 99 ) )
656 : {
657 0 : st->active_frame_cnt_bwddec = 100;
658 0 : move16();
659 : }
660 0 : if ( GT_16( st->total_frame_cnt_bwddec, 500 ) )
661 : {
662 0 : st->total_frame_cnt_bwddec = 500;
663 0 : move16();
664 : }
665 :
666 0 : FOR( i = 0; i < ( st->cldfbSyn->no_channels - st->cldfbSyn->bandsToZero ); i++ )
667 : {
668 0 : nrgQ31 = 0;
669 0 : move32();
670 0 : FOR( k = 0; k < nTimeSlots; k++ )
671 : {
672 : /* use 16-bit precision of real and imag buffers */
673 0 : realQ1 = extract_l( L_shr( rAnalysis[k][i], sub( 31 + 3 - 15, scaleFactor.lb_scale ) ) ); /*31 - (15 + scaleFactor.lb_scale) + 3 )*/
674 0 : imagQ1 = extract_l( L_shr( iAnalysis[k][i], sub( 31 + 3 - 15, scaleFactor.lb_scale ) ) ); /* Q(-3), headroom */
675 0 : nrgQ31 = L_mac0_o( nrgQ31, realQ1, realQ1, &Overflow );
676 0 : nrgQ31 = L_mac0_o( nrgQ31, imagQ1, imagQ1, &Overflow ); /* keep in Q(-6) */
677 : }
678 0 : nrg_band[i] = ( nrgQ31 );
679 0 : move16();
680 0 : test();
681 0 : if ( GT_32( nrg_band[i], max_nrg ) && GE_16( i, 11 ) )
682 : {
683 0 : max_nrg = nrg_band[i];
684 0 : move16();
685 : }
686 : }
687 0 : FOR( ; i < st->cldfbSyn->no_channels; i++ )
688 : {
689 0 : nrg_band[i] = 0;
690 0 : move16();
691 : }
692 :
693 0 : nrgQ31 = 0;
694 0 : move16();
695 0 : FOR( i = 2; i < 9; i++ )
696 : {
697 0 : nrgQ31 = L_add( nrgQ31, Mult_32_16( nrg_band[i], 4681 ) );
698 : }
699 :
700 0 : tempQ31 = L_shr( nrgQ31, 9 );
701 :
702 0 : st->avg_nrg_LT = L_add( Mult_32_16( st->avg_nrg_LT, 32440 ), Mult_32_16( tempQ31, 327 ) ); /*0.99*avg_nrg_LT + 0.01*tempQ31*/
703 0 : move32();
704 0 : update_perc = 1;
705 0 : move16();
706 0 : test();
707 0 : if ( GE_16( st->ini_frame, 25 ) && LT_32( tempQ31, Mult_32_16( st->avg_nrg_LT, 164 ) ) )
708 : {
709 0 : update_perc = 0;
710 0 : move16();
711 : }
712 :
713 0 : flag = 1;
714 0 : move16();
715 0 : if ( GE_32( max_nrg, tempQ31 ) )
716 : {
717 0 : flag = 0;
718 0 : move16();
719 : }
720 :
721 0 : FOR( i = 0; i < ( WBcnt - 1 ); i++ )
722 : {
723 0 : st->flag_buffer[i] = st->flag_buffer[i + 1];
724 0 : move16();
725 : }
726 0 : st->flag_buffer[WBcnt - 1] = flag;
727 0 : move16();
728 :
729 : /*long term percentage*/
730 0 : IF( EQ_16( update_perc, 1 ) )
731 : {
732 0 : IF( flag != 0 )
733 : {
734 0 : tmp1 = sub( 16384, st->perc_bwddec ); /*Q14*/
735 0 : move16();
736 :
737 0 : tmp = norm_s( st->active_frame_cnt_bwddec );
738 0 : tmp3 = shl( st->active_frame_cnt_bwddec, tmp ); /*Qtmp*/
739 :
740 0 : tmp2 = div_s( 16384, tmp3 ); /* 1/active_frames in Q15 + Q14 - Qtmp = Q29 - Qtmp */
741 0 : tmp2 = mult_r( tmp2, tmp1 ); /*(1-perc)*(1/active_frames) in Q14 + Q29 - Qtmp - Q15 = Q28 - Qtmp*/
742 0 : st->perc_bwddec = add( st->perc_bwddec, shl( tmp2, sub( tmp, 14 ) ) ); /* Q14 */
743 0 : move16();
744 : }
745 : ELSE
746 : {
747 0 : tmp1 = ( st->perc_bwddec ); /*Q14*/
748 0 : move16();
749 :
750 0 : tmp = norm_s( st->active_frame_cnt_bwddec );
751 0 : tmp3 = shl( st->active_frame_cnt_bwddec, tmp ); /*Qtmp*/
752 :
753 0 : tmp2 = div_s( 16384, tmp3 ); /* 1/active_frames in Q15 + Q14 - Qtmp = Q29 - Qtmp */
754 0 : tmp2 = mult_r( tmp2, tmp1 ); /*(perc)*(1/active_frames) in Q14 + Q29 - Qtmp - Q15 = Q28 - Qtmp*/
755 0 : st->perc_bwddec = sub( st->perc_bwddec, shl( tmp2, sub( tmp, 14 ) ) ); /* Q14 */
756 0 : move16();
757 : }
758 : }
759 0 : test();
760 0 : IF( GT_16( st->total_frame_cnt_bwddec, offset ) && GT_16( st->active_frame_cnt_bwddec, 50 ) )
761 : {
762 0 : test();
763 0 : test();
764 0 : test();
765 0 : IF( ( GE_16( st->perc_bwddec, perc_detect ) || ( GE_16( st->perc_bwddec, perc_miss ) && st->last_flag_filter_NB ) ) && ( sum16_fx( st->flag_buffer, WBcnt ) != 0 ) ) /*decision hysterysis*/
766 : {
767 0 : st->cldfbSyn->bandsToZero = sub( st->cldfbSyn->no_channels, 10 );
768 0 : move16();
769 0 : st->last_flag_filter_NB = 1;
770 0 : move16(); /*VAD processing must be dependent on hysterysis, as if hysterysis fails, but threshold passes, we dont want next vad frames to have NB only*/
771 : }
772 : ELSE
773 : {
774 0 : st->last_flag_filter_NB = 0;
775 0 : move16();
776 : }
777 : }
778 : ELSE
779 : {
780 0 : st->last_flag_filter_NB = 0;
781 0 : move16();
782 : }
783 0 : IF( sum16_fx( st->flag_buffer, WBcnt ) == 0 )
784 : {
785 0 : st->perc_bwddec = 0;
786 0 : move16();
787 0 : st->active_frame_cnt_bwddec = 0;
788 0 : move16();
789 0 : st->total_frame_cnt_bwddec = 0;
790 0 : move16();
791 0 : st->last_flag_filter_NB = 0;
792 0 : move16();
793 : }
794 : }
795 : ELSE
796 : {
797 0 : if ( EQ_16( st->last_flag_filter_NB, 1 ) )
798 : {
799 0 : st->cldfbSyn->bandsToZero = st->last_active_bandsToZero_bwdec;
800 0 : move16();
801 : }
802 0 : st->total_frame_cnt_bwddec = add( st->total_frame_cnt_bwddec, 1 );
803 0 : move16();
804 0 : if ( GT_16( st->total_frame_cnt_bwddec, 500 ) )
805 : {
806 0 : st->total_frame_cnt_bwddec = 500;
807 0 : move16();
808 : }
809 : }
810 :
811 0 : st->last_active_bandsToZero_bwdec = st->cldfbSyn->bandsToZero;
812 0 : move16();
813 :
814 0 : return;
815 : }
|