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