Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 :
6 : #include <assert.h>
7 : #include <stdint.h>
8 : #include "options.h"
9 : #include "prot_fx.h"
10 : #include "basop_util.h"
11 : #include "rom_dec.h"
12 :
13 : /*****************************************************
14 : calcGainc calculates st->lp_gainc
15 : ******************************************************/
16 2247 : static void calcGainc_fx( Word16 *exc, Word16 Q_exc, Word32 old_fpitch /*Q16*/, Word16 L_subfr /*Q0*/, Word32 lp_gainp /*Q16*/, Word32 *lp_gainc /*Q16*/ )
17 : {
18 : Word32 L_c;
19 : Word16 tmp16, tmp16_2, tmp16_3, tmp_e, tmp2_e, tmp_loop, i;
20 : Word32 L_acc, L_tmp;
21 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
22 2247 : Flag Overflow = 0;
23 2247 : Flag Carry = 0;
24 2247 : move32();
25 2247 : move32();
26 : #endif
27 :
28 :
29 2247 : L_acc = L_deposit_l( 0 );
30 2247 : L_c = L_deposit_l( 0 );
31 2247 : Overflow = 0;
32 2247 : move16();
33 2247 : Carry = 0;
34 2247 : move16();
35 :
36 2247 : tmp16 = round_fx( old_fpitch ); /*Q0*/
37 2247 : tmp_loop = shl( L_subfr, 1 );
38 : BASOP_SATURATE_WARNING_OFF_EVS
39 2247 : tmp16_2 = round_fx_o( L_shl_o( lp_gainp, 2, &Overflow ), &Overflow ); /*Q31->Q15, no severe saturation, because st->lp_gainp here is [0,1]*/
40 : BASOP_SATURATE_WARNING_ON_EVS
41 :
42 721703 : FOR( i = 0; i < tmp_loop; i++ )
43 : {
44 : /*st->lp_gainc += ( exc[i-2*L_subfr] - st->Mode2_lp_gainp * exc[i-2*L_subfr-(int)(st->old_fpitch+0.5f)] ) *
45 : ( exc[i-2*L_subfr] - st->Mode2_lp_gainp * exc[i-2*L_subfr-(int)(st->old_fpitch+0.5f)] );*/
46 719456 : tmp16_3 = sub_o( exc[( i - ( L_subfr * 2 ) )] /*Q1*/, mult_r( tmp16_2 /*Q15*/, exc[( ( i - ( L_subfr * 2 ) ) - tmp16 )] /*Q1*/ ) /*Q1*/, &Overflow );
47 719456 : L_acc = L_macNs_co( L_acc, tmp16_3, tmp16_3, &Carry, &Overflow ); /*Q3*/
48 719456 : Overflow = 0;
49 719456 : move16();
50 719456 : L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow ); /*Accumulate Carrys Q-1*/
51 719456 : Carry = 0;
52 719456 : move16();
53 : }
54 2247 : L_tmp = norm_llQ31( L_c, L_acc, &tmp_e ); /*Q3,norm,tmp_e*/
55 2247 : tmp_e = add( tmp_e, 31 - ( add( shl( Q_exc, 1 ), 1 ) ) ); /*L_tmp is Q31, now*/
56 2247 : tmp16 = BASOP_Util_Divide3216_Scale( L_tmp /*Q31,norm,tmp_e*/, shl( L_subfr, 1 ) /*Q15,15*/, &tmp2_e ) /*Q15,tmp2_e+tmp_e-15*/;
57 2247 : tmp_e = sub( add( tmp2_e, tmp_e ), 15 );
58 :
59 2247 : IF( tmp16 != 0 )
60 : {
61 2247 : tmp16 = Sqrt16( tmp16, &tmp_e ); /*Q15,norm,tmp_e*/
62 : }
63 2247 : *lp_gainc = L_shl( L_deposit_l( tmp16 ), add( tmp_e, 1 ) ); /*15Q16*/
64 2247 : move32();
65 2247 : }
66 :
67 0 : static void calcGainc2_fx( Word16 *exc, Word16 Q_exc, Word16 L_subfr /*Q0*/, Word32 *lp_gainc /*Q16*/ )
68 : {
69 : Word16 i, cnt, tmp16, tmp_e, tmp2_e;
70 : Word32 L_c, L_acc, L_tmp;
71 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
72 0 : Flag Overflow = 0;
73 0 : Flag Carry = 0;
74 : #endif
75 0 : move16();
76 0 : move16();
77 :
78 :
79 0 : Carry = 0;
80 0 : move16();
81 0 : Overflow = 0;
82 0 : move16();
83 :
84 0 : L_c = L_deposit_l( 0 );
85 0 : L_acc = L_deposit_l( 0 );
86 :
87 0 : cnt = shl( L_subfr, 1 );
88 :
89 0 : FOR( i = 0; i < cnt; i++ )
90 : {
91 : /* *gainc += ( exc[i-2*L_subfr] ) * ( exc[i-2*L_subfr]); */
92 0 : L_acc = L_macNs_co( L_acc, exc[( i - ( L_subfr * 2 ) )] /*Q1*/, exc[( i - ( L_subfr * 2 ) )] /*Q1*/, &Carry, &Overflow ); /*Q3*/
93 0 : Overflow = 0;
94 0 : move16();
95 0 : L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow ); /* Accumulate Carrys Q-1*/
96 0 : Carry = 0;
97 0 : move16();
98 : }
99 :
100 0 : L_tmp = norm_llQ31( L_c, L_acc, &tmp_e ); /*Q3,norm,tmp_e*/
101 0 : tmp_e = add( tmp_e, sub( 31, ( add( shl( Q_exc, 1 ), 1 ) ) ) ); /*L_tmp is Q31, now*/
102 0 : tmp16 = BASOP_Util_Divide3216_Scale( L_tmp /*Q31,norm,tmp_e*/, shl( L_subfr, 1 ) /*Q15,15*/, &tmp2_e ) /*Q15,tmp2_e+tmp_e-15*/;
103 0 : tmp_e = sub( add( tmp2_e, tmp_e ), 15 );
104 :
105 0 : IF( tmp16 != 0 )
106 : {
107 0 : tmp16 = Sqrt16( tmp16, &tmp_e ); /*Q15,norm,tmp_e*/
108 : }
109 0 : *lp_gainc = L_shl( L_deposit_l( tmp16 ), add( tmp_e, 1 ) ); /*15Q16*/
110 0 : move32();
111 0 : }
112 :
113 : /******************************************************
114 :
115 : con_tcx
116 :
117 : \brief main function in time domain TCX concealment
118 :
119 : *******************************************************/
120 :
121 1088 : void con_tcx_fx(
122 : Decoder_State *st, /* i/o: coder memory state */
123 : Word16 synth[] /* i/o: synth[] Q0*/
124 : #ifdef IVAS_CODE_CON_TCX
125 : ,
126 : const Word16 coh, /* i : coherence of stereo signal Q14*/
127 : Word16 *noise_seed, /* i/o: noise seed for stereo Q0*/
128 : const Word16 only_left /* i : TD-PLC only in left channel Q0*/
129 : #endif
130 :
131 : )
132 : {
133 : Word16 i, s, c, L_frame, L_subfr, fLowPassFilter, T0;
134 : Word16 n, mem_syn_r_size_old, mem_syn_r_size_new;
135 : Word16 *noise;
136 : Word16 mem_syn[M], *syn;
137 : Word16 *exc, buf[OLD_EXC_SIZE_DEC + L_FRAME_MAX + L_FRAME_MAX / NB_SUBFR + 1 + L_FRAME_MAX / 2];
138 : Word16 pre_emph_buf;
139 : Word16 hp_filt[L_FIR_FER2];
140 : Word16 alpha;
141 : Word16 tmp_deemph, gain, gainCNG, gain_inov;
142 : Word16 *pt_exc, *pt1_exc;
143 : Word16 Tc, tmpSeed;
144 : Word16 fUseExtrapolatedPitch;
145 : Word16 *ana_window;
146 : Word16 r_h[M + 1], A_local[M + 1], mem, r_l[M + 1];
147 : PWord16 const *w;
148 : Word16 W1, W2, W12;
149 : Word16 Q_r;
150 : Word16 tmp16, tmp16_2, tmp_loop, tmp_e, gain_tmp;
151 : Word16 gainCNG_e, noise_e, gain_inov_e; /*Exponents for gainCNG, noise, gain_inov*/
152 : Word16 Q_syn; /*Q format of temporary synthesis buffer syn*/
153 : Word32 L_tmp, L_tmp2, step32_tmp;
154 : Word32 predPitchLag, pitch_buf[NB_SUBFR16k], step32, gain32;
155 : Word16 extrapolationFailed;
156 : Word16 gainSynthDeemph;
157 : Word16 gainSynthDeemph_e;
158 : Word32 old_pitch_buf[2 * NB_SUBFR16k + 2];
159 : Word16 Q_exc, new_Q, exp_scale;
160 : Word16 offset;
161 : HQ_DEC_HANDLE hHQ_core;
162 : TCX_LTP_DEC_HANDLE hTcxLtpDec;
163 : TCX_DEC_HANDLE hTcxDec;
164 :
165 1088 : hTcxLtpDec = st->hTcxLtpDec;
166 1088 : hHQ_core = st->hHQ_core;
167 1088 : hTcxDec = st->hTcxDec;
168 :
169 : /* inits */
170 1088 : alpha = 0;
171 1088 : move16();
172 1088 : fUseExtrapolatedPitch = 0;
173 1088 : move16();
174 1088 : extrapolationFailed = 1;
175 1088 : move16();
176 :
177 1088 : noise_e = 0;
178 1088 : move16();
179 1088 : Q_syn = -1; /*Q format of temporary synthesis buffer syn*/
180 1088 : move16();
181 1088 : offset = 0;
182 1088 : move16();
183 :
184 : /* Framing parameters */
185 1088 : L_frame = hTcxDec->L_frameTCX; /*Q0*/
186 1088 : move16();
187 : /* L_subfr = st->L_frameTCX/st->nb_subfr */
188 1088 : L_subfr = mult_r( hTcxDec->L_frameTCX, div_s( 1, st->nb_subfr ) ); /*Q0*/
189 1088 : assert( L_subfr == hTcxDec->L_frameTCX / st->nb_subfr );
190 1088 : move32();
191 1088 : w = st->hTcxCfg->tcx_mdct_windowFB; /*pointer - no need to instrument Q15*/
192 1088 : W1 = st->hTcxCfg->tcx_mdct_window_lengthFB;
193 1088 : move16();
194 1088 : W2 = shr( st->hTcxCfg->tcx_mdct_window_lengthFB, 1 );
195 1088 : W12 = shr( W1, 1 );
196 :
197 : /* take the previous frame last pitch */
198 1088 : Tc = round_fx( st->old_fpitchFB ); /*Q0*/
199 :
200 :
201 1088 : set16_fx( buf, 0, OLD_EXC_SIZE_DEC + L_FRAME_MAX + L_FRAME_MAX / NB_SUBFR + 1 + L_FRAME_MAX / 2 ); /* initialize buf with 0 */
202 : // set16_fx(buf,0,shr(sizeof(buf),1)); /* initialize buf with 0 */
203 :
204 1088 : c = BASOP_Util_Divide1616_Scale(
205 : L_frame,
206 1088 : st->L_frame,
207 : &s );
208 :
209 14144 : FOR( i = 0; i < 2 * NB_SUBFR16k + 2; i++ )
210 : {
211 13056 : old_pitch_buf[i] = L_shl( Mpy_32_16_1( st->old_pitch_buf_fx[i], c ), s ); /*Q16*/
212 13056 : move32();
213 : }
214 :
215 : /* set excitation memory*/
216 1088 : exc = buf + OLD_EXC_SIZE_DEC; /*Q_exc*/
217 1088 : tmp_deemph = synth[-1]; /*Q0*/
218 1088 : move16();
219 1088 : pre_emph_buf = synth[-1]; /*Q0*/
220 1088 : move16();
221 :
222 1088 : test();
223 1088 : IF( ( EQ_16( st->nbLostCmpt, 1 ) ) || hTcxDec->tcxConceal_recalc_exc )
224 : {
225 : /* apply pre-emphasis to the signal */
226 732 : mem = synth[( -( ( ( ( L_frame / 2 ) + hTcxDec->pit_max_TCX ) + M + M ) ) - 1 )]; /*Q0*/
227 732 : move16();
228 732 : Q_exc = E_UTIL_f_preemph3( &( synth[-( ( ( L_frame / 2 ) + hTcxDec->pit_max_TCX ) + 2 * M )] ), st->preemph_fac, add( add( shr( L_frame, 1 ), hTcxDec->pit_max_TCX ), shl( M, 1 ) ), &mem, 1 );
229 732 : st->Mode2_lp_gainc = L_deposit_l( 0 );
230 :
231 732 : st->Mode2_lp_gainp = get_gain2( synth - shl( L_subfr, 1 ), synth - add( shl( L_subfr, 1 ), Tc ), shl( L_subfr, 1 ) ); /*Q16*/
232 :
233 732 : st->Mode2_lp_gainp = L_max( st->Mode2_lp_gainp, 0 ); /*Q16*/
234 732 : st->Mode2_lp_gainp = L_min( st->Mode2_lp_gainp, 65536l /*1.0f Q16*/ ); /*Q16*/
235 732 : st->Mode2_lp_gainp = L_shl( st->Mode2_lp_gainp, 13 ); /*Q29*/
236 :
237 732 : ana_window = buf; /*Q15*/
238 732 : ham_cos_window( ana_window, mult( L_frame, 24576 /*0.75f Q15*/ ), shr( L_frame, 2 ) );
239 :
240 : /* Autocorrelation */
241 732 : autocorr_fx( &( synth[( -L_frame - 1 )] ), M, r_h, r_l, &Q_r, L_frame, ana_window, 0, 0 );
242 :
243 : /* Lag windowing */
244 732 : lag_wind( r_h, r_l, M, st->output_Fs, LAGW_STRONG );
245 :
246 : /* Levinson Durbin */
247 732 : E_LPC_lev_dur( r_h, r_l, A_local, NULL, M, NULL );
248 :
249 : /* copy for multiple frame loss */
250 732 : Copy( A_local, st->old_Aq_12_8_fx, M + 1 ); /*Q12*/
251 :
252 : /* Residu */
253 732 : assert( ( 2 * L_subfr + Tc + 1 + M ) <= hTcxDec->old_synth_lenFB );
254 :
255 : BASOP_SATURATE_WARNING_OFF_EVS /*saturation possible in case of spiky synthesis*/
256 2196 : Residu3_fx(
257 : A_local,
258 732 : &( synth[-( ( add( ( L_subfr * 2 ), Tc ) + 1 ) + M )] ), /*Qx = Q0*/
259 732 : &( exc[-( ( add( ( L_subfr * 2 ), Tc ) + 1 ) + M )] ), /*Qx+1 = Q1*/
260 732 : add( add( add( shl( L_subfr, 1 ), Tc ), 1 ), M ),
261 : 1 );
262 : BASOP_SATURATE_WARNING_ON_EVS
263 : }
264 : ELSE
265 : {
266 : /* apply pre-emphasis to the signal */
267 356 : mem = synth[( -L_frame - 1 )]; /*Q0*/
268 356 : move16();
269 356 : Q_exc = E_UTIL_f_preemph3( &( synth[-L_frame] ), st->preemph_fac, L_frame, &mem, 1 );
270 356 : Copy( st->old_Aq_12_8_fx, A_local, M + 1 ); /*Q12*/
271 :
272 356 : offset = shr( L_frame, 1 );
273 356 : IF( GE_16( st->last_good, UNVOICED_TRANSITION ) )
274 : {
275 356 : tmp16 = s_max( sub( Tc, shr( L_frame, 1 ) ), 0 );
276 356 : Copy_Scale_sig( hTcxDec->old_excFB_fx, &( exc[-tmp16] ), add( offset, tmp16 ), sub( Q_exc, st->Q_exc ) ); /*Q_exc*/
277 : }
278 : ELSE
279 : {
280 0 : Copy_Scale_sig( hTcxDec->old_excFB_fx, &( exc[-( L_subfr * 2 )] ), add( shl( L_subfr, 1 ), offset ), sub( Q_exc, st->Q_exc ) ); /*Q_exc*/
281 : }
282 : }
283 :
284 : /*-----------------------------------------------------------------*
285 : * PLC: Construct the harmonic part of excitation
286 : *-----------------------------------------------------------------*/
287 :
288 1088 : test();
289 1088 : test();
290 1088 : IF( GT_16( st->last_good, UNVOICED_CLAS ) && !( EQ_16( st->last_good, UNVOICED_TRANSITION ) && EQ_16( st->core_ext_mode, GENERIC ) ) )
291 : {
292 1088 : test();
293 1088 : IF( EQ_16( st->nbLostCmpt, 1 ) || hTcxDec->tcxConceal_recalc_exc )
294 : {
295 732 : calcGainc_fx( exc, Q_exc, st->old_fpitchFB, L_subfr, st->Mode2_lp_gainp, &( st->Mode2_lp_gainc ) );
296 : }
297 :
298 1088 : tmp16 = 0;
299 1088 : move16();
300 1088 : if ( GT_32( st->output_Fs, 25600 ) )
301 : {
302 858 : tmp16 = 1;
303 858 : move16();
304 : }
305 :
306 1088 : test();
307 1088 : test();
308 1088 : test();
309 1088 : test();
310 1088 : IF( ( ( EQ_16( st->nbLostCmpt, 1 ) ) || hTcxDec->tcxConceal_recalc_exc ) && GE_16( st->rf_frame_type, RF_TCXFD ) && LE_16( st->rf_frame_type, RF_TCXTD2 ) && st->use_partial_copy )
311 0 : {
312 : Word32 tcxltp_pitch_tmp; /*15Q16*/
313 : Word16 scale_tmp; /*getInvFrameLen()->9Q6*/
314 : Word16 tmp_shift;
315 0 : tcxltp_pitch_tmp = L_add( L_deposit_h( hTcxLtpDec->tcxltp_pitch_int ), L_shl( L_deposit_l( div_s( hTcxLtpDec->tcxltp_pitch_fr, st->pit_res_max ) ), 1 ) ); /*15Q16*/
316 0 : scale_tmp = mult_r( hTcxDec->L_frameTCX, getInvFrameLen( st->L_frame ) ); /*getInvFrameLen()->9Q6*/
317 0 : tmp_shift = norm_s( scale_tmp );
318 0 : predPitchLag = L_shl( Mpy_32_16_1( tcxltp_pitch_tmp, shl( scale_tmp, tmp_shift ) ), sub( 9, tmp_shift ) ); /*Q16*/
319 :
320 0 : T0 = round_fx( predPitchLag ); /*Q0*/
321 :
322 0 : test();
323 0 : test();
324 0 : if ( ( T0 > 0 ) && ( NE_16( T0, Tc ) ) && ( LT_32( L_deposit_h( abs_s( sub( T0, Tc ) ) ) /*Q16*/, L_mult( 4915 /*.15f Q15*/ /*Q15*/, Tc /*Q0*/ ) /*Q16*/ ) ) )
325 : {
326 0 : fUseExtrapolatedPitch = 1;
327 0 : move16();
328 : }
329 : }
330 : ELSE
331 : {
332 1088 : pitch_pred_linear_fit(
333 1088 : st->nbLostCmpt,
334 1088 : st->last_good,
335 : old_pitch_buf,
336 : &( st->old_fpitchFB ),
337 : &predPitchLag,
338 1088 : hTcxDec->pit_min_TCX,
339 1088 : hTcxDec->pit_max_TCX,
340 1088 : st->mem_pitch_gain,
341 : tmp16,
342 1088 : st->plc_use_future_lag,
343 : &extrapolationFailed,
344 1088 : st->nb_subfr );
345 :
346 1088 : T0 = round_fx( predPitchLag ); /*Q0*/
347 1088 : test();
348 1088 : test();
349 1088 : test();
350 1088 : if ( ( T0 > 0 ) && ( NE_16( T0, Tc ) ) && ( LT_32( L_deposit_h( abs_s( sub( T0, Tc ) ) ) /*Q16*/, L_mult( 4915 /*.15f Q15*/ /*Q15*/, Tc /*Q0*/ ) /*Q16*/ ) ) && ( extrapolationFailed == 0 ) )
351 : {
352 259 : fUseExtrapolatedPitch = 1;
353 259 : move16();
354 : }
355 : }
356 :
357 :
358 1088 : fLowPassFilter = 0;
359 1088 : move16();
360 1088 : pt_exc = exc + offset; /*Q_exc*/
361 1088 : pt1_exc = pt_exc - Tc; /*Q_exc*/
362 :
363 1088 : if ( fUseExtrapolatedPitch != 0 )
364 : {
365 259 : pt_exc = buf; /*Q_exc*/
366 : }
367 1088 : test();
368 1088 : IF( LT_16( st->stab_fac_fx, 32767 /*1.f Q15*/ ) && EQ_16( st->nbLostCmpt, 1 ) )
369 : {
370 : /* pitch cycle is first low-pass filtered */
371 :
372 439 : IF( LE_32( st->output_Fs, 16000 ) )
373 : {
374 7830 : FOR( i = 0; i < Tc; i++ )
375 : {
376 7752 : *pt_exc++ = mac_r_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat(
377 7752 : L_mult( 174 /* 0.0053f Q15*/, pt1_exc[-5] ),
378 7752 : 0 /* 0.0000f Q15*/, pt1_exc[-4] ),
379 7752 : -1442 /*-0.0440f Q15*/, pt1_exc[-3] ),
380 7752 : 0 /* 0.0000f Q15*/, pt1_exc[-2] ),
381 7752 : 8641 /* 0.2637f Q15*/, pt1_exc[-1] ),
382 7752 : 18022 /* 0.5500f Q15*/, pt1_exc[0] ),
383 7752 : 8641 /* 0.2637f Q15*/, pt1_exc[1] ),
384 7752 : 0 /* 0.0000f Q15*/, pt1_exc[2] ),
385 7752 : -1442 /*-0.0440f Q15*/, pt1_exc[3] ),
386 7752 : 0 /* 0.0000f Q15*/, pt1_exc[4] ),
387 7752 : 174 /* 0.0053f Q15*/, pt1_exc[5] ); /*Q_exc*/
388 7752 : move16();
389 7752 : pt1_exc++;
390 : }
391 : }
392 : ELSE /*(st->output_Fs >= 32000)*/
393 : {
394 103436 : FOR( i = 0; i < Tc; i++ )
395 : {
396 103075 : *pt_exc++ = mac_r_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat( L_mac_sat(
397 103075 : L_mult( -174 /*-0.0053f Q15*/, pt1_exc[-5] ),
398 103075 : -121 /*-0.0037f Q15*/, pt1_exc[-4] ),
399 103075 : -459 /*-0.0140f Q15*/, pt1_exc[-3] ),
400 103075 : 590 /* 0.0180f Q15*/, pt1_exc[-2] ),
401 103075 : 8743 /* 0.2668f Q15*/, pt1_exc[-1] ),
402 103075 : 16355 /* 0.4991f Q15*/, pt1_exc[0] ),
403 103075 : 8743 /* 0.2668f Q15*/, pt1_exc[1] ),
404 103075 : 590 /* 0.0180f Q15*/, pt1_exc[2] ),
405 103075 : -459 /*-0.0140f Q15*/, pt1_exc[3] ),
406 103075 : -121 /*-0.0037f Q15*/, pt1_exc[4] ),
407 103075 : -174 /*-0.0053f Q15*/, pt1_exc[5] ); /*Q_exc*/
408 103075 : move16();
409 103075 : pt1_exc++;
410 : }
411 : }
412 :
413 439 : fLowPassFilter = 1;
414 439 : move16();
415 : }
416 : ELSE
417 : {
418 : /* copy the first pitch cycle without low-pass filtering */
419 156315 : FOR( i = 0; i < Tc; i++ )
420 : {
421 155666 : *pt_exc++ = *pt1_exc++; /*Q_exc*/
422 155666 : move16();
423 : }
424 649 : fLowPassFilter = 1;
425 649 : move16();
426 : }
427 :
428 1088 : if ( fUseExtrapolatedPitch != 0 )
429 : {
430 259 : pt1_exc = buf; /*Q_exc*/
431 : }
432 1088 : tmp16 = add( sub( L_frame, imult1616( fLowPassFilter, Tc ) ), L_subfr );
433 714883 : FOR( i = 0; i < tmp16; i++ )
434 : {
435 713795 : *pt_exc++ = *pt1_exc++; /*Q_exc*/
436 713795 : move16();
437 : }
438 :
439 1088 : if ( fUseExtrapolatedPitch != 0 )
440 : {
441 259 : get_subframe_pitch( st->nb_subfr,
442 : st->old_fpitch,
443 : /* predPitchLag * L_frame/st->L_frame, */
444 : L_shr( Mpy_32_16_1( predPitchLag /*Q16*/,
445 259 : mult_r( st->L_frame /*Q0*/,
446 259 : getInvFrameLen( L_frame ) /*Q21*/
447 : ) /*Q6*/
448 : ) /*Q7*/,
449 : 7 - 16 ) /*Q16*/,
450 : pitch_buf );
451 :
452 259 : PulseResynchronization_fx( buf, exc, L_frame, st->nb_subfr, st->old_fpitchFB, predPitchLag );
453 : }
454 : ELSE
455 : {
456 829 : set32_fx( pitch_buf, st->old_fpitch, st->nb_subfr ); /*Q16*/
457 : }
458 :
459 1088 : IF( EQ_16( st->nbLostCmpt, 1 ) )
460 : {
461 732 : pt_exc = exc + L_frame;
462 732 : IF( T0 == 0 )
463 : {
464 246 : pt1_exc = pt_exc - Tc;
465 : }
466 : ELSE
467 : {
468 486 : pt1_exc = pt_exc - T0;
469 : }
470 :
471 732 : tmp_loop = shr( L_frame, 1 );
472 284412 : FOR( i = 0; i < tmp_loop; i++ )
473 : {
474 283680 : *pt_exc++ = *pt1_exc++; /*Q_exc*/
475 283680 : move16();
476 : }
477 : }
478 :
479 1088 : if ( fUseExtrapolatedPitch != 0 )
480 : {
481 259 : st->old_fpitchFB = predPitchLag; /*Q16*/
482 259 : move32();
483 : }
484 1088 : st->bpf_gain_param = 0;
485 1088 : move16();
486 :
487 : /* PLC: calculate damping factor */
488 1088 : alpha = Damping_fact_fx( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac_fx, &( st->Mode2_lp_gainp ), 0 ); /*Q14*/
489 1088 : IF( EQ_16( st->nbLostCmpt, 1 ) )
490 : {
491 732 : st->cummulative_damping = 32767 /*1.f Q15*/;
492 732 : move16();
493 : }
494 : ELSE
495 : {
496 356 : st->cummulative_damping = shl_sat( mult_r_sat( st->cummulative_damping /*Q15*/, alpha /*Q14*/ ), 1 ) /*Q15*/;
497 356 : move16();
498 : }
499 :
500 1088 : gain32 = L_add( 2147483647l /*1.f Q31*/, 0 ); /*Q31*/
501 1088 : gain = 32767 /*1.f Q15*/; /*Q15*/
502 1088 : move16();
503 1088 : test();
504 1088 : IF( EQ_16( st->rf_frame_type, RF_TCXTD1 ) && EQ_16( st->use_partial_copy, 1 ) )
505 : {
506 0 : gain32 = 1073741824l /*0.5f Q31*/;
507 0 : move32();
508 0 : gain = 16384 /*0.5f Q15*/;
509 0 : move16();
510 : }
511 :
512 : /*step = (1.0f/(L_frame+(L_frame/2))) * (gain - alpha);*/
513 1088 : tmp16 = shr( imult1616( 3, L_frame ), 1 );
514 1088 : tmp_e = norm_s( tmp16 );
515 1088 : tmp16 = shl( tmp16, tmp_e );
516 1088 : tmp16 = div_s( 16384 /*1.f Q14*/, tmp16 ); /*Q15,1+tmp_e-15*/
517 1088 : tmp16_2 = sub( shr( gain, 1 ), alpha ) /*Q14*/;
518 1088 : step32 = L_shl( L_mult( tmp16, tmp16_2 ) /*Q30, 1+tmp_e-15*/, add( 1 - 14, tmp_e ) ) /*Q31*/;
519 :
520 : /* PLC: Apply fade out */
521 1088 : tmp_loop = shr( imult1616( L_frame, 3 ), 1 );
522 1092128 : FOR( i = offset; i < tmp_loop; i++ )
523 : {
524 1091040 : exc[i] = mult_r( exc[i], round_fx_sat( gain32 ) ) /*Q1*/;
525 1091040 : move16();
526 1091040 : gain32 = L_sub_sat( gain32, step32 ); /*Q31*/
527 : }
528 :
529 : /* update old exc without random part */
530 1088 : offset = s_max( sub( round_fx( st->old_fpitchFB ), shr( L_frame, 1 ) ), 0 ); /*Q0*/
531 1088 : Copy( exc + sub( L_frame, offset ), hTcxDec->old_excFB_fx, add( shr( L_frame, 1 ), offset ) ); /*Q_exc*/
532 : /* copy old_exc as 16kHz for acelp decoding */
533 1088 : IF( EQ_16( st->nbLostCmpt, 1 ) )
534 : {
535 732 : lerp( exc - shr( L_frame, 1 ), st->old_exc_fx, L_EXC_MEM_DEC, add( L_frame, shr( L_frame, 1 ) ) );
536 : }
537 : ELSE
538 : {
539 356 : Copy( st->old_exc_fx + L_FRAME16k, st->old_exc_fx, L_FRAME16k / 2 ); /*Q_exc*/
540 356 : lerp( exc, st->old_exc_fx + L_FRAME16k / 2, L_FRAME16k, L_frame );
541 : }
542 1088 : st->Q_exc = Q_exc;
543 1088 : move16();
544 : }
545 : ELSE
546 : {
547 : /* No harmonic part */
548 0 : set16_fx( &exc[0], 0, add( L_frame, shr( L_frame, 1 ) ) );
549 0 : IF( EQ_16( st->nbLostCmpt, 1 ) )
550 : {
551 0 : calcGainc2_fx( &exc[0], Q_exc, L_subfr, &( st->Mode2_lp_gainc ) );
552 : }
553 0 : set32_fx( pitch_buf, L_deposit_h( L_SUBFR ), st->nb_subfr ); /*Q16*/
554 : /* PLC: calculate damping factor */
555 0 : alpha = Damping_fact_fx( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac_fx, &( st->Mode2_lp_gainp ), 0 ); /*Q14*/
556 : }
557 :
558 : /*-----------------------------------------------------------------*
559 : * Construct the random part of excitation
560 : *-----------------------------------------------------------------*/
561 : #ifdef IVAS_CODE_CON_TCX
562 : if ( coh != -1.f )
563 : {
564 : int16_t tmpSeed1;
565 : float alpha_coh;
566 : float random1, random2;
567 :
568 : tmpSeed1 = *noise_seed;
569 : noise = buf;
570 :
571 : alpha_coh = sqrtf( ( 1 - coh ) / ( 1 + coh ) );
572 : if ( st->idchan == 1 )
573 : {
574 : alpha_coh = -alpha_coh;
575 : }
576 :
577 : for ( i = 0; i < L_frame + L_FIR_FER2 - 1; i++ )
578 : {
579 : random1 = (float) own_random( &tmpSeed1 );
580 : random2 = (float) own_random( &tmpSeed1 );
581 : noise[i] = random1 + alpha_coh * random2;
582 : }
583 :
584 : if ( st->idchan == 1 || only_left )
585 : {
586 : *noise_seed = tmpSeed1;
587 : }
588 :
589 : for ( ; i < L_frame + ( L_frame / 2 ) + 2 * L_FIR_FER2; i++ )
590 : {
591 : random1 = (float) own_random( &tmpSeed1 );
592 : random2 = (float) own_random( &tmpSeed1 );
593 : noise[i] = random1 + alpha_coh * random2;
594 : }
595 : }
596 : else
597 : #endif /*IVAS_CODE_CON_TCX*/
598 : {
599 1088 : tmpSeed = st->seed_acelp;
600 1088 : move16();
601 1088 : noise = buf;
602 1088 : noise_e = 1; /*set exponent of noise to 1*/
603 1088 : move16();
604 :
605 1088 : tmp_loop = add( L_frame, L_FIR_FER2 - 1 );
606 819328 : FOR( i = 0; i < tmp_loop; i++ )
607 : {
608 818240 : Random( &tmpSeed );
609 818240 : noise[i] = shr( tmpSeed, noise_e ); /*Q: -noise_e*/
610 818240 : move16();
611 : }
612 1088 : st->seed_acelp = tmpSeed;
613 1088 : move16();
614 :
615 1088 : tmp_loop = add( add( L_frame, shr( L_frame, 1 ) ), shl( L_FIR_FER2, 1 ) );
616 417824 : FOR( ; i < tmp_loop; i++ )
617 : {
618 416736 : Random( &tmpSeed );
619 416736 : noise[i] = shr( tmpSeed, noise_e ); /*Q: -noise_e*/
620 416736 : move16();
621 : }
622 : }
623 1088 : test();
624 1088 : IF( EQ_16( st->last_good, VOICED_CLAS ) || EQ_16( st->last_good, ONSET ) )
625 : {
626 1052 : tmp16 = 19661 /*0.6f Q15*/;
627 1052 : move16();
628 1052 : if ( LE_32( st->output_Fs, 16000 ) )
629 : {
630 220 : tmp16 = 6554 /*0.2f Q15*/;
631 220 : move16();
632 : }
633 :
634 1052 : mem = noise[0];
635 1052 : move16();
636 1052 : preemph_copy_fx( &noise[1], &noise[1], tmp16, add( add( L_frame, shr( L_frame, 1 ) ), L_FIR_FER2 ), &mem );
637 : }
638 : /* high rate filter tuning */
639 1088 : IF( LE_32( st->output_Fs, 16000 ) )
640 : {
641 2760 : FOR( i = 0; i < L_FIR_FER2; i++ )
642 : {
643 2530 : hp_filt[i] = h_high3_16[i]; /*Q15*/
644 2530 : move16();
645 : }
646 : }
647 : ELSE /*(st->output_Fs==32000)*/
648 : {
649 10296 : FOR( i = 0; i < L_FIR_FER2; i++ )
650 : {
651 9438 : hp_filt[i] = h_high3_32[i]; /*Q15*/
652 9438 : move16();
653 : }
654 : }
655 1088 : IF( EQ_16( st->nbLostCmpt, 1 ) )
656 : {
657 732 : highPassFiltering_fx( st->last_good, add( add( L_frame, shr( L_frame, 1 ) ), L_FIR_FER2 ), noise, hp_filt, L_FIR_FER2 );
658 : }
659 : ELSE
660 : {
661 356 : IF( GT_16( st->last_good, UNVOICED_TRANSITION ) )
662 : {
663 356 : tmp_loop = add( add( L_frame, shr( L_frame, 1 ) ), L_FIR_FER2 );
664 356 : gain_tmp = negate( add( -32768, st->cummulative_damping ) ); /*Q15*/
665 364272 : FOR( i = 0; i < tmp_loop; i++ )
666 : {
667 : Word16 j;
668 363916 : L_tmp2 = 0;
669 363916 : move32();
670 4366992 : FOR( j = 11; j > 0; j-- )
671 : {
672 4003076 : L_tmp2 = L_mac( L_tmp2, noise[( i + sub( L_FIR_FER2, j ) )], hp_filt[( L_FIR_FER2 - j )] );
673 : }
674 363916 : L_tmp2 = Mpy_32_16_1( L_tmp2, st->cummulative_damping /*Q15*/ ); /*Q0, noise_e*/
675 363916 : noise[i] = mac_r( L_tmp2, gain_tmp, noise[i] ); /*Q15, noise_e*/
676 363916 : move16();
677 : }
678 : }
679 : }
680 :
681 : /* PLC: [TCX: Fade-out] retrieve background level */
682 1088 : tmp16 = 32767;
683 1088 : move16();
684 1088 : gainSynthDeemph = getLevelSynDeemph_fx( &( tmp16 ), A_local, M, shr( L_frame, 2 ), st->preemph_fac, 1, &gainSynthDeemph_e ); /*Q5*/
685 1088 : IF( st->tcxonly != 0 )
686 : {
687 : /* gainCNG = st->conCngLevelBackgroundTrace/gainSynthDeemph; */
688 281 : BASOP_Util_Divide_MantExp( hTcxDec->conCngLevelBackgroundTrace,
689 281 : hTcxDec->conCngLevelBackgroundTrace_e,
690 : gainSynthDeemph, gainSynthDeemph_e,
691 : &gainCNG, &gainCNG_e );
692 : }
693 : ELSE
694 : {
695 : /* gainCNG = st->cngTDLevel/gainSynthDeemph; */
696 807 : BASOP_Util_Divide_MantExp( st->cngTDLevel,
697 807 : st->cngTDLevel_e,
698 : gainSynthDeemph, gainSynthDeemph_e,
699 : &gainCNG, &gainCNG_e );
700 : }
701 :
702 1088 : gain32 = L_add( st->Mode2_lp_gainc, 0 ); /* start-of-the-frame gain - Q16*/
703 1088 : test();
704 1088 : if ( EQ_16( st->rf_frame_type, RF_TCXTD1 ) && EQ_16( st->use_partial_copy, 1 ) )
705 : {
706 0 : gain32 = Mpy_32_16_1( gain32, 22938 /*0.7f Q15*/ ); /*Q16*/
707 : }
708 1088 : L_tmp = L_shl_sat( gain32, 1 ); /*Q16*/
709 1088 : IF( GT_32( L_shl( L_deposit_h( gainCNG ), sub( gainCNG_e, 31 - 16 ) /*Q16*/ ), L_tmp ) )
710 : {
711 16 : gainCNG_e = sub( 15 + 1, norm_l( L_tmp ) );
712 16 : gainCNG = extract_l( L_shr( L_tmp, gainCNG_e ) ); /*Q15,gainCNG_e*/
713 16 : gainCNG_e = sub( gainCNG_e, 1 );
714 : }
715 :
716 : /* st->Mode2_lp_gainc = alpha * (st->Mode2_lp_gainc) + (1.0f - alpha) * gainCNG;*/ /* end-of-the-frame gain */
717 :
718 1088 : L_tmp = Mpy_32_16_1( st->Mode2_lp_gainc, alpha ) /*Q15*/;
719 1088 : L_tmp2 = L_mult( sub( 16384 /*1.f Q14*/, alpha ) /*Q14*/, gainCNG /*Q15,gainCNG_e*/ ); /*Q30,gainCNG_e*/
720 1088 : st->Mode2_lp_gainc = BASOP_Util_Add_Mant32Exp( L_tmp, 31 - 15, L_tmp2, add( gainCNG_e, 31 - 30 ), &tmp_e ); /*Q31-tmp_e*/
721 1088 : st->Mode2_lp_gainc = L_shl( st->Mode2_lp_gainc, sub( tmp_e, 31 - 16 ) ); /*Q16*/
722 1088 : move32();
723 1088 : move32();
724 :
725 : /* PLC: [TCX: Fade-out] Linearly attenuate the gain through the frame */
726 : /*step = (1.0f/L_frame) * (gain - (st->Mode2_lp_gainc));*/
727 1088 : L_tmp = L_sub( gain32, st->Mode2_lp_gainc ); /*Q16*/
728 1088 : tmp_e = norm_l( L_tmp );
729 1088 : L_tmp = L_shl( L_tmp, tmp_e ); /*Q16,-tmp_e*/
730 1088 : step32 = Mpy_32_16_1( L_tmp /*Q16,-tmp_e*/, getInvFrameLen( L_frame ) /*W16Q21*/ ); /*Q22,-tmp_e*/
731 1088 : step32 = L_shl( step32, sub( 25 - 22, tmp_e ) ); /*Q25*/
732 :
733 1088 : pt_exc = noise + L_FIR_FER2 / 2;
734 :
735 : /*gain_inov = 1.0f / (float)sqrt( dot_product( pt_exc, pt_exc, L_frame ) / L_frame + 0.01f );*/ /* normalize energy */
736 1088 : L_tmp = Dot_productSq16HQ( 0, pt_exc /*Q0,15+1*/, L_frame, &tmp_e ) /*Q31,tmp_e+16+16*/;
737 1088 : L_tmp = Mpy_32_16_1( L_tmp, getInvFrameLen( L_frame ) /*W16Q21*/ ) /*W32Q37,tmp_e+16+16*/ /*Q5,tmp_e*/;
738 1088 : tmp_e = add( tmp_e, 31 - 5 ); /*-->Q31*/
739 1088 : gain_inov = round_fx( ISqrt32( L_tmp, &tmp_e ) ); /*Q15,tmp_e*/
740 1088 : gain_inov_e = tmp_e;
741 1088 : move16();
742 1088 : test();
743 1088 : test();
744 1088 : IF( EQ_16( st->last_good, UNVOICED_CLAS ) && NE_16( st->core_ext_mode, UNVOICED ) )
745 : {
746 0 : gain_inov = mult_r( gain_inov, 26214 /*0.8f Q15*/ ); /*Q30*/
747 : }
748 1088 : ELSE IF( !( EQ_16( st->last_good, UNVOICED_CLAS ) || EQ_16( st->last_good, UNVOICED_TRANSITION ) ) )
749 : {
750 : /*gain_inov *= (1.1f- 0.75*st->lp_gainp);*/
751 1088 : L_tmp = Mpy_32_16_1( L_sub( 590558016l /*1.1f Q29*/, Mpy_32_16_1( st->Mode2_lp_gainp, 24576 ) ) /*Q29*/, gain_inov /*Q15,gain_inov_e*/ ); /*Q29,gain_inov_e*/
752 1088 : tmp_e = norm_l( L_tmp );
753 1088 : L_tmp = L_shl( L_tmp, tmp_e );
754 1088 : gain_inov_e = add( sub( gain_inov_e, tmp_e ), 31 - 29 ); /*->Q31*/
755 1088 : gain_inov = round_fx_sat( L_tmp ); /*Q15,gain_inov_e*/
756 : }
757 :
758 1088 : st->Mode2_lp_gainp = L_shr( L_deposit_h( alpha /*Q14*/ ) /*Q14+16*/, 1 ); /*Q29*/
759 1088 : move32();
760 1088 : pt_exc = noise; /* non-causal ringing of the FIR filter */
761 :
762 1088 : tmp_e = norm_l( gain32 );
763 1088 : tmp_e = sub( tmp_e, 5 ); /*5 Bit additional Headroom for the gain - should be enough*/
764 1088 : gain32 = L_shl( gain32, tmp_e ); /*Q16,-tmp_e*/
765 1088 : L_tmp = Mpy_32_16_1( gain32 /*Q16,-tmp_e*/, gain_inov /*Q15,gain_inov_e*/ ) /*Q16,gain_inov_e-tmp_e*/;
766 :
767 1088 : gain_tmp = round_fx( L_tmp ); /*Q0, gain_inov_e-tmp_e*/
768 :
769 6528 : FOR( i = 0; i < L_FIR_FER2 / 2; i++ )
770 : {
771 5440 : *pt_exc = mult_r( *pt_exc, gain_tmp ); /*Q-15,noise_e+gain_inov_e-tmp_e*/
772 5440 : move16();
773 5440 : pt_exc++;
774 : }
775 1088 : tmp16 = add( L_frame, L_FIR_FER2 / 2 );
776 1088 : step32_tmp = L_shl( step32 /*Q25*/, sub( tmp_e, 25 - 16 ) ); /*Q16,-tmp_e*/
777 813888 : FOR( i = 0; i < tmp16; i++ ) /* Actual filtered random part of excitation */
778 : {
779 812800 : *pt_exc = mult_r( *pt_exc, gain_tmp ); /*Q-15,noise_e+gain_inov_e-tmp_e*/
780 812800 : move16();
781 812800 : pt_exc++;
782 812800 : gain32 = L_sub( gain32 /*Q16,-tmp_e*/, step32_tmp ); /*Q16,-tmp_e*/
783 812800 : gain_tmp = mult_r( round_fx( gain32 /*Q16,-tmp_e*/ ) /*Q0*/, gain_inov /*Q15,gain_inov_e*/ ) /*Q0,gain_inov_e-tmp_e*/;
784 : }
785 1088 : tmp16 = shr( L_frame, 1 );
786 404768 : FOR( i = 0; i < tmp16; i++ ) /* causal ringing of the FIR filter */
787 : {
788 403680 : *pt_exc = mult_r( *pt_exc, gain_tmp ); /*Q-15,noise_e+gain_inov_e-tmp_e*/
789 403680 : move16();
790 403680 : pt_exc++;
791 : }
792 1088 : noise_e = add( sub( add( noise_e, gain_inov_e ), tmp_e ), 15 ); /*--> noise is Q0, noise_e*/
793 : /*buf[0;L_FIR_FER2 + L_Frame + L_Frame/2] Q0, noise_e*/
794 :
795 : /*-----------------------------------------------------------------*
796 : * Construct the total excitation
797 : *-----------------------------------------------------------------*/
798 :
799 1088 : IF( GE_16( st->last_good, UNVOICED_TRANSITION ) )
800 : {
801 1088 : tmp16 = add( L_frame, shr( L_frame, 1 ) );
802 1212128 : FOR( i = 0; i < tmp16; i++ )
803 : {
804 1211040 : exc[i] = add_sat( exc[i], shl_sat( noise[i + ( L_FIR_FER2 / 2 )], add( Q_exc, noise_e ) ) ); /*Q1*/
805 1211040 : move16();
806 : }
807 : }
808 : ELSE
809 : {
810 0 : bufferCopyFx( noise + L_FIR_FER2 / 2, exc, add( L_frame, shr( L_frame, 1 ) ), 0 /*Q_noise*/, noise_e, Q_exc, 0 /*exc_e*/ );
811 0 : Copy( exc + sub( L_frame, shl( L_subfr, 1 ) ), hTcxDec->old_excFB_fx, add( shl( L_subfr, 1 ), shr( L_frame, 1 ) ) ); /*Q_exc*/
812 : /* copy old_exc as 16kHz for acelp decoding */
813 0 : IF( EQ_16( st->nbLostCmpt, 1 ) )
814 : {
815 0 : lerp( exc, st->old_exc_fx, L_EXC_MEM_DEC, add( L_frame, shr( L_frame, 1 ) ) );
816 : }
817 : ELSE
818 : {
819 0 : Copy( st->old_exc_fx + L_FRAME16k, st->old_exc_fx, L_FRAME16k / 2 ); /*Q_exc*/
820 0 : lerp( exc, st->old_exc_fx + L_FRAME16k / 2, L_FRAME16k, L_frame );
821 : }
822 0 : st->Q_exc = Q_exc;
823 0 : move16();
824 : }
825 : /*buf[0;L_FIR_FER2 + L_Frame + L_Frame/2] Q0, noise_e*/
826 : /*buf[OLD_EXC_SIZE_DEC;3/2 L_frame] Q1*/
827 :
828 : /* Update Pitch Lag memory */
829 1088 : Copy32( &st->old_pitch_buf_fx[st->nb_subfr], st->old_pitch_buf_fx, st->nb_subfr ); /*Q16*/
830 1088 : Copy32( pitch_buf, &st->old_pitch_buf_fx[st->nb_subfr], st->nb_subfr ); /*Q16*/
831 :
832 : /*----------------------------------------------------------*
833 : * - compute the synthesis speech *
834 : *----------------------------------------------------------*/
835 :
836 1088 : syn = buf + M; /*Q_syn*/
837 1088 : Copy( synth - M, buf, M ); /*Q_syn*/
838 :
839 1088 : new_Q = sub( Q_exc, 3 );
840 1088 : new_Q = s_max( new_Q, -1 );
841 :
842 1088 : tmp16 = s_min( new_Q, st->prev_Q_syn );
843 1088 : st->prev_Q_syn = new_Q;
844 1088 : move16();
845 :
846 1088 : exp_scale = sub( tmp16, sub( Q_exc, 1 ) );
847 1088 : Q_syn = tmp16;
848 1088 : move16();
849 :
850 1088 : Copy_Scale_sig( buf, mem_syn, M, exp_scale ); /*Q: tmp16*/
851 :
852 1088 : tmp_deemph = shl_sat( tmp_deemph, Q_syn ); /*Q_syn*/
853 1088 : st->Q_syn = Q_syn;
854 1088 : move16();
855 :
856 : /*buf[OLD_EXC_SIZE_DEC;3/2 L_frame] Q1: exc*/
857 : /*buf[0;M] Q0: mem_syn*/
858 1088 : E_UTIL_synthesis(
859 1088 : sub( Q_exc, Q_syn ),
860 : A_local,
861 : &exc[0],
862 : &syn[0],
863 1088 : add( L_frame, shr( L_frame, 1 ) ),
864 : mem_syn,
865 : 1,
866 : M );
867 :
868 : /*buf[OLD_EXC_SIZE_DEC;3/2 L_frame-1] Q1: exc*/
869 : /*buf[0;M-1] Q0: mem_syn*/
870 : /*buf[M;3/2 L_frame-1] Q-1: syn*/
871 :
872 1088 : n = extract_h( L_mult( L_frame, 9216 /*(float)N_ZERO_MDCT_NS/(float)FRAME_SIZE_NS Q15*/ ) ); /*q0*/
873 :
874 : /* update ACELP synthesis memory */
875 1088 : mem_syn_r_size_old = shr( L_frame, 4 ); /* replace 1.25/20.0 by shr(4) */
876 : /* copy mem_syn as 16kHz */
877 1088 : mem_syn_r_size_new = shr( L_FRAME16k, 4 ); /* replace 1.25/20.0 by shr(4) */
878 :
879 1088 : Copy( syn + sub( L_frame, L_SYN_MEM ), st->mem_syn_r, L_SYN_MEM ); /*Q_syn*/
880 1088 : lerp( st->mem_syn_r + sub( L_SYN_MEM, mem_syn_r_size_old ), st->mem_syn_r + sub( L_SYN_MEM, mem_syn_r_size_new ), mem_syn_r_size_new, mem_syn_r_size_old );
881 1088 : Copy( st->mem_syn_r + L_SYN_MEM - M, st->mem_syn2_fx, M ); /*Q_syn*/
882 :
883 : /* Deemphasis and output synth and ZIR */
884 1088 : deemph_fx( syn, st->preemph_fac, add( L_frame, shr( L_frame, 1 ) ), &tmp_deemph );
885 1088 : bufferCopyFx( syn + sub( L_frame, M + 1 ), st->syn, 1 + M, Q_syn, 0, 0, 0 ); /*Q_syn*/
886 :
887 :
888 1088 : lerp( syn + sub( L_frame, shr( L_frame, 1 ) ), hTcxDec->old_syn_Overl, shr( st->L_frame, 1 ), shr( L_frame, 1 ) );
889 1088 : Copy( syn + sub( L_frame, n ), hHQ_core->old_out_fx, sub( L_frame, n ) ); /*Q_syn*/
890 :
891 177698 : FOR( i = 0; i < W12; i++ )
892 : {
893 176610 : hHQ_core->old_out_fx[( i + n )] = round_fx( Mpy_32_16_1( L_mult( w[i].v.re, w[i].v.re ), hHQ_core->old_out_fx[( i + n )] ) ); /*Q_syn*/
894 176610 : move16();
895 : }
896 177698 : FOR( ; i < W1; i++ )
897 : {
898 176610 : hHQ_core->old_out_fx[( i + n )] = round_fx( Mpy_32_16_1( L_mult( w[( ( W12 - 1 ) - ( i - W12 ) )].v.im, w[( ( W12 - 1 ) - ( i - W12 ) )].v.im ), hHQ_core->old_out_fx[( i + n )] ) ); /*Q_syn*/
899 176610 : move16();
900 : }
901 :
902 1088 : set16_fx( &hHQ_core->old_out_fx[( W1 + n )], 0, n );
903 :
904 1088 : hHQ_core->Q_old_wtda = Q_syn;
905 1088 : move16();
906 :
907 : /* As long as there is no synth scaling factor introduced, which
908 : is given to the outside, there might occur overflows here */
909 : BASOP_SATURATE_WARNING_OFF_EVS
910 1088 : bufferCopyFx( syn, synth, L_frame, Q_syn, 0, 0, 0 ); /*Q_syn*/
911 : BASOP_SATURATE_WARNING_ON_EVS
912 :
913 1088 : Copy_Scale_sig( syn + L_frame, hTcxDec->syn_OverlFB, shr( L_frame, 1 ), negate( Q_syn ) ); /*Q0*/
914 :
915 : /* copy total excitation exc2 as 16kHz for acelp mode1 decoding */
916 1088 : IF( st->hWIDec != NULL )
917 : {
918 0 : lerp( exc, st->hWIDec->old_exc2_fx, L_EXC_MEM, L_frame );
919 0 : lerp( syn, st->hWIDec->old_syn2_fx, L_EXC_MEM, L_frame );
920 : }
921 :
922 1088 : st->bfi_pitch_fx /*Q6*/ = round_fx_sat( L_shl_sat( pitch_buf[( st->nb_subfr - 1 )] /*15Q16*/, 6 /*Q6*/ ) );
923 1088 : move16();
924 1088 : st->bfi_pitch_frame = st->L_frame;
925 1088 : move16();
926 :
927 : /* create aliasing and windowing need for transition to TCX10/5 */
928 1088 : bufferCopyFx( syn + L_frame, hTcxDec->syn_Overl_TDACFB, shr( L_frame, 1 ), Q_syn, 0, -1, 0 );
929 1088 : hTcxDec->Q_syn_Overl_TDACFB = add( st->Q_syn, sub( st->Q_syn, -1 ) );
930 1088 : move16();
931 :
932 177698 : FOR( i = 0; i < W12; i++ )
933 : {
934 176610 : buf[i] = mult_r( hTcxDec->syn_Overl_TDACFB[i], w[i].v.re ); /*hTcxDec->Q_syn_Overl_TDACFB*/
935 176610 : move16();
936 : }
937 177698 : FOR( ; i < W1; i++ )
938 : {
939 176610 : buf[i] = mult_r( hTcxDec->syn_Overl_TDACFB[i], w[( ( W12 - 1 ) - ( i - W12 ) )].v.im ); /*hTcxDec->Q_syn_Overl_TDACFB*/
940 176610 : move16();
941 : }
942 :
943 :
944 177698 : FOR( i = 0; i < W2; i++ )
945 : {
946 176610 : hTcxDec->syn_Overl_TDACFB[i] = add_sat( buf[i], buf[( ( W1 - 1 ) - i )] ); /*hTcxDec->Q_syn_Overl_TDACFB*/
947 176610 : move16();
948 : }
949 :
950 177698 : FOR( i = 0; i < W2; i++ )
951 : {
952 176610 : hTcxDec->syn_Overl_TDACFB[( W2 + i )] = add_sat( buf[( W2 + i )], buf[( ( ( W1 - 1 ) - W2 ) - i )] ); /*hTcxDec->Q_syn_Overl_TDACFB*/
953 176610 : move16();
954 : }
955 :
956 177698 : FOR( i = 0; i < W12; i++ )
957 : {
958 176610 : hTcxDec->syn_Overl_TDACFB[i] = mult_r( hTcxDec->syn_Overl_TDACFB[i], w[i].v.re ); /*hTcxDec->Q_syn_Overl_TDACFB*/
959 176610 : move16();
960 : }
961 177698 : FOR( ; i < W1; i++ )
962 : {
963 176610 : hTcxDec->syn_Overl_TDACFB[i] = mult_r( hTcxDec->syn_Overl_TDACFB[i], w[( ( W12 - 1 ) - ( i - W12 ) )].v.im ); /*hTcxDec->Q_syn_Overl_TDACFB*/
964 176610 : move16();
965 : }
966 :
967 1088 : st->hTcxCfg->tcx_curr_overlap_mode = FULL_OVERLAP;
968 1088 : move16();
969 :
970 1088 : synth[-1] = pre_emph_buf; /*Q0*/
971 1088 : move16();
972 :
973 : /* update memory for low band */
974 1088 : Scale_sig( hTcxDec->old_syn_Overl, shr( st->L_frame, 1 ), sub( -1, Q_syn ) ); /*Q_syn*/
975 1088 : lerp( hTcxDec->syn_OverlFB, hTcxDec->syn_Overl, shr( st->L_frame, 1 ), shr( L_frame, 1 ) );
976 1088 : lerp( hTcxDec->syn_Overl_TDACFB, hTcxDec->syn_Overl_TDAC, shr( st->L_frame, 1 ), shr( L_frame, 1 ) );
977 1088 : hTcxDec->Q_syn_Overl_TDAC = hTcxDec->Q_syn_Overl_TDACFB;
978 1088 : move16();
979 1088 : lerp( st->hHQ_core->old_out_fx, st->hHQ_core->old_out_LB_fx, st->L_frame, L_frame );
980 :
981 1088 : st->old_enr_LP = Enr_1_Az_fx( A_local, L_SUBFR ); /*Q3*/
982 1088 : move16();
983 :
984 1088 : return;
985 : }
986 :
987 3434 : void con_tcx_ivas_fx(
988 : Decoder_State *st, /* i/o: coder memory state */
989 : Word16 synth[],
990 : /* i/o: synth[] */ /*Q0 */
991 : const Word16 coh, /* i : coherence of stereo signal Q14*/
992 : Word16 *noise_seed, /* i/o: noise seed for stereo Q0*/
993 : const Word16 only_left, /* i : TD-PLC only in left channel Q0*/
994 : const Word16 *A_cng /* i : CNG LP filter coefficients Q14*/
995 : )
996 : {
997 : Word16 i, s, c, L_frame, L_subfr, fLowPassFilter, T0;
998 : Word16 n, mem_syn_r_size_old, mem_syn_r_size_new;
999 : Word16 *noise;
1000 : Word16 mem_syn[M], *syn;
1001 : Word16 *exc, buf[OLD_EXC_SIZE_DEC + L_FRAME_MAX + L_FRAME_MAX / NB_SUBFR + 1 + L_FRAME_MAX / 2];
1002 : Word16 pre_emph_buf;
1003 : Word16 hp_filt[L_FIR_FER2];
1004 : Word16 alpha;
1005 : Word16 tmp_deemph, gain, gainCNG, gain_inov;
1006 : Word16 *pt_exc, *pt1_exc;
1007 : Word16 Tc, tmpSeed;
1008 : Word16 fUseExtrapolatedPitch;
1009 : Word16 *ana_window;
1010 : Word16 r_h[M + 1], A_local[M + 1], mem, r_l[M + 1];
1011 : PWord16 const *w;
1012 : Word16 W1, W2, W12;
1013 : Word16 Q_r;
1014 : Word16 tmp16, tmp16_2, tmp_loop, tmp_e, gain_tmp;
1015 : Word16 gainCNG_e, noise_e, gain_inov_e; /*Exponents for gainCNG, noise, gain_inov*/
1016 : Word16 Q_syn; /*Q format of temporary synthesis buffer syn*/
1017 : Word32 L_tmp, L_tmp2, step32_tmp;
1018 : Word32 predPitchLag, pitch_buf[NB_SUBFR16k], step32, gain32;
1019 : Word16 extrapolationFailed;
1020 : Word16 gainSynthDeemph;
1021 : Word16 gainSynthDeemph_e;
1022 : Word32 old_pitch_buf[2 * NB_SUBFR16k + 2];
1023 : Word16 Q_exc, new_Q, exp_scale;
1024 : Word16 offset;
1025 : HQ_DEC_HANDLE hHQ_core;
1026 : TCX_LTP_DEC_HANDLE hTcxLtpDec;
1027 : TCX_DEC_HANDLE hTcxDec;
1028 :
1029 3434 : hTcxLtpDec = st->hTcxLtpDec;
1030 3434 : hHQ_core = st->hHQ_core;
1031 3434 : hTcxDec = st->hTcxDec;
1032 :
1033 : /* inits */
1034 3434 : alpha = 0;
1035 3434 : move16();
1036 3434 : fUseExtrapolatedPitch = 0;
1037 3434 : move16();
1038 3434 : extrapolationFailed = 1;
1039 3434 : move16();
1040 :
1041 3434 : noise_e = 0;
1042 3434 : move16();
1043 3434 : Q_syn = -1; /*Q format of temporary synthesis buffer syn*/
1044 3434 : move16();
1045 3434 : offset = 0;
1046 3434 : move16();
1047 :
1048 : /* Framing parameters */
1049 3434 : L_frame = hTcxDec->L_frameTCX;
1050 3434 : move16();
1051 : /* L_subfr = st->L_frameTCX/st->nb_subfr */
1052 3434 : L_subfr = mult_r( hTcxDec->L_frameTCX, div_s( 1, st->nb_subfr ) ); /*Q0*/
1053 3434 : assert( L_subfr == hTcxDec->L_frameTCX / st->nb_subfr );
1054 3434 : w = st->hTcxCfg->tcx_mdct_windowFB; /*pointer - no need to instrument Q15*/
1055 3434 : W1 = st->hTcxCfg->tcx_mdct_window_lengthFB;
1056 3434 : move16();
1057 3434 : W2 = shr( st->hTcxCfg->tcx_mdct_window_lengthFB, 1 );
1058 3434 : W12 = shr( W1, 1 );
1059 :
1060 : /* take the previous frame last pitch */
1061 3434 : Tc = round_fx( st->old_fpitchFB ); /*Q0*/
1062 :
1063 :
1064 3434 : set16_fx( buf, 0, OLD_EXC_SIZE_DEC + L_FRAME_MAX + L_FRAME_MAX / NB_SUBFR + 1 + L_FRAME_MAX / 2 ); /* initialize buf with 0 */
1065 : // set16_fx(buf,0,shr(sizeof(buf),1)); /* initialize buf with 0 */
1066 :
1067 3434 : c = BASOP_Util_Divide1616_Scale(
1068 : L_frame,
1069 3434 : st->L_frame,
1070 : &s );
1071 :
1072 44642 : FOR( i = 0; i < 2 * NB_SUBFR16k + 2; i++ )
1073 : {
1074 41208 : old_pitch_buf[i] = L_shl( Mpy_32_16_1( st->old_pitch_buf_fx[i], c ), s ); /*Q16*/
1075 41208 : move32();
1076 : }
1077 :
1078 : /* set excitation memory*/
1079 3434 : exc = buf + OLD_EXC_SIZE_DEC;
1080 3434 : tmp_deemph = synth[-1]; /*Q0*/
1081 3434 : move16();
1082 3434 : pre_emph_buf = synth[-1]; /*Q0*/
1083 3434 : move16();
1084 :
1085 3434 : test();
1086 3434 : IF( ( EQ_16( st->nbLostCmpt, 1 ) ) || hTcxDec->tcxConceal_recalc_exc )
1087 : {
1088 : /* apply pre-emphasis to the signal */
1089 1515 : mem = synth[( -( ( ( L_frame / 2 ) + hTcxDec->pit_max_TCX ) + M + M ) - 1 )]; /*Q0*/
1090 1515 : move16();
1091 1515 : Q_exc = E_UTIL_f_preemph3_ivas_fx( &( synth[-( ( ( L_frame / 2 ) + hTcxDec->pit_max_TCX ) + 2 * M )] ), st->preemph_fac, add( add( shr( L_frame, 1 ), hTcxDec->pit_max_TCX ), shl( M, 1 ) ), &mem, 1 );
1092 1515 : st->Mode2_lp_gainc = L_deposit_l( 0 );
1093 :
1094 1515 : st->Mode2_lp_gainp = get_gain2( synth - shl( L_subfr, 1 ), synth - add( shl( L_subfr, 1 ), Tc ), shl( L_subfr, 1 ) );
1095 1515 : move32();
1096 :
1097 1515 : st->Mode2_lp_gainp = L_max( st->Mode2_lp_gainp, 0 ); /*Q16*/
1098 1515 : st->Mode2_lp_gainp = L_min( st->Mode2_lp_gainp, 65536l /*1.0f Q16*/ ); /*Q16*/
1099 1515 : st->Mode2_lp_gainp = L_shl( st->Mode2_lp_gainp, 13 ); /*Q29*/
1100 1515 : move32();
1101 1515 : move32();
1102 1515 : move32();
1103 :
1104 1515 : ana_window = buf; /*Q15*/
1105 1515 : ham_cos_window( ana_window, mult( L_frame, 24576 /*0.75f Q15*/ ), shr( L_frame, 2 ) );
1106 :
1107 : /* Autocorrelation */
1108 1515 : autocorr_fx( &( synth[( -L_frame - 1 )] ), M, r_h, r_l, &Q_r, L_frame, ana_window, 0, 0 );
1109 :
1110 : /* Lag windowing */
1111 1515 : lag_wind( r_h, r_l, M, st->output_Fs, LAGW_STRONG );
1112 :
1113 : /* Levinson Durbin */
1114 1515 : E_LPC_lev_dur_ivas_fx( r_h, r_l, A_local, NULL, M, NULL );
1115 :
1116 : /* copy for multiple frame loss */
1117 1515 : Copy( A_local, st->old_Aq_12_8_fx, M + 1 ); /*Q14*/
1118 :
1119 : /* Residu */
1120 1515 : assert( ( 2 * L_subfr + Tc + 1 + M ) <= hTcxDec->old_synth_lenFB );
1121 :
1122 : BASOP_SATURATE_WARNING_OFF_EVS /*saturation possible in case of spiky synthesis*/
1123 4545 : Residu3_fx(
1124 : A_local,
1125 1515 : &( synth[-add( add( add( shl( L_subfr, 1 ), Tc ), 1 ), M )] ), /*Qx = Q0*/
1126 1515 : &( exc[-add( add( add( shl( L_subfr, 1 ), Tc ), 1 ), M )] ), /*Qx+1 = Q1*/
1127 1515 : add( add( add( shl( L_subfr, 1 ), Tc ), 1 ), M ),
1128 : 1 );
1129 : BASOP_SATURATE_WARNING_ON_EVS
1130 : }
1131 : ELSE
1132 : {
1133 : /* apply pre-emphasis to the signal */
1134 1919 : mem = synth[( -L_frame - 1 )]; /*Q0*/
1135 1919 : move16();
1136 1919 : Q_exc = E_UTIL_f_preemph3_ivas_fx( &( synth[-L_frame] ), st->preemph_fac, L_frame, &mem, 1 );
1137 1919 : Copy( st->old_Aq_12_8_fx, A_local, M + 1 ); /*Q14*/
1138 :
1139 1919 : offset = shr( L_frame, 1 );
1140 1919 : IF( GE_16( st->last_good, UNVOICED_TRANSITION ) )
1141 : {
1142 1919 : tmp16 = s_max( Tc - shr( L_frame, 1 ), 0 );
1143 1919 : Copy_Scale_sig( hTcxDec->old_excFB_fx, &( exc[-tmp16] ), add( offset, tmp16 ), sub( Q_exc, st->Q_exc ) ); /*Q_exc*/
1144 : }
1145 : ELSE
1146 : {
1147 0 : Copy_Scale_sig( hTcxDec->old_excFB_fx, &( exc[-( L_subfr * 2 )] ), add( shl( L_subfr, 1 ), offset ), sub( Q_exc, st->Q_exc ) ); /*Q_exc*/
1148 : }
1149 : }
1150 :
1151 : /*-----------------------------------------------------------------*
1152 : * PLC: Construct the harmonic part of excitation
1153 : *-----------------------------------------------------------------*/
1154 :
1155 3434 : test();
1156 3434 : test();
1157 3434 : IF( GT_16( st->last_good, UNVOICED_CLAS ) && !( EQ_16( st->last_good, UNVOICED_TRANSITION ) && EQ_16( st->core_ext_mode, GENERIC ) ) )
1158 : {
1159 3434 : test();
1160 3434 : IF( EQ_16( st->nbLostCmpt, 1 ) || hTcxDec->tcxConceal_recalc_exc )
1161 : {
1162 1515 : calcGainc_fx( exc, Q_exc, st->old_fpitchFB, L_subfr, st->Mode2_lp_gainp, &( st->Mode2_lp_gainc ) );
1163 : }
1164 :
1165 3434 : tmp16 = 0;
1166 3434 : move16();
1167 3434 : if ( GT_32( st->output_Fs, 25600 ) )
1168 : {
1169 2443 : tmp16 = 1;
1170 2443 : move16();
1171 : }
1172 :
1173 3434 : test();
1174 3434 : test();
1175 3434 : test();
1176 3434 : test();
1177 3434 : IF( ( ( EQ_16( st->nbLostCmpt, 1 ) ) || hTcxDec->tcxConceal_recalc_exc ) && GE_16( st->rf_frame_type, RF_TCXFD ) && LE_16( st->rf_frame_type, RF_TCXTD2 ) && st->use_partial_copy )
1178 0 : {
1179 : Word32 tcxltp_pitch_tmp; /*15Q16*/
1180 : Word16 scale_tmp; /*getInvFrameLen()->9Q6*/
1181 : Word16 tmp_shift;
1182 0 : tcxltp_pitch_tmp = L_add( L_deposit_h( hTcxLtpDec->tcxltp_pitch_int ), L_shl( L_deposit_l( div_s( hTcxLtpDec->tcxltp_pitch_fr, st->pit_res_max ) ), 1 ) ); /*15Q16*/
1183 0 : scale_tmp = mult_r( hTcxDec->L_frameTCX, getInvFrameLen( st->L_frame ) ); /*getInvFrameLen()->9Q6*/
1184 0 : tmp_shift = norm_s( scale_tmp );
1185 :
1186 0 : predPitchLag = L_shl( Mpy_32_16_1( tcxltp_pitch_tmp, shl( scale_tmp, tmp_shift ) ), sub( 9, tmp_shift ) ); /*Q16*/
1187 :
1188 0 : T0 = round_fx( predPitchLag ); /*Q0*/
1189 :
1190 0 : test();
1191 0 : test();
1192 0 : if ( ( T0 > 0 ) && ( NE_16( T0, Tc ) ) && ( LT_32( L_deposit_h( abs_s( sub( T0, Tc ) ) ) /*Q16*/, L_mult( 4915 /*.15f Q15*/ /*Q15*/, Tc /*Q0*/ ) /*Q16*/ ) ) )
1193 : {
1194 0 : fUseExtrapolatedPitch = 1;
1195 0 : move16();
1196 : }
1197 : }
1198 : ELSE
1199 : {
1200 :
1201 3434 : pitch_pred_linear_fit(
1202 3434 : st->nbLostCmpt,
1203 3434 : st->last_good,
1204 : old_pitch_buf,
1205 : &( st->old_fpitchFB ),
1206 : &predPitchLag,
1207 3434 : hTcxDec->pit_min_TCX,
1208 3434 : hTcxDec->pit_max_TCX,
1209 3434 : st->mem_pitch_gain,
1210 : tmp16,
1211 3434 : st->plc_use_future_lag,
1212 : &extrapolationFailed,
1213 3434 : st->nb_subfr );
1214 :
1215 3434 : T0 = round_fx( predPitchLag );
1216 3434 : test();
1217 3434 : test();
1218 3434 : test();
1219 3434 : if ( ( T0 > 0 ) && ( NE_16( T0, Tc ) ) && ( LT_32( L_deposit_h( abs_s( sub( T0, Tc ) ) ) /*Q16*/, L_mult( 4915 /*.15f Q15*/ /*Q15*/, Tc /*Q0*/ ) /*Q16*/ ) ) && ( extrapolationFailed == 0 ) )
1220 : {
1221 653 : fUseExtrapolatedPitch = 1;
1222 653 : move16();
1223 : }
1224 : }
1225 :
1226 :
1227 3434 : fLowPassFilter = 0;
1228 3434 : move16();
1229 3434 : pt_exc = exc + offset; /*Q_exc*/
1230 3434 : pt1_exc = pt_exc - Tc; /*Q_exc*/
1231 :
1232 3434 : if ( fUseExtrapolatedPitch != 0 )
1233 : {
1234 653 : pt_exc = buf; /*Q_exc*/
1235 : }
1236 3434 : test();
1237 3434 : IF( LT_16( st->stab_fac_fx, 32767 /*1.f Q15*/ ) && EQ_16( st->nbLostCmpt, 1 ) )
1238 : {
1239 : /* pitch cycle is first low-pass filtered */
1240 :
1241 202 : IF( LE_32( st->output_Fs, 16000 ) )
1242 : {
1243 1421 : FOR( i = 0; i < Tc; i++ )
1244 : {
1245 1401 : *pt_exc++ = mac_r( L_mac( L_mac( L_mac( L_mac( L_mac( L_mac( L_mac( L_mac( L_mac(
1246 1401 : L_mult( 174 /* 0.0053f Q15*/, pt1_exc[-5] ),
1247 1401 : 0 /* 0.0000f Q15*/, pt1_exc[-4] ),
1248 1401 : -1442 /*-0.0440f Q15*/, pt1_exc[-3] ),
1249 1401 : 0 /* 0.0000f Q15*/, pt1_exc[-2] ),
1250 1401 : 8641 /* 0.2637f Q15*/, pt1_exc[-1] ),
1251 1401 : 18022 /* 0.5500f Q15*/, pt1_exc[0] ),
1252 1401 : 8641 /* 0.2637f Q15*/, pt1_exc[1] ),
1253 1401 : 0 /* 0.0000f Q15*/, pt1_exc[2] ),
1254 1401 : -1442 /*-0.0440f Q15*/, pt1_exc[3] ),
1255 1401 : 0 /* 0.0000f Q15*/, pt1_exc[4] ),
1256 1401 : 174 /* 0.0053f Q15*/, pt1_exc[5] ); /*Q_exc*/
1257 1401 : move16();
1258 1401 : pt1_exc++;
1259 : }
1260 : }
1261 : ELSE /*(st->output_Fs >= 32000)*/
1262 : {
1263 43718 : FOR( i = 0; i < Tc; i++ )
1264 : {
1265 43536 : *pt_exc++ = mac_r( L_mac( L_mac( L_mac( L_mac( L_mac( L_mac( L_mac( L_mac( L_mac(
1266 43536 : L_mult( -174 /*-0.0053f Q15*/, pt1_exc[-5] ),
1267 43536 : -121 /*-0.0037f Q15*/, pt1_exc[-4] ),
1268 43536 : -459 /*-0.0140f Q15*/, pt1_exc[-3] ),
1269 43536 : 590 /* 0.0180f Q15*/, pt1_exc[-2] ),
1270 43536 : 8743 /* 0.2668f Q15*/, pt1_exc[-1] ),
1271 43536 : 16355 /* 0.4991f Q15*/, pt1_exc[0] ),
1272 43536 : 8743 /* 0.2668f Q15*/, pt1_exc[1] ),
1273 43536 : 590 /* 0.0180f Q15*/, pt1_exc[2] ),
1274 43536 : -459 /*-0.0140f Q15*/, pt1_exc[3] ),
1275 43536 : -121 /*-0.0037f Q15*/, pt1_exc[4] ),
1276 43536 : -174 /*-0.0053f Q15*/, pt1_exc[5] ); /*Q_exc*/
1277 43536 : move16();
1278 43536 : pt1_exc++;
1279 : }
1280 : }
1281 :
1282 202 : fLowPassFilter = 1;
1283 202 : move16();
1284 : }
1285 : ELSE
1286 : {
1287 : /* copy the first pitch cycle without low-pass filtering */
1288 742046 : FOR( i = 0; i < Tc; i++ )
1289 : {
1290 738814 : *pt_exc++ = *pt1_exc++; /*Q_exc*/
1291 738814 : move16();
1292 : }
1293 3232 : fLowPassFilter = 1;
1294 3232 : move16();
1295 : }
1296 :
1297 3434 : if ( fUseExtrapolatedPitch != 0 )
1298 : {
1299 653 : pt1_exc = buf;
1300 : }
1301 3434 : tmp16 = add( sub( L_frame, imult1616( fLowPassFilter, Tc ) ), L_subfr );
1302 2051971 : FOR( i = 0; i < tmp16; i++ )
1303 : {
1304 2048537 : *pt_exc++ = *pt1_exc++; /*Q_exc*/
1305 2048537 : move16();
1306 : }
1307 :
1308 3434 : IF( fUseExtrapolatedPitch != 0 )
1309 : {
1310 653 : get_subframe_pitch( st->nb_subfr,
1311 : st->old_fpitch,
1312 : /* predPitchLag * L_frame/st->L_frame, */
1313 : L_shr( Mpy_32_16_1( predPitchLag /*Q16*/,
1314 653 : mult_r( st->L_frame /*Q0*/,
1315 653 : getInvFrameLen( L_frame ) /*Q21*/
1316 : ) /*Q6*/
1317 : ) /*Q7*/,
1318 : 7 - 16 ) /*Q16*/,
1319 : pitch_buf );
1320 :
1321 653 : PulseResynchronization_fx( buf, exc, L_frame, st->nb_subfr, st->old_fpitchFB, predPitchLag );
1322 : }
1323 : ELSE
1324 : {
1325 2781 : set32_fx( pitch_buf, st->old_fpitch, st->nb_subfr ); /*Q16*/
1326 : }
1327 :
1328 3434 : IF( EQ_16( st->nbLostCmpt, 1 ) )
1329 : {
1330 1515 : pt_exc = exc + L_frame;
1331 1515 : IF( T0 == 0 )
1332 : {
1333 426 : pt1_exc = pt_exc - Tc; /*Q_exc*/
1334 : }
1335 : ELSE
1336 : {
1337 1089 : pt1_exc = pt_exc - T0; /*Q_exc*/
1338 : }
1339 :
1340 1515 : tmp_loop = shr( L_frame, 1 );
1341 535595 : FOR( i = 0; i < tmp_loop; i++ )
1342 : {
1343 534080 : *pt_exc++ = *pt1_exc++; /*Q_exc*/
1344 534080 : move16();
1345 : }
1346 : }
1347 :
1348 3434 : if ( fUseExtrapolatedPitch != 0 )
1349 : {
1350 653 : st->old_fpitchFB = predPitchLag; /*Q16*/
1351 653 : move32();
1352 : }
1353 3434 : st->bpf_gain_param = 0;
1354 3434 : move16();
1355 :
1356 : /* PLC: calculate damping factor */
1357 3434 : alpha = Damping_fact_fx( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac_fx, &( st->Mode2_lp_gainp ), 0 ); /*Q14*/
1358 3434 : IF( EQ_16( st->nbLostCmpt, 1 ) )
1359 : {
1360 1515 : st->cummulative_damping = 32767 /*1.f Q15*/;
1361 1515 : move16();
1362 : }
1363 : ELSE
1364 : {
1365 1919 : st->cummulative_damping = shl_sat( mult_r_sat( st->cummulative_damping /*Q15*/, alpha /*Q14*/ ), 1 ) /*Q15*/;
1366 1919 : move16();
1367 : }
1368 :
1369 3434 : gain32 = L_add( 2147483647l /*1.f Q31*/, 0 ); /*Q31*/
1370 3434 : gain = 32767 /*1.f Q15*/; /*Q15*/
1371 3434 : move16();
1372 3434 : test();
1373 3434 : IF( EQ_16( st->rf_frame_type, RF_TCXTD1 ) && EQ_16( st->use_partial_copy, 1 ) )
1374 : {
1375 0 : gain32 = 1073741824l /*0.5f Q31*/;
1376 0 : move32();
1377 0 : gain = 16384 /*0.5f Q15*/;
1378 0 : move16();
1379 : }
1380 :
1381 : /*step = (1.0f/(L_frame+(L_frame/2))) * (gain - alpha);*/
1382 3434 : tmp16 = shr( imult1616( 3, L_frame ), 1 );
1383 3434 : tmp_e = norm_s( tmp16 );
1384 3434 : tmp16 = shl( tmp16, tmp_e );
1385 3434 : tmp16 = div_s( 16384 /*1.f Q14*/, tmp16 ); /*Q15,1+tmp_e-15*/
1386 3434 : tmp16_2 = sub( shr( gain, 1 ), alpha ) /*Q14*/;
1387 3434 : step32 = L_shl( L_mult( tmp16, tmp16_2 ) /*Q30, 1+tmp_e-15*/, add( 1 - 14, tmp_e ) ) /*Q31*/;
1388 :
1389 : /* PLC: Apply fade out */
1390 3434 : tmp_loop = shr( imult1616( L_frame, 3 ), 1 );
1391 2853994 : FOR( i = offset; i < tmp_loop; i++ )
1392 : {
1393 2850560 : exc[i] = mult_r( exc[i], round_fx_sat( gain32 ) ) /*Q1*/;
1394 2850560 : move16();
1395 2850560 : gain32 = L_sub_sat( gain32, step32 ); /*Q31*/
1396 : }
1397 :
1398 : /* update old exc without random part */
1399 3434 : offset = s_max( sub( round_fx( st->old_fpitchFB ), shr( L_frame, 1 ) ), 0 ); /*Q0*/
1400 3434 : Copy( exc + sub( L_frame, offset ), hTcxDec->old_excFB_fx, add( shr( L_frame, 1 ), offset ) ); /*Q_exc*/
1401 : /* copy old_exc as 16kHz for acelp decoding */
1402 3434 : IF( EQ_16( st->nbLostCmpt, 1 ) )
1403 : {
1404 1515 : lerp( exc - shr( L_frame, 1 ), st->old_exc_fx, L_EXC_MEM_DEC, add( L_frame, shr( L_frame, 1 ) ) );
1405 : }
1406 : ELSE
1407 : {
1408 1919 : Copy( st->old_exc_fx + L_FRAME16k, st->old_exc_fx, L_FRAME16k / 2 ); /*Q_exc*/
1409 1919 : lerp( exc, st->old_exc_fx + L_FRAME16k / 2, L_FRAME16k, L_frame );
1410 : }
1411 3434 : st->Q_exc = Q_exc;
1412 3434 : move16();
1413 : }
1414 : ELSE
1415 : {
1416 : /* No harmonic part */
1417 0 : set16_fx( &exc[0], 0, add( L_frame, shr( L_frame, 1 ) ) );
1418 0 : IF( EQ_16( st->nbLostCmpt, 1 ) )
1419 : {
1420 0 : calcGainc2_fx( &exc[0], Q_exc, L_subfr, &( st->Mode2_lp_gainc ) );
1421 : }
1422 0 : set32_fx( pitch_buf, L_deposit_h( L_SUBFR ), st->nb_subfr ); /*Q16*/
1423 : /* PLC: calculate damping factor */
1424 0 : alpha = Damping_fact_fx( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac_fx, &( st->Mode2_lp_gainp ), 0 ); /*Q14*/
1425 : }
1426 :
1427 : /*-----------------------------------------------------------------*
1428 : * Construct the random part of excitation
1429 : *-----------------------------------------------------------------*/
1430 : #ifndef IVAS_CODE_CON_TCX
1431 3434 : IF( NE_16( coh, -16384 ) )
1432 : {
1433 : Word16 tmpSeed1;
1434 : Word16 alpha_coh;
1435 : Word16 random1, random2;
1436 : Word16 e;
1437 :
1438 902 : tmpSeed1 = *noise_seed;
1439 902 : noise = buf; /*Q15*/
1440 902 : noise_e = 2;
1441 902 : move16();
1442 902 : e = 0;
1443 902 : move16();
1444 902 : alpha_coh = 0;
1445 902 : move16();
1446 :
1447 902 : IF( NE_16( coh, 16384 /*1.0f in Q14*/ ) )
1448 : {
1449 900 : alpha_coh = Sqrt16( div_s( sub( 16384 /*1.0f in Q14*/, coh ), add( 16384 /*1.0f in Q14*/, coh ) ), &e ); /* Q15 - e */
1450 : }
1451 902 : if ( EQ_16( st->idchan, 1 ) )
1452 : {
1453 418 : alpha_coh = negate( alpha_coh );
1454 : }
1455 :
1456 593922 : FOR( i = 0; i < L_frame + L_FIR_FER2 - 1; i++ )
1457 : {
1458 593020 : random1 = Random( &tmpSeed1 );
1459 593020 : random2 = Random( &tmpSeed1 );
1460 593020 : noise[i] = add( shr( random1, noise_e ), shr( mult( alpha_coh, random2 ), sub( noise_e, e ) ) );
1461 593020 : move16();
1462 : }
1463 :
1464 902 : test();
1465 902 : if ( EQ_16( st->idchan, 1 ) || only_left )
1466 : {
1467 526 : *noise_seed = tmpSeed1;
1468 526 : move16();
1469 : }
1470 :
1471 303726 : FOR( ; i < L_frame + ( L_frame / 2 ) + 2 * L_FIR_FER2; i++ )
1472 : {
1473 302824 : random1 = Random( &tmpSeed1 );
1474 302824 : random2 = Random( &tmpSeed1 );
1475 302824 : noise[i] = add( shr( random1, noise_e ), shr( mult( alpha_coh, random2 ), sub( noise_e, e ) ) );
1476 302824 : move16();
1477 : }
1478 : }
1479 : ELSE
1480 : #endif /*IVAS_CODE_CON_TCX*/
1481 : {
1482 2532 : tmpSeed = st->seed_acelp; /*Q0*/
1483 2532 : move16();
1484 2532 : noise = buf;
1485 2532 : noise_e = 1; /*set exponent of noise to 1*/
1486 2532 : move16();
1487 :
1488 2532 : tmp_loop = add( L_frame, L_FIR_FER2 - 1 );
1489 1760332 : FOR( i = 0; i < tmp_loop; i++ )
1490 : {
1491 1757800 : Random( &tmpSeed );
1492 1757800 : noise[i] = shr( tmpSeed, noise_e ); /*Q: -noise_e*/
1493 1757800 : move16();
1494 : }
1495 2532 : st->seed_acelp = tmpSeed;
1496 2532 : move16();
1497 :
1498 2532 : tmp_loop = add( add( L_frame, shr( L_frame, 1 ) ), shl( L_FIR_FER2, 1 ) );
1499 899156 : FOR( ; i < tmp_loop; i++ )
1500 : {
1501 896624 : Random( &tmpSeed );
1502 896624 : noise[i] = shr( tmpSeed, noise_e ); /*Q: -noise_e*/
1503 896624 : move16();
1504 : }
1505 : }
1506 3434 : test();
1507 3434 : IF( EQ_16( st->last_good, VOICED_CLAS ) || EQ_16( st->last_good, ONSET ) )
1508 : {
1509 3421 : tmp16 = 19661 /*0.6f Q15*/;
1510 3421 : move16();
1511 3421 : if ( LE_32( st->output_Fs, 16000 ) )
1512 : {
1513 989 : tmp16 = 6554 /*0.2f Q15*/;
1514 989 : move16();
1515 : }
1516 :
1517 3421 : mem = noise[0];
1518 3421 : move16();
1519 3421 : preemph_copy_fx( &noise[1], &noise[1], tmp16, add( add( L_frame, shr( L_frame, 1 ) ), L_FIR_FER2 ), &mem );
1520 : }
1521 : /* high rate filter tuning */
1522 3434 : IF( LE_32( st->output_Fs, 16000 ) )
1523 : {
1524 11892 : FOR( i = 0; i < L_FIR_FER2; i++ )
1525 : {
1526 10901 : hp_filt[i] = h_high3_16[i]; /*Q15*/
1527 10901 : move16();
1528 : }
1529 : }
1530 : ELSE /*(st->output_Fs==32000)*/
1531 : {
1532 29316 : FOR( i = 0; i < L_FIR_FER2; i++ )
1533 : {
1534 26873 : hp_filt[i] = h_high3_32[i]; /*Q15*/
1535 26873 : move16();
1536 : }
1537 : }
1538 3434 : IF( EQ_16( st->nbLostCmpt, 1 ) )
1539 : {
1540 1515 : highPassFiltering_fx( st->last_good, add( add( L_frame, shr( L_frame, 1 ) ), L_FIR_FER2 ), noise, hp_filt, L_FIR_FER2 );
1541 : }
1542 : ELSE
1543 : {
1544 1919 : IF( GT_16( st->last_good, UNVOICED_TRANSITION ) )
1545 : {
1546 1919 : tmp_loop = add( add( L_frame, shr( L_frame, 1 ) ), L_FIR_FER2 );
1547 1919 : gain_tmp = negate( add( -32768, st->cummulative_damping ) ); /*Q15*/
1548 1895508 : FOR( i = 0; i < tmp_loop; i++ )
1549 : {
1550 : Word16 j;
1551 1893589 : L_tmp2 = 0;
1552 1893589 : move32();
1553 22723068 : FOR( j = 11; j > 0; j-- )
1554 : {
1555 20829479 : L_tmp2 = L_mac( L_tmp2, noise[( i + ( L_FIR_FER2 - j ) )], hp_filt[sub( L_FIR_FER2, j )] );
1556 : }
1557 1893589 : L_tmp2 = Mpy_32_16_1( L_tmp2, st->cummulative_damping /*Q15*/ ); /*Q0, noise_e*/
1558 1893589 : noise[i] = mac_r( L_tmp2, gain_tmp, noise[i] ); /*Q15, noise_e*/
1559 1893589 : move16();
1560 : }
1561 : }
1562 : }
1563 :
1564 : /* PLC: [TCX: Fade-out] retrieve background level */
1565 3434 : tmp16 = 32767;
1566 3434 : move16();
1567 3434 : IF( A_cng != NULL )
1568 : {
1569 902 : gainSynthDeemph = shr( getLevelSynDeemph_fx( &( tmp16 ), A_cng, M, shr( L_frame, 2 ), st->preemph_fac, 1, &gainSynthDeemph_e ), 2 ); /*Q13*/
1570 : }
1571 : ELSE
1572 : {
1573 2532 : gainSynthDeemph = getLevelSynDeemph_fx( &( tmp16 ), A_local, M, shr( L_frame, 2 ), st->preemph_fac, 1, &gainSynthDeemph_e ); /*Q13*/
1574 : }
1575 3434 : IF( st->tcxonly != 0 )
1576 : {
1577 : /* gainCNG = st->conCngLevelBackgroundTrace/gainSynthDeemph; */
1578 3434 : BASOP_Util_Divide_MantExp( hTcxDec->conCngLevelBackgroundTrace,
1579 3434 : hTcxDec->conCngLevelBackgroundTrace_e,
1580 : gainSynthDeemph, gainSynthDeemph_e,
1581 : &gainCNG, &gainCNG_e );
1582 3434 : test();
1583 3434 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && A_cng != NULL )
1584 : {
1585 902 : IF( GT_16( st->nbLostCmpt, add( MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME, MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN ) ) )
1586 : {
1587 0 : gainCNG = 0;
1588 0 : move16();
1589 : }
1590 902 : ELSE IF( GT_16( st->nbLostCmpt, MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME ) )
1591 : {
1592 : // gainCNG *= 1.f - (float)(st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME) / MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN;
1593 0 : L_tmp = L_sub( ONE_IN_Q31, imult3216( 107374182 /* 1 / MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN in Q31*/, sub( st->nbLostCmpt, MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME ) ) ); /* Q31 */
1594 0 : gainCNG = extract_l( Mpy_32_32( gainCNG, L_tmp ) ); /*Q15-gainCNG_e*/
1595 : }
1596 : }
1597 : }
1598 : ELSE
1599 : {
1600 : /* gainCNG = st->cngTDLevel/gainSynthDeemph; */
1601 0 : BASOP_Util_Divide_MantExp( st->cngTDLevel,
1602 0 : st->cngTDLevel_e,
1603 : gainSynthDeemph, gainSynthDeemph_e,
1604 : &gainCNG, &gainCNG_e );
1605 : }
1606 :
1607 3434 : gain32 = L_add( st->Mode2_lp_gainc, 0 ); /* start-of-the-frame gain - Q16*/
1608 3434 : IF( EQ_16( st->rf_frame_type, RF_TCXTD1 ) && EQ_16( st->use_partial_copy, 1 ) )
1609 : {
1610 0 : gain32 = Mpy_32_16_1( gain32, 22938 /*0.7f Q15*/ ); /*Q16*/
1611 : }
1612 3434 : L_tmp = L_shl( gain32, 1 ); /*Q16*/
1613 :
1614 3434 : IF( GT_32( L_shl( L_deposit_h( gainCNG ), sub( gainCNG_e, 31 - 16 ) /*Q16*/ ), L_tmp ) )
1615 : {
1616 3 : gainCNG_e = sub( 15 + 1, norm_l( L_tmp ) );
1617 3 : gainCNG = extract_l( L_shr( L_tmp, gainCNG_e ) ); /*Q15,gainCNG_e*/
1618 3 : gainCNG_e = sub( gainCNG_e, 1 );
1619 : }
1620 :
1621 : /* st->Mode2_lp_gainc = alpha * (st->Mode2_lp_gainc) + (1.0f - alpha) * gainCNG;*/ /* end-of-the-frame gain */
1622 :
1623 3434 : L_tmp = Mpy_32_16_1( st->Mode2_lp_gainc, alpha ) /*Q15*/;
1624 3434 : L_tmp2 = L_mult( sub( 16384 /*1.f Q14*/, alpha ) /*Q14*/, gainCNG /*Q15,gainCNG_e*/ ); /*Q30,gainCNG_e*/
1625 3434 : st->Mode2_lp_gainc = BASOP_Util_Add_Mant32Exp( L_tmp, 31 - 15, L_tmp2, add( gainCNG_e, 31 - 30 ), &tmp_e ); /*Q31-tmp_e*/
1626 3434 : st->Mode2_lp_gainc = L_shl( st->Mode2_lp_gainc, sub( tmp_e, 31 - 16 ) ); /*Q16*/
1627 3434 : move32();
1628 3434 : move32();
1629 :
1630 : /* PLC: [TCX: Fade-out] Linearly attenuate the gain through the frame */
1631 : /*step = (1.0f/L_frame) * (gain - (st->Mode2_lp_gainc));*/
1632 3434 : L_tmp = L_sub( gain32, st->Mode2_lp_gainc ); /*Q16*/
1633 3434 : tmp_e = norm_l( L_tmp );
1634 3434 : L_tmp = L_shl( L_tmp, tmp_e ); /*Q16,-tmp_e*/
1635 3434 : step32 = Mpy_32_16_1( L_tmp /*Q16,-tmp_e*/, getInvFrameLen( L_frame ) /*W16Q21*/ ); /*Q22,-tmp_e*/
1636 3434 : step32 = L_shl( step32, sub( 25 - 22, tmp_e ) ); /*Q25*/
1637 :
1638 3434 : pt_exc = noise + shr( L_FIR_FER2, 1 );
1639 :
1640 : /*gain_inov = 1.0f / (float)sqrt( dot_product( pt_exc, pt_exc, L_frame ) / L_frame + 0.01f );*/ /* normalize energy */
1641 3434 : L_tmp = Dot_productSq16HQ( 0, pt_exc /*Q0,15+1*/, L_frame, &tmp_e ) /*Q31,tmp_e+16+16*/;
1642 3434 : tmp_e = sub( add( tmp_e, shl( noise_e, 1 ) ), 1 ); // actual multiplier!
1643 3434 : L_tmp = Mpy_32_16_1( L_tmp, getInvFrameLen( L_frame ) /*W16Q21*/ ) /*W32Q37,tmp_e+16+16*/ /*Q5,tmp_e*/;
1644 3434 : tmp_e = add( tmp_e, 31 - 6 ); /*-->Q31*/
1645 3434 : gain_inov = 0;
1646 3434 : move16();
1647 3434 : gain_inov_e = 0;
1648 3434 : move16();
1649 3434 : IF( NE_32( L_tmp, 0 ) )
1650 : {
1651 3434 : gain_inov = round_fx( ISqrt32( L_tmp, &tmp_e ) ); /*Q15,tmp_e*/
1652 3434 : gain_inov_e = tmp_e;
1653 3434 : move16();
1654 : }
1655 3434 : test();
1656 3434 : test();
1657 3434 : IF( EQ_16( st->last_good, UNVOICED_CLAS ) && NE_16( st->core_ext_mode, UNVOICED ) )
1658 : {
1659 0 : gain_inov = mult_r( gain_inov, 26214 /*0.8f Q15*/ ); /*Q30*/
1660 : }
1661 3434 : ELSE IF( !( EQ_16( st->last_good, UNVOICED_CLAS ) || EQ_16( st->last_good, UNVOICED_TRANSITION ) ) )
1662 : {
1663 : /*gain_inov *= (1.1f- 0.75*st->lp_gainp);*/
1664 3434 : L_tmp = Mpy_32_16_1( L_sub( 590558016l /*1.1f Q29*/, Mpy_32_16_1( st->Mode2_lp_gainp, 24576 ) ) /*Q29*/, gain_inov /*Q15,gain_inov_e*/ ); /*Q29,gain_inov_e*/
1665 3434 : tmp_e = norm_l( L_tmp );
1666 3434 : L_tmp = L_shl( L_tmp, tmp_e );
1667 3434 : gain_inov_e = add( sub( gain_inov_e, tmp_e ), 31 - 29 ); /*->Q31*/
1668 3434 : gain_inov = round_fx_sat( L_tmp ); /*Q15,gain_inov_e*/
1669 : }
1670 :
1671 3434 : st->Mode2_lp_gainp = L_shr( L_deposit_h( alpha /*Q14*/ ) /*Q14+16*/, 1 ); /*Q29*/
1672 3434 : move32();
1673 :
1674 3434 : pt_exc = noise; /* non-causal ringing of the FIR filter */
1675 :
1676 3434 : tmp_e = norm_l( gain32 );
1677 3434 : tmp_e = sub( tmp_e, 5 ); /*5 Bit additional Headroom for the gain - should be enough*/
1678 3434 : gain32 = L_shl( gain32, tmp_e ); /*Q16,-tmp_e*/
1679 3434 : L_tmp = Mpy_32_16_1( gain32 /*Q16,-tmp_e*/, gain_inov /*Q15,gain_inov_e*/ ) /*Q16,gain_inov_e-tmp_e*/;
1680 :
1681 3434 : gain_tmp = round_fx( L_tmp ); /*Q0, gain_inov_e-tmp_e*/
1682 :
1683 20604 : FOR( i = 0; i < L_FIR_FER2 / 2; i++ )
1684 : {
1685 17170 : *pt_exc = mult_r( *pt_exc, gain_tmp ); /*Q-15,noise_e+gain_inov_e-tmp_e*/
1686 17170 : move16();
1687 17170 : pt_exc++;
1688 : }
1689 3434 : tmp16 = add( L_frame, L_FIR_FER2 / 2 );
1690 3434 : step32_tmp = L_shl( step32 /*Q25*/, sub( tmp_e, 25 - 16 ) ); /*Q16,-tmp_e*/
1691 2337084 : FOR( i = 0; i < tmp16; i++ ) /* Actual filtered random part of excitation */
1692 : {
1693 2333650 : *pt_exc = mult_r( *pt_exc, gain_tmp ); /*Q-15,noise_e+gain_inov_e-tmp_e*/
1694 2333650 : move16();
1695 2333650 : pt_exc++;
1696 2333650 : gain32 = L_sub( gain32 /*Q16,-tmp_e*/, step32_tmp ); /*Q16,-tmp_e*/
1697 2333650 : gain_tmp = mult_r( round_fx( gain32 /*Q16,-tmp_e*/ ) /*Q0*/, gain_inov /*Q15,gain_inov_e*/ ) /*Q0,gain_inov_e-tmp_e*/;
1698 : }
1699 3434 : tmp16 = shr( L_frame, 1 );
1700 1161674 : FOR( i = 0; i < tmp16; i++ ) /* causal ringing of the FIR filter */
1701 : {
1702 1158240 : *pt_exc = mult_r( *pt_exc, gain_tmp ); /*Q-15,noise_e+gain_inov_e-tmp_e*/
1703 1158240 : move16();
1704 1158240 : pt_exc++;
1705 : }
1706 3434 : noise_e = add( sub( add( noise_e, gain_inov_e ), tmp_e ), 15 ); /*--> noise is Q0, noise_e*/
1707 : /*buf[0;L_FIR_FER2 + L_Frame + L_Frame/2] Q0, noise_e*/
1708 :
1709 : /*-----------------------------------------------------------------*
1710 : * Construct the total excitation
1711 : *-----------------------------------------------------------------*/
1712 :
1713 3434 : IF( GE_16( st->last_good, UNVOICED_TRANSITION ) )
1714 : {
1715 3434 : tmp16 = add( L_frame, shr( L_frame, 1 ) );
1716 3478154 : FOR( i = 0; i < tmp16; i++ )
1717 : {
1718 3474720 : exc[i] = add_sat( exc[i], shl_sat( noise[i + ( L_FIR_FER2 / 2 )], add( Q_exc, noise_e ) ) ); /*Q1*/
1719 3474720 : move16();
1720 : }
1721 : }
1722 : ELSE
1723 : {
1724 0 : bufferCopyFx( noise + L_FIR_FER2 / 2, exc, add( L_frame, shr( L_frame, 1 ) ), 0 /*Q_noise*/, noise_e, Q_exc, 0 /*exc_e*/ );
1725 0 : Copy( exc + sub( L_frame, shl( L_subfr, 1 ) ), hTcxDec->old_excFB_fx, add( shl( L_subfr, 1 ), shr( L_frame, 1 ) ) ); /*Q_exc*/
1726 : /* copy old_exc as 16kHz for acelp decoding */
1727 0 : IF( EQ_16( st->nbLostCmpt, 1 ) )
1728 : {
1729 0 : lerp( exc, st->old_exc_fx, L_EXC_MEM_DEC, add( L_frame, shr( L_frame, 1 ) ) );
1730 : }
1731 : ELSE
1732 : {
1733 0 : Copy( st->old_exc_fx + L_FRAME16k, st->old_exc_fx, L_FRAME16k / 2 ); /*Q_exc*/
1734 0 : lerp( exc, st->old_exc_fx + L_FRAME16k / 2, L_FRAME16k, L_frame );
1735 : }
1736 0 : st->Q_exc = Q_exc;
1737 0 : move16();
1738 : }
1739 : /*buf[0;L_FIR_FER2 + L_Frame + L_Frame/2] Q0, noise_e*/
1740 : /*buf[OLD_EXC_SIZE_DEC;3/2 L_frame] Q1*/
1741 :
1742 : /* Update Pitch Lag memory */
1743 3434 : Copy32( &st->old_pitch_buf_fx[st->nb_subfr], st->old_pitch_buf_fx, st->nb_subfr ); /*Q16*/
1744 3434 : Copy32( pitch_buf, &st->old_pitch_buf_fx[st->nb_subfr], st->nb_subfr ); /*Q16*/
1745 :
1746 : /*----------------------------------------------------------*
1747 : * - compute the synthesis speech *
1748 : *----------------------------------------------------------*/
1749 :
1750 3434 : syn = buf + M; /*Q_syn*/
1751 3434 : Copy( synth - M, buf, M ); /*Q_syn*/
1752 :
1753 3434 : new_Q = sub( Q_exc, 3 );
1754 3434 : new_Q = s_max( new_Q, -1 );
1755 3434 : new_Q = s_min( new_Q, norm_s( tmp_deemph ) );
1756 :
1757 3434 : tmp16 = s_min( new_Q, st->prev_Q_syn );
1758 3434 : st->prev_Q_syn = new_Q;
1759 3434 : move16();
1760 :
1761 3434 : exp_scale = sub( tmp16, sub( Q_exc, 1 ) );
1762 3434 : Q_syn = tmp16;
1763 3434 : move16();
1764 :
1765 3434 : Copy_Scale_sig( buf, mem_syn, M, exp_scale ); /* Q: tmp16 */
1766 :
1767 3434 : tmp_deemph = shl_sat( tmp_deemph, Q_syn );
1768 3434 : st->Q_syn = Q_syn;
1769 3434 : move16();
1770 :
1771 : /*buf[OLD_EXC_SIZE_DEC;3/2 L_frame] Q1: exc*/
1772 : /*buf[0;M] Q0: mem_syn*/
1773 3434 : IF( A_cng != NULL )
1774 : {
1775 : Word16 alpha_delayed;
1776 :
1777 902 : alpha_delayed = 16384; /*1.0f in Q14*/
1778 902 : move16();
1779 902 : IF( GT_16( st->nbLostCmpt, MDCT_ST_PLC_FADEOUT_DELAY_4_LSP_FADE ) )
1780 : {
1781 294 : alpha_delayed = Damping_fact_fx( st->core_ext_mode, st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_DELAY_4_LSP_FADE, st->last_good, st->stab_fac_fx, &( st->Mode2_lp_gainp ), ACELP_CORE ); /*Q14*/
1782 : }
1783 :
1784 902 : test();
1785 902 : IF( st->plcBackgroundNoiseUpdated && NE_16( alpha_delayed, 16384 ) )
1786 : {
1787 : Word16 lsp_local[M], lsp_fade[M], alpha_inv;
1788 :
1789 0 : alpha_inv = sub( 16384 /*Q.0f in Q14*/, alpha_delayed ); /*Q14*/
1790 :
1791 0 : E_LPC_a_lsp_conversion( A_local, lsp_local, lsp_local, M );
1792 :
1793 0 : FOR( i = 0; i < M; i++ )
1794 : {
1795 0 : lsp_fade[i] = add( mult_r( alpha_delayed, lsp_local[i] ), mult_r( alpha_inv, st->lspold_cng[i] ) ); /*Q14*/
1796 0 : move16();
1797 : }
1798 :
1799 0 : Scale_sig( lsp_fade, M, 1 ); /* Q14 -> Q15 */
1800 :
1801 0 : E_LPC_f_lsp_a_conversion( lsp_fade, A_local, M );
1802 : }
1803 : }
1804 :
1805 3434 : E_UTIL_synthesis(
1806 3434 : sub( Q_exc, Q_syn ),
1807 : A_local,
1808 : &exc[0],
1809 : &syn[0],
1810 3434 : add( L_frame, shr( L_frame, 1 ) ),
1811 : mem_syn,
1812 : 1,
1813 : M );
1814 :
1815 : /*buf[OLD_EXC_SIZE_DEC;3/2 L_frame-1] Q1: exc*/
1816 : /*buf[0;M-1] Q0: mem_syn*/
1817 : /*buf[M;3/2 L_frame-1] Q-1: syn*/
1818 :
1819 3434 : n = extract_h( L_mult( L_frame, 9216 /*(float)N_ZERO_MDCT_NS/(float)FRAME_SIZE_NS Q15*/ ) ); /*Q0*/
1820 :
1821 : /* update ACELP synthesis memory */
1822 3434 : mem_syn_r_size_old = shr( L_frame, 4 ); /* replace 1.25/20.0 by shr(4) */
1823 : /* copy mem_syn as 16kHz */
1824 3434 : mem_syn_r_size_new = shr( L_FRAME16k, 4 ); /* replace 1.25/20.0 by shr(4) */
1825 :
1826 3434 : Copy( syn + sub( L_frame, L_SYN_MEM ), st->mem_syn_r, L_SYN_MEM ); /*Q_syn*/
1827 3434 : lerp( st->mem_syn_r + sub( L_SYN_MEM, mem_syn_r_size_old ), st->mem_syn_r + sub( L_SYN_MEM, mem_syn_r_size_new ), mem_syn_r_size_new, mem_syn_r_size_old );
1828 3434 : Copy( st->mem_syn_r + L_SYN_MEM - M, st->mem_syn2_fx, M ); /*Q_syn*/
1829 :
1830 : /* Deemphasis and output synth and ZIR */
1831 3434 : deemph_fx( syn, st->preemph_fac, add( L_frame, shr( L_frame, 1 ) ), &tmp_deemph );
1832 3434 : bufferCopyFx( syn + sub( L_frame, M + 1 ), st->syn, 1 + M, Q_syn, 0, 0, 0 ); /*Q_syn*/
1833 :
1834 :
1835 3434 : lerp( syn + sub( L_frame, shr( L_frame, 1 ) ), hTcxDec->old_syn_Overl, shr( st->L_frame, 1 ), shr( L_frame, 1 ) );
1836 3434 : Copy( syn + sub( L_frame, n ), hHQ_core->old_out_fx, sub( L_frame, n ) ); /*Q_syn*/
1837 :
1838 510164 : FOR( i = 0; i < W12; i++ )
1839 : {
1840 506730 : hHQ_core->old_out_fx[( i + n )] = round_fx( Mpy_32_16_1( L_mult( w[i].v.re, w[i].v.re ), hHQ_core->old_out_fx[( i + n )] ) ); /*Q_syn*/
1841 506730 : move16();
1842 : }
1843 510164 : FOR( ; i < W1; i++ )
1844 : {
1845 506730 : hHQ_core->old_out_fx[( i + n )] = round_fx( Mpy_32_16_1( L_mult( w[( ( W12 - 1 ) - ( i - W12 ) )].v.im, w[( ( W12 - 1 ) - ( i - W12 ) )].v.im ), hHQ_core->old_out_fx[( i + n )] ) ); /*Q_syn*/
1846 506730 : move16();
1847 : }
1848 :
1849 3434 : set16_fx( &hHQ_core->old_out_fx[( W1 + n )], 0, n );
1850 :
1851 3434 : hHQ_core->Q_old_wtda = Q_syn;
1852 3434 : move16();
1853 :
1854 : /* As long as there is no synth scaling factor introduced, which
1855 : is given to the outside, there might occur overflows here */
1856 : BASOP_SATURATE_WARNING_OFF_EVS
1857 3434 : bufferCopyFx( syn, synth, L_frame, Q_syn, 0, 0, 0 ); /*Q_syn*/
1858 : BASOP_SATURATE_WARNING_ON_EVS
1859 :
1860 3434 : Copy_Scale_sig( syn + L_frame, hTcxDec->syn_OverlFB, shr( L_frame, 1 ), negate( Q_syn ) ); /*Q0*/
1861 :
1862 : /* copy total excitation exc2 as 16kHz for acelp mode1 decoding */
1863 3434 : IF( st->hWIDec != NULL )
1864 : {
1865 0 : lerp( exc, st->hWIDec->old_exc2_fx, L_EXC_MEM, L_frame );
1866 0 : lerp( syn, st->hWIDec->old_syn2_fx, L_EXC_MEM, L_frame );
1867 : }
1868 :
1869 3434 : st->bfi_pitch_fx /*Q6*/ = round_fx_sat( L_shl_sat( pitch_buf[sub( st->nb_subfr, 1 )] /*15Q16*/, 6 /*Q6*/ ) );
1870 3434 : move16();
1871 3434 : st->bfi_pitch_frame = st->L_frame;
1872 3434 : move16();
1873 :
1874 : /* create aliasing and windowing need for transition to TCX10/5 */
1875 : // bufferCopyFx( syn + L_frame, hTcxDec->syn_Overl_TDACFB, shr( L_frame, 1 ), Q_syn, 0, -1, 0 );
1876 3434 : Copy_Scale_sig( syn + L_frame, hTcxDec->syn_Overl_TDACFB, shr( L_frame, 1 ), sub( Q_syn, 1 ) );
1877 3434 : hTcxDec->Q_syn_Overl_TDACFB = sub( Q_syn, 1 );
1878 3434 : move16();
1879 :
1880 510164 : FOR( i = 0; i < W12; i++ )
1881 : {
1882 506730 : buf[i] = mult_r( hTcxDec->syn_Overl_TDACFB[i], w[i].v.re ); /*hTcxDec->Q_syn_Overl_TDACFB*/
1883 506730 : move16();
1884 : }
1885 510164 : FOR( ; i < W1; i++ )
1886 : {
1887 506730 : buf[i] = mult_r( hTcxDec->syn_Overl_TDACFB[i], w[( ( W12 - 1 ) - ( i - W12 ) )].v.im ); /*hTcxDec->Q_syn_Overl_TDACFB*/
1888 506730 : move16();
1889 : }
1890 :
1891 :
1892 510164 : FOR( i = 0; i < W2; i++ )
1893 : {
1894 506730 : hTcxDec->syn_Overl_TDACFB[i] = add_sat( buf[i], buf[( ( W1 - 1 ) - i )] ); /*hTcxDec->Q_syn_Overl_TDACFB*/
1895 506730 : move16();
1896 : }
1897 :
1898 510164 : FOR( i = 0; i < W2; i++ )
1899 : {
1900 506730 : hTcxDec->syn_Overl_TDACFB[( W2 + i )] = add_sat( buf[( W2 + i )], buf[( ( ( W1 - 1 ) - W2 ) - i )] ); /*hTcxDec->Q_syn_Overl_TDACFB*/
1901 506730 : move16();
1902 : }
1903 :
1904 510164 : FOR( i = 0; i < W12; i++ )
1905 : {
1906 506730 : hTcxDec->syn_Overl_TDACFB[i] = mult_r( hTcxDec->syn_Overl_TDACFB[i], w[i].v.re ); /*hTcxDec->Q_syn_Overl_TDACFB*/
1907 506730 : move16();
1908 : }
1909 510164 : FOR( ; i < W1; i++ )
1910 : {
1911 506730 : hTcxDec->syn_Overl_TDACFB[i] = mult_r( hTcxDec->syn_Overl_TDACFB[i], w[( ( W12 - 1 ) - ( i - W12 ) )].v.im ); /*hTcxDec->Q_syn_Overl_TDACFB*/
1912 506730 : move16();
1913 : }
1914 :
1915 3434 : st->hTcxCfg->tcx_curr_overlap_mode = FULL_OVERLAP;
1916 3434 : move16();
1917 :
1918 3434 : synth[-1] = pre_emph_buf; /*Q0*/
1919 3434 : move16();
1920 :
1921 : /* update memory for low band */
1922 3434 : st->Q_syn = Q_syn;
1923 3434 : move16();
1924 3434 : Scale_sig( hTcxDec->old_syn_Overl, shr( st->L_frame, 1 ), sub( -1, Q_syn ) ); /*Q_syn*/
1925 3434 : st->hTcxDec->Q_old_syn_Overl = -1;
1926 3434 : lerp( hTcxDec->syn_OverlFB, hTcxDec->syn_Overl, shr( st->L_frame, 1 ), shr( L_frame, 1 ) );
1927 3434 : lerp( hTcxDec->syn_Overl_TDACFB, hTcxDec->syn_Overl_TDAC, shr( st->L_frame, 1 ), shr( L_frame, 1 ) );
1928 3434 : hTcxDec->Q_syn_Overl_TDAC = hTcxDec->Q_syn_Overl_TDACFB;
1929 3434 : move16();
1930 3434 : lerp( st->hHQ_core->old_out_fx, st->hHQ_core->old_out_LB_fx, st->L_frame, L_frame );
1931 3434 : st->hHQ_core->Q_old_wtda_LB = Q_syn;
1932 3434 : st->old_enr_LP = Enr_1_Az_fx( A_local, L_SUBFR ); /*Q3*/
1933 3434 : move16();
1934 :
1935 3434 : return;
1936 : }
|