Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 : #include <stdint.h>
6 : #include "options.h" /* Compilation switches */
7 : #include "cnst.h" /* Common constants */
8 : #include "rom_com.h" /* Common static table prototypes */
9 : #include "rom_dec.h" /* Decoder static table prototypes */
10 : #include "prot_fx.h" /* Function prototypes */
11 : #include "basop_util.h"
12 : /*-------------------------------------------------------------------*
13 : * Local function prototypes
14 : *-------------------------------------------------------------------*/
15 : static void pulseRes_preCalc( Word16 *cond1, Word16 *cond2, Word32 *cond3, Word16 new_pit, Word16 Tc, Word16 L_frame );
16 : void gain_dec_bfi_fx( Word16 *past_qua_en );
17 : /*======================================================================*/
18 : /* FUNCTION : FEC_exc_estim_fx() */
19 : /*----------------------------------------------------------------------*/
20 : /* PURPOSE : Calculation of excitation signal */
21 : /* */
22 : /*----------------------------------------------------------------------*/
23 : /* GLOBAL INPUT ARGUMENTS : */
24 : /* _ (Struct) st_fx : decoder static memory */
25 : /* _ (Word16) L_frame : length of the frame Q0 */
26 : /* _ (Word16) st_fx->lp_ener_fx : FEC - low-pass filtered energy Q6 */
27 : /* _ (Word16) st_fx->lp_gainc_fx : FEC - low-pass filtered code gain Q3 */
28 : /* _ (Word16) st_fx->old_pitch_buf : FEC buffer of old subframe pitch valuesQ6*/
29 : /* _ (Word16) st_fx->last_good : FEC - clas of last good received */
30 : /* _ (Word16) st_fx->bfi_pitch_fx : LP filter coefficient */
31 : /* _ (Word16) st_fx->upd_cnt : FEC counter of frames since last update*/
32 : /* _ (Word16) st_fx->last_coder_type: previous coder type */
33 : /* _ (Word16) st_fx->Last_GSC_pit_band_idx: AC mode (GSC)Last pitch band index*/
34 : /* _ (Word16) st_fx->stab_fac_fx : LSF stability factor Q15 */
35 : /* _ (Word16) st_fx->tilt_code : tilt of code Q15 */
36 : /* _ (Word16) st_fx->last_voice_factor : coding type Q12 */
37 : /* _ (Word16) st_fx->opt_AMR_WB_fx : coding type Q12 */
38 : /* _ (Word16) st_fx->lp_gainp_fx : FEC -low-pass filtered pitch gain Q14 */
39 : /* _ (Word16) st_fx->seed :FEC-seed for random generator for excitation*/
40 : /* _ (Word16) st_fx->opt_OMR_WB:flag indicating AMR-WB IO mode */
41 : /*-----------------------------------------------------------------------*/
42 : /* OUTPUT ARGUMENTS : */
43 : /* _ (Word16[]) exc_fx : adapt. excitation exc (Q_exc) */
44 : /* _ (Word16[]) exc2_fx : adapt. excitation/total exc (Q_exc) */
45 : /* _ (Word16[]) bwe_exc_fx : excitation for SWB TBE (Q_exc) */
46 : /* _ (Word16[]) pitch_buf_fx : floating pitch values for each subframe Q6*/
47 : /* _ (Word16[]) voice_factors_fx : frame error rate Q15 */
48 : /* _ (Word16[]) FEC_pitch_fx(tmp_tc): FEC pitch Q6 */
49 : /*-----------------------------------------------------------------------*/
50 :
51 : /* _ (Word16) st_fx->lp_gainp_fx : FEC -low-pass filtered pitch gain Q14 */
52 : /* _ (Word16) st_fx->seed :FEC-seed for random generator for excitation*/
53 : /* _ (Word16) st_fx->bfi_pitch_fx : LP filter coefficient */
54 : /* _ (Word16) st_fx->lp_gainc_fx : FEC - low-pass filtered code gain Q3 */
55 : /*-----------------------------------------------------------------------*/
56 : /* RETURN ARGUMENTS : */
57 : /* _ None */
58 : /*=======================================================================*/
59 :
60 :
61 5822 : void FEC_exc_estim_fx(
62 : Decoder_State *st_fx, /* i/o: Decoder static memory */
63 : const Word16 L_frame, /* i : length of the frame */
64 : Word16 *exc, /* o : pointer to excitation buffer (with past) */
65 : Word16 *exc2, /* o : total excitation (for synthesis) */
66 : Word16 exc_dct_in[], /* o : GSC excitation in DCT domain */
67 : Word16 *pitch_buf, /* o : Floating pitch for each subframe */
68 : Word16 *voice_factors, /* o : voicing factors */
69 : Word16 *tmp_tc, /* o : FEC pitch Q6 */
70 : Word16 *bwe_exc, /* o : excitation for SWB TBE */
71 : Word16 *lsf_new, /* i : ISFs at the end of the frame */
72 : Word16 *Q_exc,
73 : Word16 *tmp_noise /* o : long-term noise energy Q0 */
74 : )
75 : {
76 :
77 : Word16 exc2_buf[L_FRAME16k + MODE1_L_FIR_FER - 1];
78 : Word16 gainCNG, new_pit /*Q0*/; /* Q3*/
79 : Word16 exp;
80 : Word32 L_tmp, L_tmp2;
81 : Word16 tmp, tmp1, tmp16;
82 : Word16 delta;
83 : Word16 i, j;
84 : Word16 alpha;
85 : Word16 gain, gain_inov;
86 : Word16 Tc;
87 : Word16 *pt_exc, *pt1_exc;
88 : Word16 step;
89 : Word32 L_step;
90 : Word16 hp_filt[5];
91 : Word16 Diff_len, max_len, Len;
92 : Word16 last_bin_fx, nb_subfr;
93 : Word16 extrapolationFailed;
94 : Word16 cond1, cond2;
95 : Word32 cond3;
96 : Word32 predPitchLag;
97 : GSC_DEC_HANDLE hGSCDec;
98 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
99 5822 : Flag Overflow = 0;
100 5822 : move16();
101 : #endif
102 5822 : hGSCDec = st_fx->hGSCDec;
103 :
104 : AMRWB_IO_DEC_HANDLE hAmrwb_IO;
105 5822 : hAmrwb_IO = st_fx->hAmrwb_IO;
106 : /* nb_subfr = L_frame/L_SUBFR */
107 5822 : nb_subfr = shr( L_frame, 6 );
108 5822 : Diff_len = 0; /* to avoid compilation flags */
109 5822 : move16();
110 5822 : set16_fx( exc_dct_in, 0, L_FRAME16k );
111 :
112 5822 : extrapolationFailed = 1;
113 5822 : move16();
114 :
115 5822 : gainCNG = 0;
116 5822 : move16();
117 5822 : IF( st_fx->lp_ener_fx != 0 )
118 : {
119 490 : exp = norm_l( st_fx->lp_ener_fx ); /*lp_ener in Q6*/
120 490 : tmp = extract_h( L_shl( st_fx->lp_ener_fx, exp ) );
121 490 : exp = sub( exp, 30 - 6 );
122 :
123 490 : tmp = div_s( 16384, tmp );
124 490 : L_tmp = L_deposit_h( tmp );
125 490 : L_tmp = Isqrt_lc( L_tmp, &exp );
126 :
127 490 : gainCNG = round_fx( L_shl( L_tmp, sub( exp, 12 ) ) ); /* In Q3 */
128 : }
129 5822 : tmp1 = shl_o( st_fx->lp_gainc_fx, 1, &Overflow );
130 5822 : gainCNG = s_min( gainCNG, tmp1 );
131 5822 : set16_fx( exc_dct_in, 0, L_FRAME16k );
132 :
133 : /*-----------------------------------------------------------------*
134 : * pitch extrapolation
135 : *-----------------------------------------------------------------*/
136 :
137 : {
138 : Word32 *tmp_old_pitch /*15Q16*/;
139 : Word16 tmp_pitmin, tmp_pitmax;
140 :
141 : /*tmp_old_pitch = L_frame == L_FRAME ? &st_fx->old_pitch_buf_fx[2*NB_SUBFR-1] : &st_fx->old_pitch_buf_fx[2*NB_SUBFR16k-1];*/
142 : /*tmp_pitmin = L_frame == L_FRAME?PIT_MIN_DOUBLEEXTEND:PIT16k_MIN_EXTEND;*/
143 : /*tmp_pitmax = L_frame == L_FRAME?PIT_MAX:PIT16k_MAX;*/
144 :
145 5822 : tmp_old_pitch = &st_fx->old_pitch_buf_fx[2 * NB_SUBFR16k - 1];
146 5822 : tmp_pitmin = PIT16k_MIN_EXTEND;
147 5822 : move16();
148 5822 : tmp_pitmax = PIT16k_MAX;
149 5822 : move16();
150 5822 : IF( EQ_16( L_frame, L_FRAME ) )
151 : {
152 1310 : tmp_old_pitch = &st_fx->old_pitch_buf_fx[2 * NB_SUBFR - 1];
153 1310 : tmp_pitmin = PIT_MIN_DOUBLEEXTEND;
154 1310 : move16();
155 1310 : tmp_pitmax = PIT_MAX;
156 1310 : move16();
157 : }
158 :
159 :
160 5822 : pitch_pred_linear_fit(
161 5822 : st_fx->nbLostCmpt,
162 5822 : st_fx->last_good,
163 5822 : st_fx->old_pitch_buf_fx,
164 : tmp_old_pitch,
165 : &predPitchLag,
166 : tmp_pitmin,
167 : tmp_pitmax,
168 5822 : st_fx->mem_pitch_gain,
169 : 0,
170 : 0,
171 : &extrapolationFailed,
172 : nb_subfr );
173 :
174 5822 : new_pit /*Q0 int*/ = shl( round_fx( predPitchLag ), 0 );
175 : }
176 :
177 :
178 : /*-----------------------------------------------------------------*
179 : * estimate subframe pitch values for the FEC frame
180 : *-----------------------------------------------------------------*/
181 :
182 : /* initialize pitch to the long-term pitch */
183 :
184 5822 : *tmp_tc = st_fx->bfi_pitch_fx;
185 5822 : move16(); /*Q6*/
186 5822 : IF( EQ_16( L_frame, L_FRAME ) )
187 : {
188 1310 : test();
189 1310 : test();
190 1310 : IF( ( LT_16( round_fx( L_shl( st_fx->old_pitch_buf_fx[2 * NB_SUBFR - 1], 6 ) ), shl_o( mult( 29491, st_fx->bfi_pitch_fx ), 1, &Overflow ) ) &&
191 : GT_16( round_fx( L_shl( st_fx->old_pitch_buf_fx[2 * NB_SUBFR - 1], 6 ) ), mult( 19661, st_fx->bfi_pitch_fx ) ) ) || /* last pitch coherent with the past */
192 : GE_16( st_fx->upd_cnt, MAX_UPD_CNT ) ) /* or last update too far in the past */
193 : {
194 : /* take the pitch value of last subframe of the previous frame */
195 1287 : *tmp_tc = round_fx( L_shl( st_fx->old_pitch_buf_fx[2 * NB_SUBFR - 1], 6 ) );
196 1287 : move16();
197 : }
198 : }
199 : ELSE /* L_frame == L_FRAME16k */
200 : {
201 4512 : test();
202 4512 : test();
203 4512 : IF( ( LT_16( round_fx( L_shl( st_fx->old_pitch_buf_fx[2 * NB_SUBFR16k - 1], 6 ) ), shl_o( mult( 29491, st_fx->bfi_pitch_fx ), 1, &Overflow ) ) &&
204 : GT_16( round_fx( L_shl( st_fx->old_pitch_buf_fx[2 * NB_SUBFR16k - 1], 6 ) ), mult( 19661, st_fx->bfi_pitch_fx ) ) ) || /* last pitch coherent with the past */
205 : GE_16( st_fx->upd_cnt, MAX_UPD_CNT ) ) /* or last update too far in the past */
206 : {
207 : /* take the pitch value of last subframe of the previous frame */
208 4495 : *tmp_tc = round_fx( L_shl( st_fx->old_pitch_buf_fx[2 * NB_SUBFR16k - 1], 6 ) );
209 4495 : move16();
210 : }
211 : }
212 :
213 : /* convert pitch period */
214 : /* Tc = (short)(tmp_tc + 0.5f) */
215 5822 : Tc = shr_r( *tmp_tc, 6 );
216 :
217 : /* estimate pitch values for all subframes */
218 : /*calculate conditions for Pulse resynchronization to take place*/
219 5822 : pulseRes_preCalc( &cond1, &cond2, &cond3, new_pit, Tc, L_frame );
220 :
221 5822 : test();
222 5822 : test();
223 5822 : test();
224 5822 : test();
225 5822 : IF( ( cond1 < 0 ) && ( new_pit > 0 ) && ( cond2 != 0 ) && ( cond3 > 0 ) && extrapolationFailed == 0 )
226 : {
227 283 : tmp16 = *tmp_tc; /*Q6*/
228 283 : move16();
229 283 : IF( EQ_16( nb_subfr, 4 ) )
230 : {
231 74 : delta = shr( sub( shl( new_pit, 6 ), *tmp_tc ), 2 ); /* 4 sub-frames */
232 : }
233 : ELSE
234 : {
235 209 : delta = mult_r( sub( shl( new_pit, 6 ), *tmp_tc ), 6554 ); /* 5 sub-frames */
236 : }
237 1624 : FOR( i = 0; i < nb_subfr; i++ ) /* subframe pitch values */
238 : {
239 : /* fT0 += delta */
240 1341 : tmp16 = add( tmp16, delta );
241 : /* ptch_buf[i] = (short)(fT0 + 0.5) */
242 1341 : pitch_buf[i] = shl( mult_r( tmp16, 512 ), 6 );
243 1341 : move16();
244 : }
245 : }
246 : ELSE
247 : {
248 31998 : FOR( i = 0; i < nb_subfr; i++ ) /* subframe pitch values for bass postfilter */
249 : {
250 26459 : pitch_buf[i] = *tmp_tc;
251 26459 : move16();
252 : }
253 : }
254 :
255 : /*-----------------------------------------------------------------*
256 : * estimate damping factor
257 : *-----------------------------------------------------------------*/
258 :
259 : /* rapid convergence to 0 */
260 5822 : alpha = _ALPHA_VT_FX;
261 5822 : move16();
262 5822 : test();
263 5822 : test();
264 5822 : test();
265 5822 : test();
266 5822 : test();
267 5822 : test();
268 5822 : test();
269 5822 : IF( EQ_16( st_fx->last_coder_type, UNVOICED ) && LE_16( st_fx->nbLostCmpt, 3 ) )
270 : {
271 : /* last good frame was clearly unvoiced */
272 282 : alpha = _ALPHA_UU_FX;
273 282 : move16();
274 : }
275 5540 : ELSE IF( EQ_16( st_fx->last_coder_type, AUDIO ) || EQ_16( st_fx->last_good, INACTIVE_CLAS ) )
276 : {
277 124 : test();
278 124 : IF( hGSCDec->Last_GSC_pit_band_idx > 0 && GT_16( st_fx->nbLostCmpt, 1 ) )
279 : {
280 14 : alpha = 26214;
281 14 : move16();
282 : }
283 110 : ELSE IF( LE_16( st_fx->nbLostCmpt, 5 ) )
284 : {
285 110 : alpha = 32604;
286 110 : move16();
287 : }
288 : ELSE
289 : {
290 0 : alpha = 31130;
291 0 : move16();
292 : }
293 : }
294 5416 : ELSE IF( EQ_16( st_fx->last_good, UNVOICED_CLAS ) )
295 : {
296 948 : IF( LE_16( st_fx->nbLostCmpt, 1 ) )
297 : {
298 : /* if stable, do not decrease the energy, pitch_gain = 0 */
299 782 : alpha = mac_ro( ( 1L << 16 ) * 2 * _ALPHA_U_FX, st_fx->stab_fac_fx, 32768 - 2 * _ALPHA_U_FX, &Overflow ); /*st_fx->stab_fac_fx in Q15*/
300 : }
301 166 : ELSE IF( EQ_16( st_fx->nbLostCmpt, 2 ) )
302 : {
303 160 : alpha = _ALPHA_S_FX;
304 160 : move16(); /* ALPHA_U*1.5f = 0.6 */
305 : }
306 : ELSE
307 : {
308 6 : alpha = _ALPHA_U_FX;
309 6 : move16(); /* 0.4 go rapidly to CNG gain, pitch gain = 0 */
310 : }
311 : }
312 4468 : ELSE IF( EQ_16( st_fx->last_good, UNVOICED_TRANSITION ) )
313 : {
314 14 : alpha = _ALPHA_UT_FX;
315 14 : move16();
316 : }
317 4454 : ELSE IF( EQ_16( st_fx->last_good, ONSET ) && LE_16( st_fx->nbLostCmpt, 3 ) && ( EQ_16( st_fx->last_coder_type, GENERIC ) || EQ_16( st_fx->last_coder_type, TRANSITION ) ) )
318 : {
319 161 : alpha = 26214;
320 161 : move16(); /* mild convergence to 0 for the first 3 erased frames 0.8 in Q15 */
321 : }
322 4293 : ELSE IF( ( EQ_16( st_fx->last_good, VOICED_CLAS ) || EQ_16( st_fx->last_good, ONSET ) ) && LE_16( st_fx->nbLostCmpt, 3 ) )
323 : {
324 2255 : alpha = _ALPHA_V_FX;
325 2255 : move16(); /* constant for the first 3 erased frames */
326 : }
327 2038 : ELSE IF( EQ_16( st_fx->last_good, SIN_ONSET ) )
328 : {
329 12 : alpha = _ALPHA_S_FX;
330 12 : move16();
331 : }
332 5822 : test();
333 5822 : test();
334 5822 : IF( GE_16( st_fx->last_good, VOICED_CLAS ) && LT_16( st_fx->last_good, INACTIVE_CLAS ) && NE_16( st_fx->last_coder_type, AUDIO ) )
335 : {
336 2578 : IF( EQ_16( st_fx->nbLostCmpt, 1 ) ) /* if first erased frame in a block, reset harmonic gain */
337 : {
338 : /* move pitch gain towards 1 for voiced to remove energy fluctuations */
339 : /*gain = (float)sqrt( st_fx->lp_gainp );*/
340 1860 : st_fx->lp_gainp_fx = s_max( st_fx->lp_gainp_fx, 1 );
341 1860 : move16();
342 1860 : exp = norm_s( st_fx->lp_gainp_fx );
343 1860 : tmp = shl( st_fx->lp_gainp_fx, exp );
344 1860 : tmp = div_s( 16384, tmp );
345 1860 : L_tmp = L_deposit_h( tmp );
346 1860 : L_tmp = Isqrt_lc( L_tmp, &exp );
347 :
348 1860 : gain = extract_h( L_shl_o( L_tmp, exp, &Overflow ) );
349 :
350 1860 : gain = s_min( gain, 32113 ); /*0.98 */
351 1860 : gain = s_max( gain, 27853 ); /*0.85 */
352 :
353 1860 : alpha = mult_r( alpha, gain );
354 : }
355 : ELSE
356 : {
357 : /* st_fx->lp_gainp_fx is in Q14 when bfi_cnt > 1 to follow floating point because lp_gainp could be > than 1 */
358 718 : alpha = st_fx->lp_gainp_fx;
359 718 : move16();
360 : }
361 : }
362 :
363 : /*-----------------------------------------------------------------*
364 : * construct the harmonic part of excitation
365 : *-----------------------------------------------------------------*/
366 5822 : test();
367 5822 : test();
368 5822 : test();
369 5822 : test();
370 5822 : IF( ( GE_16( st_fx->last_good, UNVOICED_TRANSITION ) && LT_16( st_fx->last_good, INACTIVE_CLAS ) ) ||
371 : ( ( EQ_16( st_fx->last_coder_type, AUDIO ) || EQ_16( st_fx->last_good, INACTIVE_CLAS ) ) && hGSCDec->Last_GSC_pit_band_idx > 0 ) )
372 : {
373 :
374 4620 : pt_exc = exc;
375 4620 : pt1_exc = pt_exc - Tc;
376 :
377 4620 : IF( EQ_16( st_fx->nbLostCmpt, 1 ) )
378 : {
379 : /* first pitch cycle is low-pass filtered */
380 :
381 193753 : FOR( i = 0; i < Tc; i++ ) /* pitch cycle is first low-pass filtered */
382 : {
383 : /* *pt_exc++ = (0.18f * pt1_exc[-1] + 0.64f * pt1_exc[0] + 0.18f * pt1_exc[1]) */
384 191625 : L_tmp = L_mult( 5898, pt1_exc[-1] );
385 191625 : L_tmp = L_mac( L_tmp, 20972, pt1_exc[0] );
386 191625 : *pt_exc++ = mac_r( L_tmp, 5898, pt1_exc[1] );
387 191625 : move16();
388 191625 : pt1_exc++;
389 : }
390 : }
391 :
392 : /* last pitch cycle of the previous frame is repeatedly copied up to an extra subframe */
393 :
394 4620 : tmp = extract_l( ( exc + add( L_frame, L_SUBFR ) ) - pt_exc );
395 1538947 : FOR( i = 0; i < tmp; i++ )
396 : {
397 1534327 : *pt_exc++ = *pt1_exc++;
398 1534327 : move16();
399 : }
400 :
401 4620 : IF( new_pit > 0 )
402 : {
403 : /*calculate conditions for Pulse resynchronization to take place*/
404 3016 : pulseRes_preCalc( &cond1, &cond2, &cond3, new_pit, Tc, L_frame );
405 :
406 3016 : test();
407 3016 : test();
408 3016 : test();
409 3016 : test();
410 3016 : IF( ( cond1 < 0 ) && ( new_pit > 0 ) && ( cond2 != 0 ) && ( cond3 > 0 ) && extrapolationFailed == 0 )
411 : {
412 283 : Copy( exc, exc - add( L_frame, L_SUBFR ), add( L_frame, L_SUBFR ) );
413 283 : PulseResynchronization_fx( exc - add( L_frame, L_SUBFR ), exc, L_frame, nb_subfr, L_deposit_h( Tc /*Q0*/ ) /*15Q16*/, L_deposit_h( new_pit /*Q0*/ ) /*15Q16*/ );
414 : }
415 : }
416 4620 : test();
417 4620 : test();
418 4620 : IF( EQ_16( st_fx->last_good, UNVOICED_TRANSITION ) && ( EQ_16( st_fx->last_coder_type, GENERIC ) || EQ_16( st_fx->last_coder_type, TRANSITION ) ) )
419 : {
420 : /* start of the frame gain */
421 14 : gain = 0;
422 14 : move16();
423 :
424 : /* end of the frame gain */
425 14 : st_fx->lp_gainp_fx = 0;
426 14 : move16();
427 14 : step = 0;
428 14 : move16();
429 : }
430 : ELSE
431 : {
432 :
433 : /* start of the frame gain */
434 4606 : gain = 16384;
435 4606 : move16();
436 :
437 : /* end of the frame gain */
438 4606 : test();
439 4606 : test();
440 4606 : test();
441 4606 : IF( !( GE_16( st_fx->last_good, VOICED_CLAS ) && LT_16( st_fx->last_good, INACTIVE_CLAS ) && NE_16( st_fx->last_coder_type, AUDIO ) && GT_16( st_fx->nbLostCmpt, 1 ) ) )
442 : {
443 3888 : st_fx->lp_gainp_fx = shr( alpha, 1 ); /* alpha in Q15 */
444 : }
445 : ELSE
446 : {
447 718 : st_fx->lp_gainp_fx = alpha;
448 718 : move16(); /* alpha in Q14 */
449 : }
450 :
451 4606 : IF( EQ_16( L_frame, L_FRAME ) )
452 : {
453 748 : step = shr( sub( gain, st_fx->lp_gainp_fx ), 8 );
454 : }
455 : ELSE /*L_frame == L_FRAME16k*/
456 : {
457 : /*step = (1.0f/L_frame) * (gain - st_fx->lp_gainp);*/
458 :
459 3858 : step = shr( mult_r( 26214, sub( gain, st_fx->lp_gainp_fx ) ), 8 ); /*Q14*/
460 : }
461 : }
462 :
463 1434892 : FOR( i = 0; i < L_frame; i++ )
464 : {
465 : /* exc[i] *= gain */
466 1430272 : exc[i] = round_fx( L_shl( L_mult( exc[i], gain ), 1 ) ); /* in Q_exc */
467 1430272 : move16();
468 : /* gain -= step */
469 1430272 : gain = sub( gain, step );
470 : }
471 4620 : test();
472 4620 : test();
473 4620 : IF( ( EQ_16( st_fx->last_coder_type, AUDIO ) || EQ_16( st_fx->last_good, INACTIVE_CLAS ) ) && hGSCDec->Last_GSC_pit_band_idx > 0 )
474 : {
475 91 : Diff_len = mfreq_loc_div_25[hGSCDec->Last_GSC_pit_band_idx];
476 91 : move16();
477 :
478 : /* Transform to frequency domain */
479 91 : edct_16fx( exc, exc_dct_in, st_fx->L_frame, 5, st_fx->element_mode );
480 :
481 : /* Reset unvaluable part of the adaptive (pitch) excitation contribution */
482 91 : max_len = sub( st_fx->L_frame, Diff_len );
483 91 : Len = s_min( max_len, 80 );
484 :
485 91 : move16(); /*ptr init*/
486 6763 : FOR( i = 0; i < Len; i++ )
487 : {
488 6672 : exc_dct_in[i + Diff_len] = mult_r( exc_dct_in[i + Diff_len], sm_table_fx[i] );
489 6672 : move16();
490 : }
491 :
492 3798 : FOR( ; i < max_len; i++ )
493 : {
494 3707 : exc_dct_in[i + Diff_len] = 0;
495 3707 : move16();
496 : }
497 91 : Diff_len = add( Diff_len, 1 );
498 : }
499 : } /* end of "if st_fx->last_good >= VOICED_TRANSITION" */
500 :
501 : /*-----------------------------------------------------------------*
502 : * Replicate the last spectrum in case the last good frame was coded by GSC
503 : *-----------------------------------------------------------------*/
504 5822 : test();
505 5822 : test();
506 5822 : test();
507 5822 : IF( EQ_16( st_fx->last_coder_type, AUDIO ) || ( EQ_16( st_fx->last_good, INACTIVE_CLAS ) && st_fx->inactive_coder_type_flag && !st_fx->Opt_AMR_WB ) )
508 : {
509 202 : st_fx->GSC_noisy_speech = st_fx->Last_GSC_noisy_speech_flag;
510 202 : move16();
511 : /* st_fx->L_frame / L_SUBFR */
512 202 : tmp = shr( st_fx->L_frame, 6 );
513 : /* Replication of the last spectrum, with a slight downscaling of its dynamic */
514 : #ifdef REMOVE_EVS_DUPLICATES
515 202 : gsc_dec_ivas_fx( st_fx, exc_dct_in, hGSCDec->Last_GSC_pit_band_idx, Diff_len, 0, tmp, st_fx->last_coder_type, &last_bin_fx, lsf_new, NULL, &st_fx->Q_exc );
516 : #else
517 : IF( st_fx->element_mode == EVS_MONO )
518 : {
519 : gsc_dec_fx( st_fx, exc_dct_in, hGSCDec->Last_GSC_pit_band_idx, Diff_len, 0, tmp, st_fx->last_coder_type, &last_bin_fx, lsf_new, NULL, st_fx->Q_exc );
520 : }
521 : ELSE
522 : {
523 : gsc_dec_ivas_fx( st_fx, exc_dct_in, hGSCDec->Last_GSC_pit_band_idx, Diff_len, 0, tmp, st_fx->last_coder_type, &last_bin_fx, lsf_new, NULL, &st_fx->Q_exc );
524 : }
525 : #endif
526 202 : *tmp_noise = shr_r( st_fx->lp_gainc_fx, 3 ); /*Q0*/
527 202 : move16();
528 : /* Transform back to time domain */
529 202 : edct_16fx( exc_dct_in, exc, st_fx->L_frame, 5, st_fx->element_mode );
530 : }
531 : ELSE
532 : {
533 : /*-----------------------------------------------------------------*
534 : * Construct the random part of excitation
535 : *-----------------------------------------------------------------*/
536 :
537 : /* generate the random part of the excitation */
538 1755332 : FOR( i = 0; i < L_frame + MODE1_L_FIR_FER - 1; i++ )
539 : {
540 : /*Q-3*/
541 1749712 : exc2_buf[i] = shr( Random( &st_fx->seed ), 3 );
542 1749712 : move16();
543 : }
544 :
545 : /* start of the frame gain */
546 5620 : gain = st_fx->lp_gainc_fx;
547 5620 : move16();
548 :
549 5620 : test();
550 5620 : test();
551 5620 : test();
552 5620 : IF( !( GE_16( st_fx->last_good, VOICED_CLAS ) && LT_16( st_fx->last_good, INACTIVE_CLAS ) && NE_16( st_fx->last_coder_type, AUDIO ) && GT_16( st_fx->nbLostCmpt, 1 ) ) )
553 : {
554 : /* Here alpha is in Q15 and lp_gainc_fx in Q3 */
555 : /* st_fx->lp_gainc = alpha * st_fx->lp_gainc + (1.0f - alpha) * gainCNG; */
556 4902 : L_tmp = L_mult( alpha, st_fx->lp_gainc_fx );
557 :
558 4902 : st_fx->lp_gainc_fx = msu_r( L_tmp, add( alpha, -32768 ), gainCNG );
559 4902 : move16();
560 : }
561 : ELSE
562 : { /* Here alpha is in Q14, but lp_gainc still in Q3 */
563 : /* st_fx->lp_gainc = alpha * st_fx->lp_gainc + (1.0f - alpha) * gainCNG; */
564 718 : L_tmp = L_mult( alpha, st_fx->lp_gainc_fx ); /* Q14*Q3->Q18 */
565 :
566 718 : st_fx->lp_gainc_fx = round_fx( L_shl( L_msu( L_tmp, add( alpha, -16384 ), gainCNG ), 1 ) ); /* (Q14*Q3<<1)>>16 ->Q3 */
567 718 : move16();
568 : }
569 :
570 5620 : test();
571 5620 : test();
572 5620 : test();
573 5620 : if ( EQ_16( st_fx->last_good, UNVOICED_TRANSITION ) && ( EQ_16( st_fx->last_coder_type, GENERIC ) || EQ_16( st_fx->last_coder_type, TRANSITION ) ) && gainCNG > 0 )
574 : {
575 2 : st_fx->lp_gainc_fx = gainCNG;
576 2 : move16();
577 : }
578 :
579 : /* linearly attenuate the gain throughout the frame */
580 : /* step = (1.0f/L_FRAME) * (gain - *lp_gainc); */
581 5620 : step = sub( gain, st_fx->lp_gainc_fx ); /* divide by L_FRAME done later */
582 5620 : test();
583 5620 : IF( EQ_16( L_frame, L_FRAME16k ) )
584 : {
585 4508 : step = mult_r( step, 26214 ); /* L_frame16k-> L_frame and division by L_frame done later*/
586 : }
587 :
588 : /* calculate gain to normalize energy */
589 5620 : pt_exc = exc2_buf + MODE1_L_FIR_FER / 2;
590 5620 : move16();
591 :
592 : /* To avoid saturation split the L_frame dot product into (L_frame/L_SUBFR) dot products
593 : and scale down before adding */
594 : /* gain_inov = 1.0f / (float)sqrt( dotp( pt_exc, pt_exc, L_frame ) / L_frame + 0.01f ); */
595 :
596 5620 : L_tmp = L_deposit_l( 0 );
597 16860 : FOR( i = 0; i < 2; i++ )
598 : {
599 11240 : L_tmp2 = L_mult0( *pt_exc, *pt_exc );
600 11240 : pt_exc++;
601 1727232 : FOR( j = 1; j < shr( L_frame, 1 ); j++ )
602 : {
603 1715992 : L_tmp2 = L_mac0( L_tmp2, *pt_exc, *pt_exc ); /* Q-5 */
604 1715992 : pt_exc++;
605 : }
606 11240 : L_tmp = L_add( L_tmp, L_shr( L_tmp2, 1 ) ); /* Q-7 */
607 : }
608 5620 : test();
609 5620 : IF( EQ_16( L_frame, L_FRAME16k ) )
610 : {
611 4508 : L_tmp = Mult_32_16( L_tmp, 26214 ); /* x0.8 to normalize to 256 samples */
612 : }
613 5620 : exp = norm_l( L_tmp );
614 5620 : L_tmp = L_shl( L_tmp, exp ); /* Normalize */
615 5620 : exp = add( exp, 8 - 7 ); /* Q0, 8 ->divide by 256 */
616 5620 : exp = sub( 31, exp ); /* For Denormalization in Q31 */
617 5620 : L_tmp = Isqrt_lc( L_tmp, &exp ); /* in Q(31-exp) */
618 5620 : gain_inov = round_fx( L_tmp );
619 :
620 : /* attenuate somewhat on unstable unvoiced */
621 5620 : test();
622 5620 : test();
623 5620 : IF( ( EQ_16( st_fx->last_good, UNVOICED_CLAS ) || EQ_16( st_fx->last_good, INACTIVE_CLAS ) ) && NE_16( st_fx->last_coder_type, UNVOICED ) )
624 : {
625 952 : gain_inov = mult_r( gain_inov, 26214 );
626 : }
627 :
628 : /* scaling of the random part of excitation */
629 5620 : pt_exc = exc2_buf;
630 5620 : move16();
631 5620 : L_step = L_shr( L_mult( gain_inov, step ), 8 ); /* here is the divide by L_FRAME */
632 5620 : L_tmp2 = L_mult( gain_inov, gain ); /* Q15 * Q3 -> Q3 */
633 5620 : tmp = round_fx( L_tmp2 );
634 5620 : exp = add( add( exp, *Q_exc ), 15 ); /* 3+Q_exc+15 -> Q_exc+18 */
635 :
636 16860 : FOR( i = 0; i < MODE1_L_FIR_FER / 2; i++ )
637 : {
638 : /* non-causal ringing of the FIR filter */
639 : /**pt_exc++ *= (gain_inov * gain);*/
640 11240 : L_tmp = L_mult( tmp, *pt_exc ); /* Q_exc+18 * Q-3 -> Q_exc+16 */
641 11240 : *pt_exc++ = round_fx_sat( L_shl_sat( L_tmp, exp ) );
642 11240 : move16();
643 : }
644 :
645 1732852 : FOR( i = 0; i < L_frame; i++ )
646 : {
647 : /* the inner part of the FIR filter */
648 : /* *pt_exc++ *= (gain_inov * gain); */
649 1727232 : L_tmp = L_mult( tmp, *pt_exc );
650 1727232 : *pt_exc++ = round_fx_sat( L_shl_sat( L_tmp, exp ) );
651 1727232 : move16();
652 : /* gain -= step; */
653 1727232 : L_tmp2 = L_sub( L_tmp2, L_step );
654 1727232 : tmp = round_fx( L_tmp2 );
655 : }
656 :
657 16860 : FOR( i = 0; i < MODE1_L_FIR_FER / 2; i++ ) /* causal ringing of the FIR filter */
658 : {
659 : /* *pt_exc++ *= (gain_inov * gain) */
660 11240 : L_tmp = L_mult( tmp, *pt_exc );
661 11240 : *pt_exc++ = round_fx_sat( L_shl_sat( L_tmp, exp ) );
662 11240 : move16();
663 : }
664 : }
665 :
666 : /*-----------------------------------------------------------------*
667 : * Total excitation
668 : *-----------------------------------------------------------------*/
669 5822 : test();
670 5822 : test();
671 5822 : test();
672 5822 : test();
673 5822 : IF( EQ_16( st_fx->last_coder_type, AUDIO ) || ( EQ_16( st_fx->last_good, INACTIVE_CLAS ) && st_fx->inactive_coder_type_flag && !st_fx->Opt_AMR_WB ) )
674 : {
675 : /* For GSC - the excitation is already computed */
676 202 : Copy( exc, exc2, st_fx->L_frame );
677 : }
678 5620 : ELSE IF( GE_16( st_fx->last_good, UNVOICED_TRANSITION ) && LT_16( st_fx->last_good, INACTIVE_CLAS ) )
679 : {
680 : /* For voiced and generic signals - prepare a HP filter for the random part of excitation */
681 : /* tmp = -(1-tilt_code) to correctly represent 1.0000 */
682 4520 : tmp = add( st_fx->tilt_code_fx, -32768 );
683 27120 : FOR( i = 0; i < MODE1_L_FIR_FER; i++ )
684 : {
685 22600 : hp_filt[i] = msu_r( 0, tmp, h_high_fx[i] );
686 22600 : move16();
687 : }
688 :
689 : /* HP filter the random part of the excitation and add the adaptive part */
690 4520 : pt_exc = exc2_buf;
691 1409192 : FOR( i = 0; i < L_frame; i++ )
692 : {
693 : /* exc2[i] = exc[i] + dotp( &exc2_buf[i], hp_filt, MODE1_L_FIR_FER );*/
694 1404672 : L_tmp = L_mult( hp_filt[0], pt_exc[0] );
695 7023360 : FOR( j = 1; j < MODE1_L_FIR_FER; j++ )
696 : {
697 5618688 : L_tmp = L_mac_sat( L_tmp, hp_filt[j], pt_exc[j] );
698 : }
699 1404672 : exc2[i] = msu_r_sat( L_tmp, -32768, exc[i] );
700 1404672 : move16();
701 1404672 : pt_exc++;
702 : }
703 : }
704 : ELSE
705 : {
706 : /* For purely unvoiced signals - just copy the unfiltered random part of the excitation */
707 1100 : Copy( exc2_buf + MODE1_L_FIR_FER / 2, exc, L_frame );
708 1100 : Copy( exc2_buf + MODE1_L_FIR_FER / 2, exc2, L_frame );
709 : }
710 5822 : IF( st_fx->hBWE_TD != NULL )
711 : {
712 5822 : IF( EQ_16( L_frame, L_FRAME ) )
713 : {
714 1310 : interp_code_5over2_fx( exc, bwe_exc, L_frame );
715 : }
716 : ELSE
717 : {
718 4512 : interp_code_4over2_fx( exc, bwe_exc, L_frame );
719 : }
720 : }
721 5822 : test();
722 5822 : IF( EQ_16( st_fx->last_coder_type, AUDIO ) || EQ_16( st_fx->last_good, INACTIVE_CLAS ) )
723 : {
724 206 : IF( EQ_16( st_fx->L_frame, L_FRAME ) )
725 : {
726 198 : set16_fx( voice_factors, 32767, NB_SUBFR );
727 : }
728 : ELSE
729 : {
730 8 : set16_fx( voice_factors, 32767, NB_SUBFR16k );
731 : }
732 : }
733 : ELSE
734 : {
735 5616 : IF( EQ_16( st_fx->L_frame, L_FRAME ) )
736 : {
737 1112 : set16_fx( voice_factors, st_fx->last_voice_factor_fx, NB_SUBFR ); /* The factor of the last subframe is propagated forward */
738 : }
739 : ELSE
740 : {
741 4504 : set16_fx( voice_factors, st_fx->last_voice_factor_fx, NB_SUBFR16k ); /* The factor of the last subframe is propagated forward */
742 : }
743 : }
744 5822 : IF( st_fx->Opt_AMR_WB )
745 : {
746 0 : gain_dec_bfi_fx( hAmrwb_IO->past_qua_en_fx );
747 : }
748 : /* L_frame / L_SUBFR */
749 5822 : tmp = shr( L_frame, 6 );
750 5822 : st_fx->bfi_pitch_fx = pitch_buf[tmp - 1];
751 5822 : move16();
752 5822 : st_fx->bfi_pitch_frame = st_fx->L_frame;
753 5822 : move16();
754 5822 : return;
755 : }
756 :
757 :
758 : /*calculates some conditions for Pulse resynchronization to take place*/
759 8838 : static void pulseRes_preCalc( Word16 *cond1, Word16 *cond2, Word32 *cond3, Word16 new_pit, Word16 Tc, Word16 L_frame )
760 : {
761 : Word16 tmp_pit, tmp_pit_e, tmp_frame, tmp_frame_e;
762 : Word32 tmp_pit2;
763 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
764 8838 : Flag Overflow = 0;
765 8838 : move32();
766 : #endif
767 :
768 8838 : tmp_pit = BASOP_Util_Divide1616_Scale( new_pit /*Q0*/, Tc /*Q0*/, &tmp_pit_e ) /*Q15*/;
769 8838 : tmp_frame = add( extract_l( L_mult0( L_frame, 64 /*1.f/L_SUBFR Q12*/ ) /*Q12*/ ), 4096 /*1.f Q12*/ ); /*Q12*/
770 8838 : tmp_frame = BASOP_Util_Divide1616_Scale( 4096 /*1.f Q12*/, tmp_frame, &tmp_frame_e ); /*Q15*/
771 8838 : tmp_frame = shl( tmp_frame, add( tmp_frame_e, 1 ) );
772 8838 : tmp_frame = sub( 32767 /*1.f Q15*/, tmp_frame ); /*Q15*/
773 : BASOP_SATURATE_WARNING_OFF_EVS
774 : /*To calc Q15 threshold, overflow may happen - do negation and compare with negated value to check also highest possible value*/
775 8838 : tmp_pit = shl_o( negate( tmp_pit ), tmp_pit_e, &Overflow );
776 : BASOP_SATURATE_WARNING_ON_EVS
777 8838 : *cond1 = sub( tmp_pit, negate( tmp_frame ) );
778 8838 : move16();
779 :
780 8838 : *cond2 = sub( Tc, new_pit );
781 8838 : move16();
782 :
783 8838 : tmp_pit_e = BASOP_Util_Add_MantExp( new_pit, 15 - 0, negate( Tc ), 15 - 0, &tmp_pit ); /*Q15*/
784 8838 : tmp_pit = abs_s( tmp_pit );
785 8838 : tmp_pit2 = L_mult( Tc, 4915 /*0.15f Q15*/ ); /*Q16*/
786 : BASOP_SATURATE_WARNING_OFF_EVS
787 : /*To calc Q15 threshold, overflow may happen - do negation and compare with negated value to check also highest possible value*/
788 8838 : tmp_pit2 = L_shl_sat( L_negate( tmp_pit2 ), sub( 15 - 16, tmp_pit_e ) );
789 : BASOP_SATURATE_WARNING_ON_EVS
790 8838 : *cond3 = L_sub( L_mult0( -1, tmp_pit ), tmp_pit2 );
791 8838 : move32();
792 8838 : }
793 :
794 : /*-------------------------------------------------------------------*
795 : * gain_dec_bfi()
796 : *
797 : * Estimate past quantized gain prediction residual to be used in
798 : * next frame
799 : *-------------------------------------------------------------------*/
800 :
801 0 : void gain_dec_bfi_fx(
802 : Word16 *past_qua_en /* i/o: gain quantization memory (4 words) Qx*/
803 : )
804 : {
805 : Word16 i;
806 : Word16 av_pred_en;
807 : Word32 Lav_pred_en;
808 :
809 0 : Lav_pred_en = L_mult( past_qua_en[0], 8192 );
810 0 : FOR( i = 1; i < GAIN_PRED_ORDER; i++ )
811 : {
812 0 : Lav_pred_en = L_mac( Lav_pred_en, past_qua_en[i], 8192 );
813 : }
814 :
815 : /*av_pred_en = (float)(av_pred_en*(1.0f/(float)GAIN_PRED_ORDER)-3.0f);*/
816 0 : av_pred_en = sub( round_fx( Lav_pred_en ), 3 << 10 );
817 :
818 : /*if (av_pred_en < -14.0f)av_pred_en = -14.0f;*/
819 0 : av_pred_en = s_max( av_pred_en, -14 * ( 1 << 10 ) );
820 :
821 :
822 0 : FOR( i = GAIN_PRED_ORDER - 1; i > 0; i-- )
823 : {
824 0 : past_qua_en[i] = past_qua_en[i - 1];
825 0 : move16();
826 : }
827 :
828 0 : past_qua_en[0] = av_pred_en;
829 0 : move16();
830 :
831 0 : return;
832 : }
|