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 5862 : 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 : #ifndef ISSUE_1866_replace_overflow_libdec
99 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
100 : Flag Overflow = 0;
101 : move16();
102 : #endif
103 : #endif
104 5862 : hGSCDec = st_fx->hGSCDec;
105 :
106 : AMRWB_IO_DEC_HANDLE hAmrwb_IO;
107 5862 : hAmrwb_IO = st_fx->hAmrwb_IO;
108 : /* nb_subfr = L_frame/L_SUBFR */
109 5862 : nb_subfr = shr( L_frame, 6 );
110 5862 : Diff_len = 0; /* to avoid compilation flags */
111 5862 : move16();
112 5862 : set16_fx( exc_dct_in, 0, L_FRAME16k );
113 :
114 5862 : extrapolationFailed = 1;
115 5862 : move16();
116 :
117 5862 : gainCNG = 0;
118 5862 : move16();
119 5862 : IF( st_fx->lp_ener_fx != 0 )
120 : {
121 490 : exp = norm_l( st_fx->lp_ener_fx ); /*lp_ener in Q6*/
122 490 : tmp = extract_h( L_shl( st_fx->lp_ener_fx, exp ) );
123 490 : exp = sub( exp, 30 - 6 );
124 :
125 490 : tmp = div_s( 16384, tmp );
126 490 : L_tmp = L_deposit_h( tmp );
127 490 : L_tmp = Isqrt_lc( L_tmp, &exp );
128 :
129 490 : gainCNG = round_fx( L_shl( L_tmp, sub( exp, 12 ) ) ); /* In Q3 */
130 : }
131 : #ifdef ISSUE_1866_replace_overflow_libdec
132 5862 : tmp1 = shl_sat( st_fx->lp_gainc_fx, 1 );
133 : #else
134 : tmp1 = shl_o( st_fx->lp_gainc_fx, 1, &Overflow );
135 : #endif
136 5862 : gainCNG = s_min( gainCNG, tmp1 );
137 5862 : set16_fx( exc_dct_in, 0, L_FRAME16k );
138 :
139 : /*-----------------------------------------------------------------*
140 : * pitch extrapolation
141 : *-----------------------------------------------------------------*/
142 :
143 : {
144 : Word32 *tmp_old_pitch /*15Q16*/;
145 : Word16 tmp_pitmin, tmp_pitmax;
146 :
147 : /*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];*/
148 : /*tmp_pitmin = L_frame == L_FRAME?PIT_MIN_DOUBLEEXTEND:PIT16k_MIN_EXTEND;*/
149 : /*tmp_pitmax = L_frame == L_FRAME?PIT_MAX:PIT16k_MAX;*/
150 :
151 5862 : tmp_old_pitch = &st_fx->old_pitch_buf_fx[2 * NB_SUBFR16k - 1];
152 5862 : tmp_pitmin = PIT16k_MIN_EXTEND;
153 5862 : move16();
154 5862 : tmp_pitmax = PIT16k_MAX;
155 5862 : move16();
156 5862 : IF( EQ_16( L_frame, L_FRAME ) )
157 : {
158 1346 : tmp_old_pitch = &st_fx->old_pitch_buf_fx[2 * NB_SUBFR - 1];
159 1346 : tmp_pitmin = PIT_MIN_DOUBLEEXTEND;
160 1346 : move16();
161 1346 : tmp_pitmax = PIT_MAX;
162 1346 : move16();
163 : }
164 :
165 :
166 5862 : pitch_pred_linear_fit(
167 5862 : st_fx->nbLostCmpt,
168 5862 : st_fx->last_good,
169 5862 : st_fx->old_pitch_buf_fx,
170 : tmp_old_pitch,
171 : &predPitchLag,
172 : tmp_pitmin,
173 : tmp_pitmax,
174 5862 : st_fx->mem_pitch_gain,
175 : 0,
176 : 0,
177 : &extrapolationFailed,
178 : nb_subfr );
179 :
180 5862 : new_pit /*Q0 int*/ = shl( round_fx( predPitchLag ), 0 );
181 : }
182 :
183 :
184 : /*-----------------------------------------------------------------*
185 : * estimate subframe pitch values for the FEC frame
186 : *-----------------------------------------------------------------*/
187 :
188 : /* initialize pitch to the long-term pitch */
189 :
190 5862 : *tmp_tc = st_fx->bfi_pitch_fx;
191 5862 : move16(); /*Q6*/
192 5862 : IF( EQ_16( L_frame, L_FRAME ) )
193 : {
194 1346 : test();
195 1346 : test();
196 : #ifdef ISSUE_1866_replace_overflow_libdec
197 1346 : IF( ( LT_16( round_fx( L_shl( st_fx->old_pitch_buf_fx[2 * NB_SUBFR - 1], 6 ) ), shl_sat( mult( 29491, st_fx->bfi_pitch_fx ), 1 ) ) &&
198 : 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 */
199 : GE_16( st_fx->upd_cnt, MAX_UPD_CNT ) ) /* or last update too far in the past */
200 : #else
201 : 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 ) ) &&
202 : 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 */
203 : GE_16( st_fx->upd_cnt, MAX_UPD_CNT ) ) /* or last update too far in the past */
204 : #endif
205 : {
206 : /* take the pitch value of last subframe of the previous frame */
207 1324 : *tmp_tc = round_fx( L_shl( st_fx->old_pitch_buf_fx[2 * NB_SUBFR - 1], 6 ) );
208 1324 : move16();
209 : }
210 : }
211 : ELSE /* L_frame == L_FRAME16k */
212 : {
213 4516 : test();
214 4516 : test();
215 : #ifdef ISSUE_1866_replace_overflow_libdec
216 4516 : IF( ( LT_16( round_fx( L_shl( st_fx->old_pitch_buf_fx[2 * NB_SUBFR16k - 1], 6 ) ), shl_sat( mult( 29491, st_fx->bfi_pitch_fx ), 1 ) ) &&
217 : 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 */
218 : GE_16( st_fx->upd_cnt, MAX_UPD_CNT ) ) /* or last update too far in the past */
219 : #else
220 : 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 ) ) &&
221 : 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 */
222 : GE_16( st_fx->upd_cnt, MAX_UPD_CNT ) ) /* or last update too far in the past */
223 : #endif
224 :
225 : {
226 : /* take the pitch value of last subframe of the previous frame */
227 4498 : *tmp_tc = round_fx( L_shl( st_fx->old_pitch_buf_fx[2 * NB_SUBFR16k - 1], 6 ) );
228 4498 : move16();
229 : }
230 : }
231 :
232 : /* convert pitch period */
233 : /* Tc = (short)(tmp_tc + 0.5f) */
234 5862 : Tc = shr_r( *tmp_tc, 6 );
235 :
236 : /* estimate pitch values for all subframes */
237 : /*calculate conditions for Pulse resynchronization to take place*/
238 5862 : pulseRes_preCalc( &cond1, &cond2, &cond3, new_pit, Tc, L_frame );
239 :
240 5862 : test();
241 5862 : test();
242 5862 : test();
243 5862 : test();
244 5862 : IF( ( cond1 < 0 ) && ( new_pit > 0 ) && ( cond2 != 0 ) && ( cond3 > 0 ) && extrapolationFailed == 0 )
245 : {
246 288 : tmp16 = *tmp_tc; /*Q6*/
247 288 : move16();
248 288 : IF( EQ_16( nb_subfr, 4 ) )
249 : {
250 80 : delta = shr( sub( shl( new_pit, 6 ), *tmp_tc ), 2 ); /* 4 sub-frames */
251 : }
252 : ELSE
253 : {
254 208 : delta = mult_r( sub( shl( new_pit, 6 ), *tmp_tc ), 6554 ); /* 5 sub-frames */
255 : }
256 1648 : FOR( i = 0; i < nb_subfr; i++ ) /* subframe pitch values */
257 : {
258 : /* fT0 += delta */
259 1360 : tmp16 = add( tmp16, delta );
260 : /* ptch_buf[i] = (short)(fT0 + 0.5) */
261 1360 : pitch_buf[i] = shl( mult_r( tmp16, 512 ), 6 );
262 1360 : move16();
263 : }
264 : }
265 : ELSE
266 : {
267 32178 : FOR( i = 0; i < nb_subfr; i++ ) /* subframe pitch values for bass postfilter */
268 : {
269 26604 : pitch_buf[i] = *tmp_tc;
270 26604 : move16();
271 : }
272 : }
273 :
274 : /*-----------------------------------------------------------------*
275 : * estimate damping factor
276 : *-----------------------------------------------------------------*/
277 :
278 : /* rapid convergence to 0 */
279 5862 : alpha = _ALPHA_VT_FX;
280 5862 : move16();
281 5862 : test();
282 5862 : test();
283 5862 : test();
284 5862 : test();
285 5862 : test();
286 5862 : test();
287 5862 : test();
288 5862 : IF( EQ_16( st_fx->last_coder_type, UNVOICED ) && LE_16( st_fx->nbLostCmpt, 3 ) )
289 : {
290 : /* last good frame was clearly unvoiced */
291 280 : alpha = _ALPHA_UU_FX;
292 280 : move16();
293 : }
294 5582 : ELSE IF( EQ_16( st_fx->last_coder_type, AUDIO ) || EQ_16( st_fx->last_good, INACTIVE_CLAS ) )
295 : {
296 126 : test();
297 126 : IF( hGSCDec->Last_GSC_pit_band_idx > 0 && GT_16( st_fx->nbLostCmpt, 1 ) )
298 : {
299 16 : alpha = 26214;
300 16 : move16();
301 : }
302 110 : ELSE IF( LE_16( st_fx->nbLostCmpt, 5 ) )
303 : {
304 110 : alpha = 32604;
305 110 : move16();
306 : }
307 : ELSE
308 : {
309 0 : alpha = 31130;
310 0 : move16();
311 : }
312 : }
313 5456 : ELSE IF( EQ_16( st_fx->last_good, UNVOICED_CLAS ) )
314 : {
315 948 : IF( LE_16( st_fx->nbLostCmpt, 1 ) )
316 : {
317 : /* if stable, do not decrease the energy, pitch_gain = 0 */
318 : #ifdef ISSUE_1866_replace_overflow_libdec
319 782 : alpha = mac_r_sat( ( 1L << 16 ) * 2 * _ALPHA_U_FX, st_fx->stab_fac_fx, 32768 - 2 * _ALPHA_U_FX ); /*st_fx->stab_fac_fx in Q15*/
320 : #else
321 : 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*/
322 : #endif
323 : }
324 166 : ELSE IF( EQ_16( st_fx->nbLostCmpt, 2 ) )
325 : {
326 160 : alpha = _ALPHA_S_FX;
327 160 : move16(); /* ALPHA_U*1.5f = 0.6 */
328 : }
329 : ELSE
330 : {
331 6 : alpha = _ALPHA_U_FX;
332 6 : move16(); /* 0.4 go rapidly to CNG gain, pitch gain = 0 */
333 : }
334 : }
335 4508 : ELSE IF( EQ_16( st_fx->last_good, UNVOICED_TRANSITION ) )
336 : {
337 16 : alpha = _ALPHA_UT_FX;
338 16 : move16();
339 : }
340 4492 : 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 ) ) )
341 : {
342 161 : alpha = 26214;
343 161 : move16(); /* mild convergence to 0 for the first 3 erased frames 0.8 in Q15 */
344 : }
345 4331 : ELSE IF( ( EQ_16( st_fx->last_good, VOICED_CLAS ) || EQ_16( st_fx->last_good, ONSET ) ) && LE_16( st_fx->nbLostCmpt, 3 ) )
346 : {
347 2293 : alpha = _ALPHA_V_FX;
348 2293 : move16(); /* constant for the first 3 erased frames */
349 : }
350 2038 : ELSE IF( EQ_16( st_fx->last_good, SIN_ONSET ) )
351 : {
352 12 : alpha = _ALPHA_S_FX;
353 12 : move16();
354 : }
355 5862 : test();
356 5862 : test();
357 5862 : 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 ) )
358 : {
359 2614 : IF( EQ_16( st_fx->nbLostCmpt, 1 ) ) /* if first erased frame in a block, reset harmonic gain */
360 : {
361 : /* move pitch gain towards 1 for voiced to remove energy fluctuations */
362 : /*gain = (float)sqrt( st_fx->lp_gainp );*/
363 1880 : st_fx->lp_gainp_fx = s_max( st_fx->lp_gainp_fx, 1 );
364 1880 : move16();
365 1880 : exp = norm_s( st_fx->lp_gainp_fx );
366 1880 : tmp = shl( st_fx->lp_gainp_fx, exp );
367 1880 : tmp = div_s( 16384, tmp );
368 1880 : L_tmp = L_deposit_h( tmp );
369 1880 : L_tmp = Isqrt_lc( L_tmp, &exp );
370 :
371 : #ifdef ISSUE_1866_replace_overflow_libdec
372 1880 : gain = extract_h( L_shl_sat( L_tmp, exp ) );
373 : #else
374 : gain = extract_h( L_shl_o( L_tmp, exp, &Overflow ) );
375 : #endif
376 :
377 1880 : gain = s_min( gain, 32113 ); /*0.98 */
378 1880 : gain = s_max( gain, 27853 ); /*0.85 */
379 :
380 1880 : alpha = mult_r( alpha, gain );
381 : }
382 : ELSE
383 : {
384 : /* st_fx->lp_gainp_fx is in Q14 when bfi_cnt > 1 to follow floating point because lp_gainp could be > than 1 */
385 734 : alpha = st_fx->lp_gainp_fx;
386 734 : move16();
387 : }
388 : }
389 :
390 : /*-----------------------------------------------------------------*
391 : * construct the harmonic part of excitation
392 : *-----------------------------------------------------------------*/
393 5862 : test();
394 5862 : test();
395 5862 : test();
396 5862 : test();
397 5862 : IF( ( GE_16( st_fx->last_good, UNVOICED_TRANSITION ) && LT_16( st_fx->last_good, INACTIVE_CLAS ) ) ||
398 : ( ( EQ_16( st_fx->last_coder_type, AUDIO ) || EQ_16( st_fx->last_good, INACTIVE_CLAS ) ) && hGSCDec->Last_GSC_pit_band_idx > 0 ) )
399 : {
400 :
401 4660 : pt_exc = exc;
402 4660 : pt1_exc = pt_exc - Tc;
403 :
404 4660 : IF( EQ_16( st_fx->nbLostCmpt, 1 ) )
405 : {
406 : /* first pitch cycle is low-pass filtered */
407 :
408 195538 : FOR( i = 0; i < Tc; i++ ) /* pitch cycle is first low-pass filtered */
409 : {
410 : /* *pt_exc++ = (0.18f * pt1_exc[-1] + 0.64f * pt1_exc[0] + 0.18f * pt1_exc[1]) */
411 193388 : L_tmp = L_mult( 5898, pt1_exc[-1] );
412 193388 : L_tmp = L_mac( L_tmp, 20972, pt1_exc[0] );
413 193388 : *pt_exc++ = mac_r( L_tmp, 5898, pt1_exc[1] );
414 193388 : move16();
415 193388 : pt1_exc++;
416 : }
417 : }
418 :
419 : /* last pitch cycle of the previous frame is repeatedly copied up to an extra subframe */
420 :
421 4660 : tmp = extract_l( ( exc + add( L_frame, L_SUBFR ) ) - pt_exc );
422 1550152 : FOR( i = 0; i < tmp; i++ )
423 : {
424 1545492 : *pt_exc++ = *pt1_exc++;
425 1545492 : move16();
426 : }
427 :
428 4660 : IF( new_pit > 0 )
429 : {
430 : /*calculate conditions for Pulse resynchronization to take place*/
431 3037 : pulseRes_preCalc( &cond1, &cond2, &cond3, new_pit, Tc, L_frame );
432 :
433 3037 : test();
434 3037 : test();
435 3037 : test();
436 3037 : test();
437 3037 : IF( ( cond1 < 0 ) && ( new_pit > 0 ) && ( cond2 != 0 ) && ( cond3 > 0 ) && extrapolationFailed == 0 )
438 : {
439 288 : Copy( exc, exc - add( L_frame, L_SUBFR ), add( L_frame, L_SUBFR ) );
440 288 : 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*/ );
441 : }
442 : }
443 4660 : test();
444 4660 : test();
445 4660 : 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 ) ) )
446 : {
447 : /* start of the frame gain */
448 16 : gain = 0;
449 16 : move16();
450 :
451 : /* end of the frame gain */
452 16 : st_fx->lp_gainp_fx = 0;
453 16 : move16();
454 16 : step = 0;
455 16 : move16();
456 : }
457 : ELSE
458 : {
459 :
460 : /* start of the frame gain */
461 4644 : gain = 16384;
462 4644 : move16();
463 :
464 : /* end of the frame gain */
465 4644 : test();
466 4644 : test();
467 4644 : test();
468 4644 : 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 ) ) )
469 : {
470 3910 : st_fx->lp_gainp_fx = shr( alpha, 1 ); /* alpha in Q15 */
471 : }
472 : ELSE
473 : {
474 734 : st_fx->lp_gainp_fx = alpha;
475 734 : move16(); /* alpha in Q14 */
476 : }
477 :
478 4644 : IF( EQ_16( L_frame, L_FRAME ) )
479 : {
480 784 : step = shr( sub( gain, st_fx->lp_gainp_fx ), 8 );
481 : }
482 : ELSE /*L_frame == L_FRAME16k*/
483 : {
484 : /*step = (1.0f/L_frame) * (gain - st_fx->lp_gainp);*/
485 :
486 3860 : step = shr( mult_r( 26214, sub( gain, st_fx->lp_gainp_fx ) ), 8 ); /*Q14*/
487 : }
488 : }
489 :
490 1445300 : FOR( i = 0; i < L_frame; i++ )
491 : {
492 : /* exc[i] *= gain */
493 1440640 : exc[i] = round_fx( L_shl( L_mult( exc[i], gain ), 1 ) ); /* in Q_exc */
494 1440640 : move16();
495 : /* gain -= step */
496 1440640 : gain = sub( gain, step );
497 : }
498 4660 : test();
499 4660 : test();
500 4660 : IF( ( EQ_16( st_fx->last_coder_type, AUDIO ) || EQ_16( st_fx->last_good, INACTIVE_CLAS ) ) && hGSCDec->Last_GSC_pit_band_idx > 0 )
501 : {
502 93 : Diff_len = mfreq_loc_div_25[hGSCDec->Last_GSC_pit_band_idx];
503 93 : move16();
504 :
505 : /* Transform to frequency domain */
506 93 : edct_16fx( exc, exc_dct_in, st_fx->L_frame, 5, st_fx->element_mode );
507 :
508 : /* Reset unvaluable part of the adaptive (pitch) excitation contribution */
509 93 : max_len = sub( st_fx->L_frame, Diff_len );
510 93 : Len = s_min( max_len, 80 );
511 :
512 93 : move16(); /*ptr init*/
513 6895 : FOR( i = 0; i < Len; i++ )
514 : {
515 6802 : exc_dct_in[i + Diff_len] = mult_r( exc_dct_in[i + Diff_len], sm_table_fx[i] );
516 6802 : move16();
517 : }
518 :
519 3672 : FOR( ; i < max_len; i++ )
520 : {
521 3579 : exc_dct_in[i + Diff_len] = 0;
522 3579 : move16();
523 : }
524 93 : Diff_len = add( Diff_len, 1 );
525 : }
526 : } /* end of "if st_fx->last_good >= VOICED_TRANSITION" */
527 :
528 : /*-----------------------------------------------------------------*
529 : * Replicate the last spectrum in case the last good frame was coded by GSC
530 : *-----------------------------------------------------------------*/
531 5862 : test();
532 5862 : test();
533 5862 : test();
534 5862 : 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 ) )
535 : {
536 204 : st_fx->GSC_noisy_speech = st_fx->Last_GSC_noisy_speech_flag;
537 204 : move16();
538 : /* st_fx->L_frame / L_SUBFR */
539 204 : tmp = shr( st_fx->L_frame, 6 );
540 :
541 : /* Replication of the last spectrum, with a slight downscaling of its dynamic */
542 204 : 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 );
543 :
544 204 : *tmp_noise = shr_r( st_fx->lp_gainc_fx, 3 ); /*Q0*/
545 204 : move16();
546 : /* Transform back to time domain */
547 204 : edct_16fx( exc_dct_in, exc, st_fx->L_frame, 5, st_fx->element_mode );
548 : }
549 : ELSE
550 : {
551 : /*-----------------------------------------------------------------*
552 : * Construct the random part of excitation
553 : *-----------------------------------------------------------------*/
554 :
555 : /* generate the random part of the excitation */
556 1765506 : FOR( i = 0; i < L_frame + MODE1_L_FIR_FER - 1; i++ )
557 : {
558 : /*Q-3*/
559 1759848 : exc2_buf[i] = shr( Random( &st_fx->seed ), 3 );
560 1759848 : move16();
561 : }
562 :
563 : /* start of the frame gain */
564 5658 : gain = st_fx->lp_gainc_fx;
565 5658 : move16();
566 :
567 5658 : test();
568 5658 : test();
569 5658 : test();
570 5658 : 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 ) ) )
571 : {
572 : /* Here alpha is in Q15 and lp_gainc_fx in Q3 */
573 : /* st_fx->lp_gainc = alpha * st_fx->lp_gainc + (1.0f - alpha) * gainCNG; */
574 4924 : L_tmp = L_mult( alpha, st_fx->lp_gainc_fx );
575 :
576 4924 : st_fx->lp_gainc_fx = msu_r( L_tmp, add( alpha, -32768 ), gainCNG );
577 4924 : move16();
578 : }
579 : ELSE
580 : { /* Here alpha is in Q14, but lp_gainc still in Q3 */
581 : /* st_fx->lp_gainc = alpha * st_fx->lp_gainc + (1.0f - alpha) * gainCNG; */
582 734 : L_tmp = L_mult( alpha, st_fx->lp_gainc_fx ); /* Q14*Q3->Q18 */
583 :
584 734 : st_fx->lp_gainc_fx = round_fx( L_shl( L_msu( L_tmp, add( alpha, -16384 ), gainCNG ), 1 ) ); /* (Q14*Q3<<1)>>16 ->Q3 */
585 734 : move16();
586 : }
587 :
588 5658 : test();
589 5658 : test();
590 5658 : test();
591 5658 : 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 )
592 : {
593 2 : st_fx->lp_gainc_fx = gainCNG;
594 2 : move16();
595 : }
596 :
597 : /* linearly attenuate the gain throughout the frame */
598 : /* step = (1.0f/L_FRAME) * (gain - *lp_gainc); */
599 5658 : step = sub( gain, st_fx->lp_gainc_fx ); /* divide by L_FRAME done later */
600 5658 : test();
601 5658 : IF( EQ_16( L_frame, L_FRAME16k ) )
602 : {
603 4512 : step = mult_r( step, 26214 ); /* L_frame16k-> L_frame and division by L_frame done later*/
604 : }
605 :
606 : /* calculate gain to normalize energy */
607 5658 : pt_exc = exc2_buf + MODE1_L_FIR_FER / 2;
608 5658 : move16();
609 :
610 : /* To avoid saturation split the L_frame dot product into (L_frame/L_SUBFR) dot products
611 : and scale down before adding */
612 : /* gain_inov = 1.0f / (float)sqrt( dotp( pt_exc, pt_exc, L_frame ) / L_frame + 0.01f ); */
613 :
614 5658 : L_tmp = L_deposit_l( 0 );
615 16974 : FOR( i = 0; i < 2; i++ )
616 : {
617 11316 : L_tmp2 = L_mult0( *pt_exc, *pt_exc );
618 11316 : pt_exc++;
619 1737216 : FOR( j = 1; j < shr( L_frame, 1 ); j++ )
620 : {
621 1725900 : L_tmp2 = L_mac0( L_tmp2, *pt_exc, *pt_exc ); /* Q-5 */
622 1725900 : pt_exc++;
623 : }
624 11316 : L_tmp = L_add( L_tmp, L_shr( L_tmp2, 1 ) ); /* Q-7 */
625 : }
626 5658 : test();
627 5658 : IF( EQ_16( L_frame, L_FRAME16k ) )
628 : {
629 4512 : L_tmp = Mult_32_16( L_tmp, 26214 ); /* x0.8 to normalize to 256 samples */
630 : }
631 5658 : exp = norm_l( L_tmp );
632 5658 : L_tmp = L_shl( L_tmp, exp ); /* Normalize */
633 5658 : exp = add( exp, 8 - 7 ); /* Q0, 8 ->divide by 256 */
634 5658 : exp = sub( 31, exp ); /* For Denormalization in Q31 */
635 5658 : L_tmp = Isqrt_lc( L_tmp, &exp ); /* in Q(31-exp) */
636 5658 : gain_inov = round_fx( L_tmp );
637 :
638 : /* attenuate somewhat on unstable unvoiced */
639 5658 : test();
640 5658 : test();
641 5658 : 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 ) )
642 : {
643 952 : gain_inov = mult_r( gain_inov, 26214 );
644 : }
645 :
646 : /* scaling of the random part of excitation */
647 5658 : pt_exc = exc2_buf;
648 5658 : move16();
649 5658 : L_step = L_shr( L_mult( gain_inov, step ), 8 ); /* here is the divide by L_FRAME */
650 5658 : L_tmp2 = L_mult( gain_inov, gain ); /* Q15 * Q3 -> Q3 */
651 5658 : tmp = round_fx( L_tmp2 );
652 5658 : exp = add( add( exp, *Q_exc ), 15 ); /* 3+Q_exc+15 -> Q_exc+18 */
653 :
654 16974 : FOR( i = 0; i < MODE1_L_FIR_FER / 2; i++ )
655 : {
656 : /* non-causal ringing of the FIR filter */
657 : /**pt_exc++ *= (gain_inov * gain);*/
658 11316 : L_tmp = L_mult( tmp, *pt_exc ); /* Q_exc+18 * Q-3 -> Q_exc+16 */
659 11316 : *pt_exc++ = round_fx_sat( L_shl_sat( L_tmp, exp ) );
660 11316 : move16();
661 : }
662 :
663 1742874 : FOR( i = 0; i < L_frame; i++ )
664 : {
665 : /* the inner part of the FIR filter */
666 : /* *pt_exc++ *= (gain_inov * gain); */
667 1737216 : L_tmp = L_mult( tmp, *pt_exc );
668 1737216 : *pt_exc++ = round_fx_sat( L_shl_sat( L_tmp, exp ) );
669 1737216 : move16();
670 : /* gain -= step; */
671 1737216 : L_tmp2 = L_sub( L_tmp2, L_step );
672 1737216 : tmp = round_fx( L_tmp2 );
673 : }
674 :
675 16974 : FOR( i = 0; i < MODE1_L_FIR_FER / 2; i++ ) /* causal ringing of the FIR filter */
676 : {
677 : /* *pt_exc++ *= (gain_inov * gain) */
678 11316 : L_tmp = L_mult( tmp, *pt_exc );
679 11316 : *pt_exc++ = round_fx_sat( L_shl_sat( L_tmp, exp ) );
680 11316 : move16();
681 : }
682 : }
683 :
684 : /*-----------------------------------------------------------------*
685 : * Total excitation
686 : *-----------------------------------------------------------------*/
687 5862 : test();
688 5862 : test();
689 5862 : test();
690 5862 : test();
691 5862 : 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 ) )
692 : {
693 : /* For GSC - the excitation is already computed */
694 204 : Copy( exc, exc2, st_fx->L_frame );
695 : }
696 5658 : ELSE IF( GE_16( st_fx->last_good, UNVOICED_TRANSITION ) && LT_16( st_fx->last_good, INACTIVE_CLAS ) )
697 : {
698 : /* For voiced and generic signals - prepare a HP filter for the random part of excitation */
699 : /* tmp = -(1-tilt_code) to correctly represent 1.0000 */
700 4558 : tmp = add( st_fx->tilt_code_fx, -32768 );
701 27348 : FOR( i = 0; i < MODE1_L_FIR_FER; i++ )
702 : {
703 22790 : hp_filt[i] = msu_r( 0, tmp, h_high_fx[i] );
704 22790 : move16();
705 : }
706 :
707 : /* HP filter the random part of the excitation and add the adaptive part */
708 4558 : pt_exc = exc2_buf;
709 1419086 : FOR( i = 0; i < L_frame; i++ )
710 : {
711 : /* exc2[i] = exc[i] + dotp( &exc2_buf[i], hp_filt, MODE1_L_FIR_FER );*/
712 1414528 : L_tmp = L_mult( hp_filt[0], pt_exc[0] );
713 7072640 : FOR( j = 1; j < MODE1_L_FIR_FER; j++ )
714 : {
715 5658112 : L_tmp = L_mac_sat( L_tmp, hp_filt[j], pt_exc[j] );
716 : }
717 1414528 : exc2[i] = msu_r_sat( L_tmp, -32768, exc[i] );
718 1414528 : move16();
719 1414528 : pt_exc++;
720 : }
721 : }
722 : ELSE
723 : {
724 : /* For purely unvoiced signals - just copy the unfiltered random part of the excitation */
725 1100 : Copy( exc2_buf + MODE1_L_FIR_FER / 2, exc, L_frame );
726 1100 : Copy( exc2_buf + MODE1_L_FIR_FER / 2, exc2, L_frame );
727 : }
728 5862 : IF( st_fx->hBWE_TD != NULL )
729 : {
730 5862 : IF( EQ_16( L_frame, L_FRAME ) )
731 : {
732 1346 : interp_code_5over2_fx( exc, bwe_exc, L_frame );
733 : }
734 : ELSE
735 : {
736 4516 : interp_code_4over2_fx( exc, bwe_exc, L_frame );
737 : }
738 : }
739 5862 : test();
740 5862 : IF( EQ_16( st_fx->last_coder_type, AUDIO ) || EQ_16( st_fx->last_good, INACTIVE_CLAS ) )
741 : {
742 208 : IF( EQ_16( st_fx->L_frame, L_FRAME ) )
743 : {
744 200 : set16_fx( voice_factors, 32767, NB_SUBFR );
745 : }
746 : ELSE
747 : {
748 8 : set16_fx( voice_factors, 32767, NB_SUBFR16k );
749 : }
750 : }
751 : ELSE
752 : {
753 5654 : IF( EQ_16( st_fx->L_frame, L_FRAME ) )
754 : {
755 1146 : set16_fx( voice_factors, st_fx->last_voice_factor_fx, NB_SUBFR ); /* The factor of the last subframe is propagated forward */
756 : }
757 : ELSE
758 : {
759 4508 : set16_fx( voice_factors, st_fx->last_voice_factor_fx, NB_SUBFR16k ); /* The factor of the last subframe is propagated forward */
760 : }
761 : }
762 5862 : IF( st_fx->Opt_AMR_WB )
763 : {
764 0 : gain_dec_bfi_fx( hAmrwb_IO->past_qua_en_fx );
765 : }
766 : /* L_frame / L_SUBFR */
767 5862 : tmp = shr( L_frame, 6 );
768 5862 : st_fx->bfi_pitch_fx = pitch_buf[tmp - 1];
769 5862 : move16();
770 5862 : st_fx->bfi_pitch_frame = st_fx->L_frame;
771 5862 : move16();
772 5862 : return;
773 : }
774 :
775 :
776 : /*calculates some conditions for Pulse resynchronization to take place*/
777 8899 : static void pulseRes_preCalc( Word16 *cond1, Word16 *cond2, Word32 *cond3, Word16 new_pit, Word16 Tc, Word16 L_frame )
778 : {
779 : Word16 tmp_pit, tmp_pit_e, tmp_frame, tmp_frame_e;
780 : Word32 tmp_pit2;
781 : #ifndef ISSUE_1866_replace_overflow_libdec
782 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
783 : Flag Overflow = 0;
784 : move32();
785 : #endif
786 : #endif
787 :
788 8899 : tmp_pit = BASOP_Util_Divide1616_Scale( new_pit /*Q0*/, Tc /*Q0*/, &tmp_pit_e ) /*Q15*/;
789 8899 : tmp_frame = add( extract_l( L_mult0( L_frame, 64 /*1.f/L_SUBFR Q12*/ ) /*Q12*/ ), 4096 /*1.f Q12*/ ); /*Q12*/
790 8899 : tmp_frame = BASOP_Util_Divide1616_Scale( 4096 /*1.f Q12*/, tmp_frame, &tmp_frame_e ); /*Q15*/
791 8899 : tmp_frame = shl( tmp_frame, add( tmp_frame_e, 1 ) );
792 8899 : tmp_frame = sub( 32767 /*1.f Q15*/, tmp_frame ); /*Q15*/
793 : BASOP_SATURATE_WARNING_OFF_EVS
794 : /*To calc Q15 threshold, overflow may happen - do negation and compare with negated value to check also highest possible value*/
795 : #ifdef ISSUE_1866_replace_overflow_libdec
796 8899 : tmp_pit = shl_sat( negate( tmp_pit ), tmp_pit_e );
797 : #else
798 : tmp_pit = shl_o( negate( tmp_pit ), tmp_pit_e, &Overflow );
799 : #endif
800 : BASOP_SATURATE_WARNING_ON_EVS
801 8899 : *cond1 = sub( tmp_pit, negate( tmp_frame ) );
802 8899 : move16();
803 :
804 8899 : *cond2 = sub( Tc, new_pit );
805 8899 : move16();
806 :
807 8899 : tmp_pit_e = BASOP_Util_Add_MantExp( new_pit, 15 - 0, negate( Tc ), 15 - 0, &tmp_pit ); /*Q15*/
808 8899 : tmp_pit = abs_s( tmp_pit );
809 8899 : tmp_pit2 = L_mult( Tc, 4915 /*0.15f Q15*/ ); /*Q16*/
810 : BASOP_SATURATE_WARNING_OFF_EVS
811 : /*To calc Q15 threshold, overflow may happen - do negation and compare with negated value to check also highest possible value*/
812 8899 : tmp_pit2 = L_shl_sat( L_negate( tmp_pit2 ), sub( 15 - 16, tmp_pit_e ) );
813 : BASOP_SATURATE_WARNING_ON_EVS
814 8899 : *cond3 = L_sub( L_mult0( -1, tmp_pit ), tmp_pit2 );
815 8899 : move32();
816 8899 : }
817 :
818 : /*-------------------------------------------------------------------*
819 : * gain_dec_bfi()
820 : *
821 : * Estimate past quantized gain prediction residual to be used in
822 : * next frame
823 : *-------------------------------------------------------------------*/
824 :
825 0 : void gain_dec_bfi_fx(
826 : Word16 *past_qua_en /* i/o: gain quantization memory (4 words) Qx*/
827 : )
828 : {
829 : Word16 i;
830 : Word16 av_pred_en;
831 : Word32 Lav_pred_en;
832 :
833 0 : Lav_pred_en = L_mult( past_qua_en[0], 8192 );
834 0 : FOR( i = 1; i < GAIN_PRED_ORDER; i++ )
835 : {
836 0 : Lav_pred_en = L_mac( Lav_pred_en, past_qua_en[i], 8192 );
837 : }
838 :
839 : /*av_pred_en = (float)(av_pred_en*(1.0f/(float)GAIN_PRED_ORDER)-3.0f);*/
840 0 : av_pred_en = sub( round_fx( Lav_pred_en ), 3 << 10 );
841 :
842 : /*if (av_pred_en < -14.0f)av_pred_en = -14.0f;*/
843 0 : av_pred_en = s_max( av_pred_en, -14 * ( 1 << 10 ) );
844 :
845 :
846 0 : FOR( i = GAIN_PRED_ORDER - 1; i > 0; i-- )
847 : {
848 0 : past_qua_en[i] = past_qua_en[i - 1];
849 0 : move16();
850 : }
851 :
852 0 : past_qua_en[0] = av_pred_en;
853 0 : move16();
854 :
855 0 : return;
856 : }
|