Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 : /*BASOp version info: This file is up to date with trunk rev. 39929 */
6 :
7 : #include <stdint.h>
8 : #include <stdio.h>
9 : #include <assert.h>
10 : #include "options.h"
11 : #include "prot_fx.h"
12 : #include "basop_util.h"
13 : #include "stl.h"
14 : #include "rom_com.h"
15 : /*-------------------------------------------------------------------*
16 : * decoder_acelp_fx()
17 : *
18 : * Decode ACELP frame MODE2
19 : *-------------------------------------------------------------------*/
20 612 : void decoder_acelp_fx(
21 : Decoder_State *st,
22 : Word16 prm[], /* i : parameters */
23 : Word16 A[], /* i : coefficients NxAz[M+1] */
24 : ACELP_config acelp_cfg, /* i : ACELP config Q12 */
25 : Word16 synth[], /* i/o: synth[-2*LFAC..L_DIV] Q0 */
26 : Word16 *pT, /* o : pitch for all subframe Q0 */
27 : Word16 *pgainT, /* o : pitch gain for all subfr 1Q14 */
28 : Word16 stab_fac, /* i : stability of isf */
29 : Word16 *pitch_buffer, /* o : pitch values for each subfr. Q6 */
30 : Word16 *voice_factors, /* o : voicing factors Q15 */
31 : const Word16 LSF_Q_prediction, /* i : LSF prediction mode */
32 : Word16 *bwe_exc /* o : excitation for SWB TBE Q_exc */
33 : )
34 : {
35 : Word16 i, j, i_subfr;
36 : Word16 T0, T0_frac, T0_min, T0_min_frac, T0_max, T0_max_frac, T0_res;
37 : Word16 tmp, tmp2, gain_pit /*Q14*/, Es_pred, tmp_deemph;
38 : Word32 Ltmp, Ltmp2, gain_code;
39 : Word16 code[L_SUBFR];
40 : Word16 mem_syn[M];
41 : Word16 *syn, syn_buf[M + L_FRAME16k + L_FRAME16k / 2];
42 : Word16 *exc, exc_buf[L_EXC_MEM_DEC + L_FRAME16k + 1];
43 : Word16 exc2[L_FRAME_16k];
44 : Word16 *p_A;
45 : Word32 pitch_buf[NB_SUBFR16k];
46 : Word16 dummy_pitch_buf[NB_SUBFR16k];
47 : Word16 gain_inov;
48 : Word16 mem_back[M]; // Q_mem_back
49 : Word16 update_flg;
50 : Word16 Q_mem_back; /*Q format of mem_back*/
51 : Word16 h1[L_FRAME_16k / 4 + 1];
52 : Word16 mem[M];
53 : Word16 *pA;
54 : PulseConfig config;
55 : Word16 weights[5]; /* Q15 */
56 :
57 : Word16 reScaleLen_fx; /* rescaling length for the BWE buffers */
58 : Word16 reSampLen;
59 :
60 : /*Q formats of buffers */
61 : Word16 prev_Q_syn;
62 612 : Word32 gain_code2 = 0;
63 612 : move32();
64 : Word16 code2[L_SUBFR];
65 612 : Word16 error = 0;
66 612 : move16();
67 612 : Word16 gain_preQ = 0; /* Gain of prequantizer excitation */
68 612 : move16();
69 : Word16 code_preQ[L_SUBFR]; /* Prequantizer excitation */
70 : Word16 lp_flag;
71 :
72 :
73 : Word16 prev_gain_pit;
74 : Word16 tmp_noise; /* Long term temporary noise energy */
75 : Word32 gain_code_tmp;
76 : Word16 gain_pit_tmp;
77 : Word32 gain_code_pre;
78 : Word16 avoid_lpc_burst_on_recovery;
79 : Word16 force_scale_syn;
80 : TD_BWE_DEC_HANDLE hBWE_TD;
81 : TCX_DEC_HANDLE hTcxDec;
82 :
83 612 : hBWE_TD = st->hBWE_TD;
84 612 : hTcxDec = st->hTcxDec;
85 :
86 612 : gain_code_pre = 0;
87 612 : move16();
88 :
89 :
90 612 : set16_fx( code_preQ, 0, L_SUBFR );
91 :
92 612 : gain_inov = 0; /* to avoid compilation warnings */
93 612 : T0 = 0; /* to avoid compilation warnings */
94 612 : T0_frac = 0; /* to avoid compilation warnings */
95 612 : T0_res = 0; /* to avoid compilation warnings */
96 612 : prev_Q_syn = st->prev_Q_syn = st->Q_syn;
97 612 : move16();
98 612 : move16();
99 612 : move16();
100 612 : move16();
101 612 : move16();
102 612 : move16();
103 612 : gain_pit = 0;
104 612 : gain_code = 0;
105 612 : move16();
106 612 : move16();
107 612 : move16();
108 612 : update_flg = 0;
109 612 : move16();
110 612 : gain_code2 = 0;
111 :
112 612 : prev_gain_pit = 0;
113 612 : move16();
114 612 : tmp_noise = 0;
115 612 : move16();
116 :
117 612 : IF( EQ_16( st->nb_subfr, 4 ) )
118 : {
119 0 : move16();
120 0 : move16();
121 0 : move16();
122 0 : move16();
123 0 : weights[0] = 3277 /*0.1f Q15*/;
124 0 : weights[1] = 6554 /*0.2f Q15*/;
125 0 : weights[2] = 9830 /*0.3f Q15*/;
126 0 : weights[3] = 13107 /*0.4f Q15*/;
127 : }
128 : ELSE /*nb_subfr == 5*/
129 : {
130 612 : move16();
131 612 : move16();
132 612 : move16();
133 612 : move16();
134 612 : move16();
135 612 : weights[0] = 2185 /*(float)1/15 Q15*/;
136 612 : weights[1] = 4369 /*(float)2/15 Q15*/;
137 612 : weights[2] = 6554 /*(float)3/15 Q15*/;
138 612 : weights[3] = 8738 /*(float)4/15 Q15*/;
139 612 : weights[4] = 10923 /*float)5/15 Q15*/;
140 : }
141 612 : st->Mode2_lp_gainp = 0;
142 612 : move32();
143 612 : st->Mode2_lp_gainc = 0;
144 612 : move32();
145 :
146 612 : avoid_lpc_burst_on_recovery = 0;
147 612 : move16();
148 612 : test();
149 612 : test();
150 612 : if ( st->last_con_tcx && ( NE_16( st->L_frameTCX_past, st->L_frame ) ) && ( st->last_core != 0 ) )
151 : {
152 0 : avoid_lpc_burst_on_recovery = 1;
153 0 : move16();
154 : }
155 :
156 :
157 : /*------------------------------------------------------------------------*
158 : * Previous frame is TCX *
159 : *------------------------------------------------------------------------*/
160 :
161 :
162 : /* Reset phase dispersion */
163 612 : IF( st->last_core_bfi > ACELP_CORE )
164 : {
165 29 : st->dm_fx.prev_gain_code = 0;
166 29 : move32();
167 29 : set16_fx( st->dm_fx.prev_gain_pit, 0, 6 );
168 29 : st->dm_fx.prev_state = 0;
169 29 : move16();
170 : }
171 :
172 : /* Update of synthesis filter memories in case of 12k8 core */
173 612 : test();
174 612 : test();
175 612 : IF( st->prev_bfi && st->last_con_tcx && LT_16( st->L_frame, L_FRAME16k ) )
176 : {
177 0 : synth_mem_updt2( st->L_frame, L_FRAME16k, st->old_exc_fx, st->mem_syn_r, st->mem_syn2_fx, NULL, DEC );
178 : }
179 :
180 612 : test();
181 612 : IF( st->last_con_tcx && st->old_enr_LP )
182 : {
183 : Word16 enr_LP, ratio;
184 :
185 : /* rescale excitation buffer if LPC energies differs too much */
186 0 : enr_LP = Enr_1_Az_fx( A, L_SUBFR );
187 :
188 0 : IF( LT_16( st->old_enr_LP, enr_LP ) )
189 : {
190 0 : ratio = div_s( st->old_enr_LP, enr_LP ); /* Q15 */
191 0 : IF( LT_16( ratio, 26215 /*.8f in Q15*/ ) )
192 : {
193 0 : FOR( i = 0; i < L_EXC_MEM_DEC; i++ )
194 : {
195 0 : st->old_exc_fx[i] = mult_r( st->old_exc_fx[i], ratio ); // Q_exc
196 0 : move16();
197 : }
198 : }
199 : }
200 : }
201 :
202 : /*------------------------------------------------------------------------*
203 : * Initialize buffers *
204 : *------------------------------------------------------------------------*/
205 612 : Copy( st->mem_syn2_fx, mem_back, M );
206 612 : move16();
207 612 : Q_mem_back = st->Q_syn;
208 : /* set ACELP synthesis memory */
209 612 : Copy( st->mem_syn2_fx, mem_syn, M );
210 :
211 : /* set excitation memory*/
212 612 : exc = exc_buf + L_EXC_MEM_DEC;
213 612 : Copy( st->old_exc_fx, exc_buf, L_EXC_MEM_DEC );
214 612 : *( exc + st->L_frame ) = 0;
215 612 : move16();
216 : /* Init syn buffer */
217 612 : syn = syn_buf + M;
218 612 : Copy( st->mem_syn2_fx, syn_buf, M );
219 :
220 : /*------------------------------------------------------------------------*
221 : * Fast recovery flag
222 : *------------------------------------------------------------------------*/
223 612 : test();
224 612 : if ( st->prev_bfi && EQ_16( st->coder_type, VOICED ) )
225 : {
226 : /*Force BPF to be applied fully*/
227 0 : st->bpf_gain_param = 3;
228 0 : move16();
229 : }
230 :
231 : /*------------------------------------------------------------------------*
232 : * - decode mean_ener_code for gain decoder (d_gain2.c) *
233 : *------------------------------------------------------------------------*/
234 612 : Es_pred = 0;
235 612 : move16();
236 612 : IF( acelp_cfg.nrg_mode > 0 )
237 : {
238 612 : d_gain_pred_fx( acelp_cfg.nrg_mode, &Es_pred, &prm );
239 : }
240 :
241 : /*------------------------------------------------------------------------*
242 : * Loop for every subframe in the analysis frame *
243 : *------------------------------------------------------------------------*
244 : * To find the pitch and innovation parameters. The subframe size is *
245 : * L_subfr and the loop is repeated L_ACELP/L_subfr times. *
246 : * - compute impulse response of weighted synthesis filter (h1[]) *
247 : * - compute the target signal for pitch search *
248 : * - find the closed-loop pitch parameters *
249 : * - encode the pitch delay *
250 : * - update the impulse response h1[] by including fixed-gain pitch *
251 : * - find target vector for codebook search *
252 : * - correlation between target vector and impulse response *
253 : * - codebook search *
254 : * - encode codebook address *
255 : * - VQ of pitch and codebook gains *
256 : * - find synthesis speech *
257 : * - update states of weighting filter *
258 : *------------------------------------------------------------------------*/
259 :
260 612 : p_A = A;
261 :
262 3672 : FOR( i_subfr = 0; i_subfr < st->L_frame; i_subfr += L_SUBFR )
263 : {
264 :
265 3060 : Word16 idx = 0;
266 3060 : IF( i_subfr != 0 )
267 : {
268 2448 : idx = idiv1616( i_subfr, L_SUBFR );
269 : }
270 :
271 3060 : test();
272 3060 : IF( EQ_16( st->use_partial_copy, 1 ) && EQ_16( st->rf_frame_type, RF_NELP ) )
273 : {
274 0 : IF( i_subfr == 0 )
275 : {
276 0 : decod_nelp_fx( st, &tmp_noise, dummy_pitch_buf, exc, exc2, voice_factors, bwe_exc, &st->Q_exc, st->bfi, pgainT );
277 0 : set32_fx( pitch_buf, L_SUBFR_Q16, NB_SUBFR );
278 0 : set16_fx( pitch_buffer, 4096, NB_SUBFR ); /* L_SUBFR_Q16 in Q6 */
279 : }
280 : }
281 : ELSE
282 : {
283 :
284 : /*-------------------------------------------------------*
285 : * - Decode adaptive codebook. *
286 : *-------------------------------------------------------*/
287 :
288 3060 : test();
289 3060 : if ( EQ_16( st->use_partial_copy, 1 ) && st->acelp_cfg.gains_mode[idx] == 0 )
290 : {
291 0 : gain_pit = prev_gain_pit;
292 0 : move16();
293 : }
294 :
295 3060 : IF( acelp_cfg.ltp_bits != 0 )
296 : {
297 : /* pitch lag decoding */
298 6120 : pitch_buf[idx] = Mode2_pit_decode( acelp_cfg.ltp_mode, i_subfr, L_SUBFR, &prm, &T0, &T0_frac, &T0_res,
299 3060 : &T0_min, &T0_min_frac, &T0_max, &T0_max_frac, st->pit_min, st->pit_fr1, st->pit_fr1b, st->pit_fr2, st->pit_max, st->pit_res_max );
300 3060 : move32();
301 : /* find pitch excitation */
302 3060 : test();
303 3060 : IF( EQ_16( st->pit_res_max, 6 ) && !( st->use_partial_copy ) )
304 : {
305 3060 : IF( EQ_16( T0_res, shr( st->pit_res_max, 1 ) ) )
306 : {
307 2948 : pred_lt4( &exc[i_subfr], &exc[i_subfr], T0, shl( T0_frac, 1 ), L_SUBFR + 1, pitch_inter6_2, PIT_L_INTERPOL6_2, PIT_UP_SAMP6 );
308 : }
309 : ELSE
310 : {
311 112 : pred_lt4( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, L_SUBFR + 1, pitch_inter6_2, PIT_L_INTERPOL6_2, PIT_UP_SAMP6 );
312 : }
313 : }
314 : ELSE
315 : {
316 0 : IF( EQ_16( T0_res, shr( st->pit_res_max, 1 ) ) )
317 : {
318 0 : pred_lt4( &exc[i_subfr], &exc[i_subfr], T0, shl( T0_frac, 1 ), L_SUBFR + 1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP );
319 : }
320 : ELSE
321 : {
322 0 : pred_lt4( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, L_SUBFR + 1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP );
323 : }
324 : }
325 :
326 : /* LP filtering of the adaptive excitation*/
327 3060 : lp_flag = acelp_cfg.ltf_mode;
328 3060 : move16();
329 :
330 3060 : IF( EQ_16( acelp_cfg.ltf_mode, NORMAL_OPERATION ) )
331 : {
332 1350 : lp_flag = *prm;
333 1350 : move16();
334 1350 : prm++;
335 : }
336 :
337 3060 : lp_filt_exc_dec_fx( st, MODE2, i_subfr, L_SUBFR, st->L_frame, lp_flag, exc );
338 : }
339 : ELSE
340 : {
341 : /* No adaptive codebook (UC) */
342 0 : set16_fx( &exc[i_subfr], 0, L_SUBFR );
343 :
344 0 : T0 = L_SUBFR;
345 0 : move16();
346 0 : T0_frac = 0;
347 0 : move16();
348 0 : T0_res = 1;
349 0 : move16();
350 0 : pitch_buf[idx] = L_deposit_h( L_SUBFR ); // Q16
351 0 : move32();
352 : }
353 :
354 3060 : IF( st->igf != 0 )
355 : {
356 3060 : tbe_celp_exc( st->L_frame, i_subfr, T0, T0_frac, &error, bwe_exc );
357 : }
358 :
359 3060 : pitch_buffer[idx] = shl( add( shl( T0, 2 ), T0_frac ), 4 ); // Q6
360 3060 : move16();
361 :
362 : /*-------------------------------------------------------*
363 : * - Decode innovative codebook. *
364 : *-------------------------------------------------------*/
365 3060 : test();
366 3060 : test();
367 3060 : test();
368 3060 : test();
369 3060 : IF( EQ_16( st->use_partial_copy, 1 ) &&
370 : ( EQ_16( st->rf_frame_type, RF_ALLPRED ) ||
371 : ( EQ_16( st->rf_frame_type, RF_GENPRED ) &&
372 : ( EQ_16( i_subfr, L_SUBFR ) || EQ_16( i_subfr, 3 * L_SUBFR ) ) ) ) )
373 : {
374 0 : set16_fx( code, 0, L_SUBFR );
375 : }
376 : ELSE
377 : {
378 3060 : config = PulseConfTable[acelp_cfg.fixed_cdk_index[idx]];
379 3060 : D_ACELP_indexing_fx( code, config, NB_TRACK_FCB_4T, prm, &st->BER_detect );
380 3060 : ( prm ) += 8;
381 : /*-------------------------------------------------------*
382 : * - Add the fixed-gain pitch contribution to code[]. *
383 : *-------------------------------------------------------*/
384 :
385 3060 : cb_shape_fx( acelp_cfg.pre_emphasis, acelp_cfg.pitch_sharpening, acelp_cfg.phase_scrambling, acelp_cfg.formant_enh, acelp_cfg.formant_tilt,
386 3060 : acelp_cfg.formant_enh_num, acelp_cfg.formant_enh_den, p_A, code, st->tilt_code_fx, extract_h( L_add( pitch_buf[i_subfr / L_SUBFR], 26216 ) ), 1, L_SUBFR );
387 : }
388 : /*-------------------------------------------------------*
389 : * - Generate Gaussian excitation *
390 : *-------------------------------------------------------*/
391 3060 : test();
392 3060 : IF( EQ_16( acelp_cfg.gains_mode[idx], 7 ) && !st->use_partial_copy )
393 : {
394 0 : gaus_L2_dec( code2, st->tilt_code_fx, p_A, acelp_cfg.formant_enh_num, &( st->seed_acelp ) );
395 : }
396 : ELSE
397 : {
398 3060 : gain_code2 = 0;
399 3060 : move32();
400 3060 : set16_fx( code2, 0, L_SUBFR );
401 : }
402 :
403 : /*-------------------------------------------------*
404 : * - Decode codebooks gains. *
405 : *-------------------------------------------------*/
406 3060 : IF( st->acelp_cfg.gains_mode[idx] != 0 )
407 : {
408 3060 : decode_acelp_gains_fx( code, acelp_cfg.gains_mode[idx], Es_pred, &gain_pit, &gain_code, &prm, &( st->past_gpit ),
409 : &( st->past_gcode ), &gain_inov, L_SUBFR, code2, &gain_code2 );
410 : }
411 3060 : test();
412 3060 : if ( st->use_partial_copy && EQ_16( st->rf_frame_type, RF_ALLPRED ) )
413 : {
414 0 : st->past_gcode = 0;
415 0 : move32();
416 : }
417 3060 : test();
418 3060 : if ( st->use_partial_copy && EQ_16( st->rf_frame_type, RF_NOPRED ) )
419 : {
420 0 : st->past_gpit = 67; //.004089f in Q14
421 0 : move32();
422 : }
423 3060 : IF( st->igf != 0 )
424 : {
425 : /* Rescaling for 12.8k and 16k cores related to BWE */
426 3060 : IF( EQ_16( st->L_frame, L_FRAME ) )
427 : {
428 : /* 5/2 times resampled past memories*/
429 0 : reScaleLen_fx = add( shl( i_subfr, 1 ), shr( i_subfr, 1 ) );
430 0 : reSampLen = ( L_SUBFR * HIBND_ACB_L_FAC );
431 0 : move16();
432 : }
433 : ELSE
434 : {
435 : /* 2 times resampled past memories*/
436 3060 : reScaleLen_fx = shl( i_subfr, 1 );
437 3060 : reSampLen = ( L_SUBFR * 2 );
438 3060 : move16();
439 : }
440 :
441 3060 : Rescale_exc( NULL, &exc[i_subfr], &bwe_exc[reScaleLen_fx],
442 3060 : NULL, L_SUBFR, reSampLen, gain_code, &( st->Q_exc ), st->Q_subfr,
443 : exc2, i_subfr, GENERIC );
444 : }
445 : ELSE
446 : {
447 0 : Rescale_exc( NULL, &exc[i_subfr], NULL, NULL, L_SUBFR, 0,
448 0 : gain_code, &( st->Q_exc ), st->Q_subfr, exc2, i_subfr, GENERIC );
449 : }
450 :
451 : /*----------------------------------------------------------*
452 : * Update parameters for the next subframe. *
453 : * - tilt of code: 0.0 (unvoiced) to 0.5 (voiced) *
454 : *----------------------------------------------------------*/
455 3060 : E_UTIL_voice_factor( exc, i_subfr, code, gain_pit, gain_code, &( st->voice_fac ), &( st->tilt_code_fx ), L_SUBFR, acelp_cfg.voice_tilt, st->Q_exc, 0 );
456 :
457 3060 : pgainT[idx] = gain_pit;
458 3060 : move16();
459 :
460 : /*-------------------------------------------------------*
461 : * - Find the total excitation. *
462 : *-------------------------------------------------------*/
463 3060 : gain_code_tmp = gain_code;
464 3060 : move32();
465 3060 : gain_pit_tmp = gain_pit;
466 3060 : move16();
467 3060 : if ( i_subfr == 0 )
468 : {
469 612 : gain_code_pre = 0;
470 612 : move32();
471 : }
472 3060 : test();
473 3060 : test();
474 3060 : test();
475 3060 : IF( ( st->core == ACELP_CORE ) && ( st->last_core == ACELP_CORE ) && ( EQ_16( st->use_partial_copy, 1 ) || EQ_16( st->prev_use_partial_copy, 1 ) ) )
476 : {
477 0 : test();
478 0 : test();
479 0 : test();
480 0 : test();
481 0 : test();
482 0 : test();
483 0 : test();
484 0 : test();
485 0 : IF( i_subfr > 0 && GT_16( gain_pit, 20152 /*1.23 in Q14*/ ) && GT_16( st->prev_tilt_code_dec_fx, 6553 /*1.23 in Q15*/ ) && EQ_16( st->next_coder_type, VOICED ) && ( EQ_16( st->use_partial_copy, 1 ) || EQ_16( st->prev_use_partial_copy, 1 ) ) )
486 : {
487 0 : gain_pit = mult( gain_pit, sub( 26214 /*.8f in Q15*/, mult( i_subfr, 51 /*1.0f/640 in Q15*/ ) ) );
488 : }
489 0 : ELSE IF( !st->prev_use_partial_copy && EQ_16( st->last_coder_type, UNVOICED ) && NE_16( st->next_coder_type, UNVOICED ) && LT_32( gain_code, gain_code_pre ) )
490 :
491 : {
492 0 : gain_code = 0;
493 0 : move32();
494 : }
495 : }
496 3060 : gain_code_pre = gain_code;
497 3060 : move32();
498 3060 : st->tilt_code_dec_fx[idx] = st->tilt_code_fx;
499 3060 : move16();
500 :
501 :
502 3060 : tmp2 = shr( L_SUBFR, 1 );
503 9180 : FOR( j = 0; j < 2; j++ )
504 : {
505 201960 : FOR( i = ( tmp2 - ( L_SUBFR / 2 ) ); i < tmp2; i++ )
506 : {
507 : /* code in Q9, gain_pit in Q14, gain_code in Q16; exc Q_new */
508 195840 : Ltmp = Mpy_32_16_1( gain_code2, code2[i] );
509 195840 : Ltmp = L_shl( Ltmp, add( 5, st->Q_exc ) );
510 195840 : Ltmp = L_mac( Ltmp, gain_pit, exc[i + i_subfr] );
511 195840 : exc2[( i + i_subfr )] = round_fx_sat( L_shl_sat( Ltmp, 1 ) );
512 195840 : move16();
513 195840 : Ltmp2 = Mpy_32_16_1( gain_code, code[i] );
514 195840 : Ltmp2 = L_shl( Ltmp2, add( 5, st->Q_exc ) );
515 195840 : Ltmp = L_add( Ltmp, Ltmp2 );
516 : BASOP_SATURATE_WARNING_OFF_EVS
517 195840 : Ltmp = L_shl_sat( Ltmp, 1 ); /* saturation can occur here */
518 : BASOP_SATURATE_WARNING_ON_EVS
519 195840 : exc[( i + i_subfr )] = round_fx_sat( Ltmp );
520 195840 : move16();
521 : }
522 6120 : tmp2 = L_SUBFR;
523 6120 : move16();
524 : }
525 :
526 : /*-----------------------------------------------------------------*
527 : * Prepare TBE excitation
528 : *-----------------------------------------------------------------*/
529 3060 : gain_code = gain_code_tmp;
530 3060 : move32();
531 3060 : gain_pit = gain_pit_tmp;
532 3060 : move16();
533 3060 : IF( st->igf != 0 )
534 : {
535 : #ifdef FIX_2010_PREP_TBE_EXC
536 3060 : prep_tbe_exc_fx( st->L_frame, L_SUBFR, i_subfr, gain_pit, gain_code, code, st->voice_fac, &voice_factors[idx], bwe_exc,
537 3060 : gain_preQ, code_preQ, Q10, st->Q_exc, T0, T0_frac, st->coder_type, st->core_brate, st->element_mode, st->idchan, st->hBWE_TD != NULL, 0 );
538 : #else
539 : prep_tbe_exc_fx( st->L_frame, L_SUBFR, i_subfr, gain_pit, gain_code, code, st->voice_fac, &voice_factors[idx], bwe_exc,
540 : gain_preQ, code_preQ, st->Q_exc, T0, T0_frac, st->coder_type, st->core_brate, st->element_mode, st->idchan, st->hBWE_TD != NULL, 0 );
541 : #endif
542 : }
543 :
544 : /*---------------------------------------------------------*
545 : * Enhance the excitation *
546 : *---------------------------------------------------------*/
547 :
548 3060 : E_UTIL_enhancer( st->voice_fac, stab_fac, st->past_gcode, gain_inov, &( st->gc_threshold_fx ), code, &exc2[i_subfr],
549 3060 : gain_pit, &st->dm_fx.prev_gain_code, st->dm_fx.prev_gain_pit, &st->dm_fx.prev_state, st->coder_type,
550 3060 : acelp_cfg.fixed_cdk_index[idx], L_SUBFR, st->L_frame, st->Q_exc );
551 :
552 : } /* !RF_NELP frame partial copy */
553 :
554 : /*----------------------------------------------------------*
555 : * - compute the synthesis speech *
556 : *----------------------------------------------------------*/
557 :
558 3060 : rescale_mem( &st->Q_exc, &prev_Q_syn, &st->Q_syn, mem_syn, syn, M, i_subfr );
559 :
560 3060 : E_UTIL_synthesis( sub( st->Q_exc, st->Q_syn ), p_A, &exc2[i_subfr], &syn[i_subfr], L_SUBFR, mem_syn, 1, M );
561 :
562 : /*-----------------------------------------------------------------*
563 : * update lp_filtered gains for the case of frame erasure
564 : *-----------------------------------------------------------------*/
565 :
566 3060 : st->Mode2_lp_gainp = L_add( st->Mode2_lp_gainp, L_mult0( st->past_gpit, weights[idx] ) ); /* 2Q29=1Q14*Q15 */
567 3060 : move32();
568 3060 : st->Mode2_lp_gainc = L_add( st->Mode2_lp_gainc, Mpy_32_16_1( st->past_gcode, weights[idx] ) ); /* 15Q16=15Q16*Q15 */
569 3060 : move32();
570 :
571 : /*----------------------------------------------------------*
572 : * - update pitch lag for guided ACELP *
573 : *----------------------------------------------------------*/
574 3060 : test();
575 3060 : if ( st->enableGplc && EQ_16( shr( i_subfr, 6 ), sub( st->nb_subfr, 1 ) ) )
576 : {
577 612 : st->T0_4th = T0;
578 612 : move16();
579 : }
580 :
581 : /*----------------------------------------------------------*
582 : * - Update LPC coeffs *
583 : *----------------------------------------------------------*/
584 3060 : p_A += ( M + 1 );
585 :
586 : /* copy current gain for next subframe use, in case there is no explicit encoding */
587 3060 : prev_gain_pit = gain_pit;
588 3060 : move16();
589 : } /* end of subframe loop */
590 :
591 612 : IF( st->BER_detect )
592 : {
593 0 : FOR( i = 0; i < st->L_frame; i++ )
594 : {
595 0 : exc[i] = 0;
596 0 : move16();
597 : }
598 :
599 0 : int_lsp_fx( st->L_frame, st->old_lsp_q_cng, st->lsp_q_cng, st->Aq_cng, M, interpol_frac_fx, 0 );
600 :
601 0 : p_A = st->Aq_cng;
602 0 : IF( LT_16( st->last_good, UNVOICED_TRANSITION ) )
603 : {
604 0 : Copy( st->mem_syn2_fx, mem_syn, M );
605 : }
606 : ELSE
607 : {
608 0 : set16_fx( mem_syn, 0, M );
609 : }
610 :
611 0 : FOR( i_subfr = 0; i_subfr < st->L_frame; i_subfr += L_SUBFR )
612 : {
613 0 : E_UTIL_synthesis( sub( st->Q_exc, st->Q_syn ), p_A, &exc[i_subfr], &syn[i_subfr], L_SUBFR, mem_syn, 1, M );
614 0 : p_A += ( M + 1 );
615 : }
616 : }
617 :
618 612 : tmp = 0;
619 612 : move16();
620 612 : pA = A + ( st->nb_subfr - 1 ) * ( M + 1 );
621 612 : set16_fx( h1, 0, add( L_SUBFR, 1 ) );
622 612 : set16_fx( mem, 0, M );
623 612 : h1[0] = 32768 / 32;
624 612 : move16();
625 612 : E_UTIL_synthesis( 0, pA, h1, h1, L_SUBFR, mem, 0, M ); /* impulse response of LPC */
626 612 : deemph_fx( h1, st->preemph_fac, L_SUBFR, &tmp ); /* impulse response of deemph */
627 : /* impulse response level = gain introduced by synthesis+deemphasis */
628 612 : Ltmp = Dot_productSq16HQ( 0, h1, L_SUBFR, &st->last_gain_syn_deemph_e );
629 612 : st->last_gain_syn_deemph_e = add( st->last_gain_syn_deemph_e, 10 /*scaling of h1[0] and E_UTIL_synthesis * 2*/ );
630 612 : move16();
631 612 : st->last_gain_syn_deemph = round_fx_sat( Sqrt32( Ltmp, &st->last_gain_syn_deemph_e ) ); // Q(15-last_gain_syn_deemph_e - (16))
632 612 : move16();
633 :
634 : /* Do the classification */
635 : {
636 : Word16 pit16[NB_SUBFR16k];
637 : Word16 k;
638 3672 : FOR( k = 0; k < st->nb_subfr; k++ )
639 : {
640 3060 : pit16[k] = shl( extract_h( pitch_buf[k] ), 6 ); /*Q6*/
641 3060 : move16();
642 : }
643 :
644 612 : FEC_clas_estim_fx( st, /*Opt_AMR_WB*/ 0, st->L_frame, &( st->clas_dec ), st->core_ext_mode, pit16, syn,
645 : &st->lp_ener_FER_fx, /**decision_hyst*/ NULL, /**UV_cnt*/ NULL, /**LT_UV_cnt*/ NULL, /**Last_ener*/ NULL, /**locattack*/ NULL,
646 612 : /**lt_diff_etot*/ NULL, /**amr_io_class*/ NULL, st->Q_syn, /**class_para*/ NULL, st->mem_syn_clas_estim_fx,
647 : &st->classifier_Q_mem_syn, -32768 /*-1.f Q15*/, 0 /*CLASSIFIER_ACELP*/, 0 /*bfi*/, st->last_core_brate, -1 );
648 : }
649 :
650 : /* Update Pitch Lag memory */
651 :
652 612 : Copy32( &st->old_pitch_buf_fx[st->nb_subfr], st->old_pitch_buf_fx, st->nb_subfr );
653 612 : Copy32( pitch_buf, &st->old_pitch_buf_fx[st->nb_subfr], st->nb_subfr );
654 :
655 :
656 : {
657 : Word16 pBuf_scaleSyn[NB_SUBFR16k];
658 612 : Word16 L_frame_fr = 0;
659 612 : IF( st->L_frame != 0 )
660 : {
661 612 : L_frame_fr = idiv1616( st->L_frame, L_SUBFR );
662 : }
663 :
664 3672 : FOR( i = 0; i < L_frame_fr; i++ )
665 : {
666 3060 : pBuf_scaleSyn[i] = round_fx( pitch_buf[i] );
667 3060 : move16();
668 : }
669 :
670 612 : Scale_sig( mem_back, M, sub( st->Q_syn, Q_mem_back ) ); // Q_syn
671 :
672 612 : force_scale_syn = 0;
673 612 : move16();
674 :
675 612 : test();
676 612 : test();
677 612 : if ( ( EQ_16( st->clas_dec, ONSET ) ) || ( ( GE_16( st->last_good, VOICED_TRANSITION ) ) && ( LT_16( st->last_good, INACTIVE_CLAS ) ) ) )
678 : {
679 506 : force_scale_syn = 1;
680 506 : move16();
681 : }
682 :
683 612 : FEC_scale_syn_fx( st->L_frame, &update_flg, st->clas_dec, st->last_good, syn, pBuf_scaleSyn, st->enr_old_fx, 0,
684 612 : st->coder_type, LSF_Q_prediction, &st->scaling_flag, &st->lp_ener_FEC_av, &st->lp_ener_FEC_max, st->bfi, st->total_brate, st->prev_bfi, st->last_core_brate,
685 612 : exc, exc2, A, &( st->old_enr_LP ), mem_back, mem_syn, st->Q_exc, st->Q_syn, EVS_MONO, avoid_lpc_burst_on_recovery, force_scale_syn );
686 : }
687 :
688 : /* update ACELP synthesis memory */
689 612 : Copy( mem_syn, st->mem_syn2_fx, M );
690 612 : Copy( syn + st->L_frame - L_SYN_MEM, st->mem_syn_r, L_SYN_MEM );
691 :
692 : /* Deemphasis and output synth and ZIR */
693 612 : tmp_deemph = st->syn[M];
694 612 : move16();
695 612 : E_UTIL_deemph2( st->Q_syn, syn, st->preemph_fac, st->L_frame, &tmp_deemph ); /* tmp_deemph and syn in Q0 starting from here*/
696 :
697 612 : bufferCopyFx( syn + shr( st->L_frame, 1 ), hTcxDec->old_syn_Overl, shr( st->L_frame, 1 ), 0 /*Qf_syn*/, -1 /*Qf_old_xnq*/, 0, 0 /*Q_old_xnq*/ );
698 612 : st->hTcxDec->Q_old_syn_Overl = sub( st->Q_syn, 1 );
699 612 : move16();
700 :
701 612 : Copy( syn + sub( st->L_frame, M + 1 ), st->syn, 1 + M ); /*Q0*/
702 :
703 612 : Copy( syn, synth, st->L_frame );
704 612 : IF( st->hBWE_TD != NULL )
705 : {
706 612 : Copy( syn, hBWE_TD->old_core_synth_fx, st->L_frame );
707 : }
708 :
709 :
710 : /* update old_Aq */
711 612 : Copy( exc_buf + st->L_frame, st->old_exc_fx, L_EXC_MEM_DEC );
712 :
713 : /* Output pitch parameters for bass post-filter */
714 3672 : FOR( i_subfr = 0; i_subfr < st->L_frame; i_subfr += L_SUBFR )
715 : {
716 3060 : Word16 idx = 0;
717 3060 : move16();
718 3060 : IF( i_subfr != 0 )
719 : {
720 2448 : idx = idiv1616( i_subfr, L_SUBFR );
721 : }
722 3060 : *pT++ = round_fx( pitch_buf[idx] ); // Q0
723 : }
724 :
725 :
726 612 : hTcxDec->tcxltp_last_gain_unmodified = 0;
727 612 : move16();
728 :
729 : /*Update MODE1*/
730 612 : Copy( p_A - ( M + 1 ), st->old_Aq_12_8_fx, M + 1 );
731 612 : st->old_Es_pred_fx = Es_pred;
732 612 : move16();
733 :
734 612 : hTcxDec->tcxltp_third_last_pitch = hTcxDec->tcxltp_second_last_pitch;
735 612 : move32();
736 612 : hTcxDec->tcxltp_second_last_pitch = st->old_fpitch;
737 612 : move32();
738 612 : st->old_fpitch = pitch_buf[( ( st->L_frame >> 6 ) - 1 )];
739 612 : move32();
740 :
741 :
742 612 : return;
743 : }
|