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