Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 : /*VERSIONINFO: File up to date with trunk rev. 39929*/
6 :
7 :
8 : #include <stdint.h>
9 : #include "options.h"
10 : #include <assert.h>
11 : #include "prot_fx.h"
12 : #include "basop_util.h"
13 : #include "rom_dec.h"
14 : extern const Word16 T_DIV_L_Frame[]; /*0Q15 * 2^-7 */
15 :
16 : /*Table 2^7 * 1/L_frame */
17 :
18 : #define L_SYN_BUF M + L_DIV_MAX + L_DIV_MAX
19 : #define L_EXC_BUF OLD_EXC_SIZE_DEC_16k + L_DIV_MAX + L_SUBFR + 1 + L_DIV_MAX / 2
20 :
21 : /*LOCAL FUNCTIONS*/
22 : static void memsynPrecission_fx( Word16 nbLostCmpt, Word16 *mem_syn, Word16 *exc, Word16 len, Word16 *s_16 );
23 :
24 :
25 : /***************************************************************
26 : * \brief Main concealment function for ACELP
27 : *
28 : *
29 : ****************************************************************/
30 :
31 0 : void con_acelp_fx(
32 : const Word16 A[], /*<! i Q12: coefficients NxAz[M+1] */
33 : const Word16 coder_type, /*<! i Q0 : ACELP coder type */
34 : Word16 synth[], /*<! i/o Qx : synthesis buffer, Headroom: 3 bits? */
35 : Word16 *pT, /*<! o Q0 : pitch for all subframe [4]pit_min..pit_max */
36 : Word16 *pgainT, /*<! o Q14: pitch gain for all subfr [4] 0...1.3 */
37 : const Word16 stab_fac, /*<! i Q15: stability of isf */
38 : Decoder_State *st,
39 : const Word16 *Qf_exc, /*<! i : Q format for excitation buffer */
40 : Word16 *Qf_mem_syn, /*<! i/o : Q format for st->mem_syn >rescaling done */
41 : Word16 *pitch_buffer, /* Q0 */
42 : Word16 *voice_factors, /* Q6 */
43 : Word16 *bwe_exc /* Qx */ )
44 : {
45 :
46 : Word16 i_subfr, i, T0; /*Q0*/
47 : Word16 tmp, tmp2, tmp_deemph;
48 : Word16 mem_syn[M], mem_syn2[M], *syn;
49 : Word16 *noise_buf;
50 : Word16 *exc, *harmonic_exc_buf, buf[L_EXC_MEM_DEC + M + L_FRAME_16k + L_FRAME_16k / 2]; /*Qf_exc*/
51 : const Word16 *p_A;
52 : Word32 pitch_buf[NB_SUBFR16k] /*15Q16*/;
53 : Word16 alpha; /*Q14*/
54 : Word16 step, gain, gainCNG, ftmp;
55 : Word16 *pt_exc;
56 : Word16 gain_inov;
57 : Word16 gainCNG_e; /*scaling Factor (exponent) of gainCNG*/
58 : Word16 Qf_syn; /*Q format and exponent of new synthesis*/
59 : Word16 *pt1_exc;
60 : Word32 tmp_tc; /*15Q16*/
61 : Word16 extrapolationFailed;
62 : Word32 predPitchLag; /*15Q16*/
63 : Word32 pc; /*float 15Q16*/
64 : Word16 fUseExtrapolatedPitch; /*int*/
65 : Word16 tmpSeed, Tc; /*Q0*/
66 : Word16 s_32;
67 : Word16 synthScaling;
68 0 : PWord16 const *w = st->hTcxCfg->tcx_mdct_window;
69 : Word16 W1, W2;
70 : Word16 nSubframes;
71 : Word16 s_16, s_gain_inov, s2;
72 : Word16 tmp_16, gain_16;
73 : Word32 tmp_32, gain_32, step_32;
74 : Word16 l_fir_fer;
75 : Word16 lpFiltAdapt[3];
76 : Word16 hp_filt[3];
77 : Word16 Qf_syn_new;
78 : Word16 exc_unv[L_FRAME_16k + L_FRAME_16k / 2];
79 : Word16 syn_unv[L_FRAME_16k + L_FRAME_16k / 2];
80 : Word16 mem_syn_unv[M];
81 : Word16 gain_lpc[NB_SUBFR16k];
82 : Word16 gain_lpc_e[NB_SUBFR16k];
83 : Word16 mem[M];
84 : Word16 h1[L_FRAME_16k / 4 + 1];
85 : Word16 gainSynthDeemph;
86 : Word16 gainSynthDeemph_e;
87 : Word16 l;
88 : Word16 g, g_e;
89 : Word16 n;
90 0 : const Word16 scale_h1 = 5;
91 : HQ_DEC_HANDLE hHQ_core;
92 : TCX_DEC_HANDLE hTcxDec;
93 0 : move16();
94 :
95 0 : hHQ_core = st->hHQ_core;
96 0 : hTcxDec = st->hTcxDec;
97 :
98 : /*Inits*/
99 0 : l_fir_fer = L_FIR_FER;
100 0 : move16();
101 :
102 0 : fUseExtrapolatedPitch = 0;
103 0 : move16();
104 0 : extrapolationFailed = 1;
105 0 : move16();
106 :
107 0 : alpha = 0;
108 0 : move16();
109 : /*st->Mode2_lp_gainc = L_shl(st->Mode2_lp_gainc,7);*/ /*rudiment, could be changed in the whole file but should work also*/
110 0 : pc = L_deposit_l( 0 );
111 :
112 : /*------------------------------------------------------------------------*
113 : * Initialize buffers *
114 : *------------------------------------------------------------------------*/
115 :
116 : /* set ACELP synthesis memory */
117 0 : Copy( st->mem_syn2_fx, mem_syn, M ); /* Q_syn */
118 :
119 : /* set excitation memory*/
120 0 : harmonic_exc_buf = buf + M; /*Qf_exc*/
121 0 : exc = harmonic_exc_buf + L_EXC_MEM_DEC; /*Qf_exc*/
122 0 : Copy( st->old_exc_fx, harmonic_exc_buf, L_EXC_MEM_DEC ); /*Q_exc*/
123 0 : exc[st->L_frame] = 0;
124 0 : move16();
125 :
126 : /*------------------------------------------------------------------------*
127 : * PLC: [ACELP:Extrapolate Pitch Lag]
128 : *------------------------------------------------------------------------*/
129 :
130 0 : if ( EQ_16( st->flagGuidedAcelp, 1 ) )
131 : {
132 0 : T0 = st->guidedT0;
133 0 : move16();
134 : }
135 :
136 0 : pitch_pred_linear_fit( st->nbLostCmpt, st->last_good,
137 0 : st->old_pitch_buf_fx,
138 : &st->old_fpitch,
139 0 : &predPitchLag, st->pit_min, st->pit_max, st->mem_pitch_gain, 0,
140 0 : st->plc_use_future_lag, &extrapolationFailed, st->nb_subfr );
141 0 : T0 = round_fx( predPitchLag ); /*Q0*/
142 :
143 0 : IF( extrapolationFailed != 0 )
144 : {
145 : /*------------------------------------------------------------------------*
146 : * - Construct adaptive codebook from side information *
147 : *------------------------------------------------------------------------*/
148 :
149 0 : IF( st->flagGuidedAcelp == 0 )
150 : {
151 0 : nSubframes = 0;
152 0 : move16();
153 : }
154 : ELSE
155 : {
156 0 : nSubframes = 2;
157 0 : move16();
158 : /* Construct adaptive codebook with T0, T0_frac, T0_res, gain_pit for 2 sub-frames */
159 0 : l = shl( L_SUBFR, 1 );
160 0 : FOR( i = 0; i < l; i++ )
161 : {
162 0 : exc[i] = exc[( i - st->guidedT0 )]; /*Qf_exc*/
163 0 : move16();
164 : }
165 : }
166 : }
167 : ELSE
168 : {
169 0 : nSubframes = 0;
170 0 : move16();
171 : }
172 :
173 0 : tmp_tc = st->old_fpitch; /*15Q16*/
174 0 : move32(); /* take the previous frame last pitch*/
175 0 : if ( nSubframes > 0 )
176 : {
177 0 : tmp_tc = L_deposit_h( st->guidedT0 ); /* take the transmit pitch*/ /* Q16 */
178 : }
179 :
180 : /* PLC: [ACELP: Fade-out]
181 : * PLC: calculate damping factor */
182 0 : alpha = Damping_fact_fx( coder_type, st->nbLostCmpt, st->last_good, stab_fac, &( st->Mode2_lp_gainp ), 0 ); /*Q14*/
183 0 : st->cummulative_damping = shl( mult( st->cummulative_damping, alpha ), 1 ); /*shl(Q15*Q14,1)=shl(Q14,1) = Q15*/
184 0 : move16();
185 0 : if ( EQ_16( st->nbLostCmpt, 1 ) )
186 : {
187 0 : st->cummulative_damping = 32767 /*1.f Q15*/; /*Q15*/
188 0 : move16();
189 : }
190 :
191 : /*-----------------------------------------------------------------*
192 : * PLC: [ACELP: adaptive codebook]
193 : * PLC: Construct the harmonic part of excitation
194 : *-----------------------------------------------------------------*/
195 :
196 0 : IF( GE_16( st->last_good, UNVOICED_TRANSITION ) )
197 : {
198 :
199 : /*---------------------------------------------------------------*
200 : * Last pitch cycle of the previous frame is repeatedly copied. *
201 : *---------------------------------------------------------------*/
202 :
203 0 : Tc = round_fx( tmp_tc ); /* Q0 */
204 : BASOP_SATURATE_WARNING_OFF_EVS /*if this ever saturates, it doesn't matter*/
205 0 : tmp = sub( shl_sat( abs_s( sub( T0, Tc ) ), 6 ), mult( 19661 /*0.15f Q17*/, shl_sat( Tc, 4 ) ) /*Q6*/ );
206 : BASOP_SATURATE_WARNING_ON_EVS
207 0 : test();
208 0 : test();
209 0 : test();
210 0 : if ( ( T0 > 0 ) && ( NE_16( T0, Tc ) ) && ( tmp < 0 ) && extrapolationFailed == 0 )
211 : {
212 0 : fUseExtrapolatedPitch = 1;
213 0 : move16();
214 : }
215 :
216 0 : pt_exc = exc;
217 0 : if ( st->enableGplc != 0 )
218 : {
219 0 : pt_exc = &exc[( nSubframes * L_SUBFR )]; /*Qf_exc*/
220 : }
221 0 : pt1_exc = pt_exc - Tc; /*Qf_exc*/
222 :
223 0 : IF( fUseExtrapolatedPitch != 0 )
224 : {
225 : /* Required because later pt1_exc[1] used in filtering points to exc[0]. To make it safe also for GPL pt_exc is used instead of exc */
226 0 : pt_exc[0] = 0;
227 0 : move16();
228 0 : pt_exc = harmonic_exc_buf; /*Qf_exc*/
229 0 : assert( pt_exc < pt1_exc - 1 );
230 : }
231 :
232 0 : IF( EQ_16( st->nbLostCmpt, 1 ) )
233 : {
234 : /* pitch cycle is first low-pass filtered */
235 :
236 : /*get filter coefficients*/
237 0 : genPlcFiltBWAdap_fx(
238 : st->sr_core, /*W32 Q0*/
239 : &lpFiltAdapt[0] /*Q15*/,
240 : 0,
241 0 : st->cummulative_damping /*Q15*/
242 : );
243 0 : FOR( i = 0; i < Tc; i++ )
244 : {
245 :
246 : /* *pt_exc++ = ( lpFiltAdapt[0] * pt1_exc[-1] + lpFiltAdapt[1] * pt1_exc[0] + lpFiltAdapt[2] * pt1_exc[1]);*/
247 0 : tmp_32 = L_mult( lpFiltAdapt[0], pt1_exc[-1] ); /*Q16 + Qf_exc*/
248 0 : tmp_32 = L_mac( tmp_32, lpFiltAdapt[1], pt1_exc[0] ); /*Q16 + Qf_exc*/
249 0 : tmp_16 = mac_r( tmp_32, lpFiltAdapt[2], pt1_exc[1] ); /*Qf_exc*/
250 0 : *pt_exc = tmp_16; /*Qf_exc*/
251 0 : move16();
252 0 : pt_exc++;
253 0 : pt1_exc++;
254 : }
255 : }
256 : ELSE
257 : {
258 : /* copy the first pitch cycle without low-pass filtering */
259 0 : FOR( i = 0; i < Tc; i++ )
260 : {
261 0 : *pt_exc++ = *pt1_exc++; /*Qf_exc*/
262 0 : move16();
263 : }
264 : }
265 :
266 0 : if ( fUseExtrapolatedPitch != 0 )
267 : {
268 0 : pt1_exc = harmonic_exc_buf; /*Qf_exc*/
269 : }
270 :
271 0 : l = add( st->L_frame, sub( imult1616( L_SUBFR, sub( 1, nSubframes ) ), Tc ) );
272 0 : FOR( i = 0; i < l; i++ )
273 : {
274 0 : *pt_exc++ = *pt1_exc++; /*Qf_exc*/
275 0 : move16();
276 : }
277 :
278 : /*-------------------------------------------------------*
279 : * PLC: [ACELP: adaptive codebook]
280 : * PLC: Resync pulse positions.
281 : *-------------------------------------------------------*/
282 :
283 0 : IF( nSubframes > 0 )
284 : {
285 0 : pitch_buf[0] = L_deposit_h( st->guidedT0 ); /*Q16*/
286 0 : move32();
287 0 : pitch_buf[1] = L_deposit_h( st->guidedT0 ); /*Q16*/
288 0 : move32();
289 : }
290 :
291 0 : IF( nSubframes > 0 )
292 : {
293 0 : pitch_buf[3] = pitch_buf[2] = pitch_buf[1]; /* do not resync on second half of frame */
294 0 : move32();
295 0 : move32();
296 0 : if ( EQ_16( st->nb_subfr, 5 ) )
297 : {
298 : /* for guided acelp cases and nSubframes=2, set pitch_buf[4] to avoid memory_access issues in post_decoder() */
299 0 : pitch_buf[4] = pitch_buf[3]; /*Q16*/
300 0 : move32();
301 : }
302 : }
303 : ELSE
304 : {
305 0 : IF( fUseExtrapolatedPitch != 0 )
306 : {
307 :
308 0 : get_subframe_pitch( st->nb_subfr, st->old_fpitch, predPitchLag, pitch_buf );
309 0 : PulseResynchronization_fx( harmonic_exc_buf, exc, st->L_frame, st->nb_subfr, st->old_fpitch, predPitchLag );
310 : }
311 : ELSE
312 : {
313 0 : set32_fx( pitch_buf, st->old_fpitch, st->nb_subfr ); /*15Q16*/
314 : }
315 : }
316 :
317 : /*------------------------------------------------------------*
318 : * PLC: [ACELP: adaptive codebook]
319 : * PLC: Create the harmonic part needed for the overlap-add.
320 : *------------------------------------------------------------*/
321 0 : pt_exc = exc + st->L_frame; /*Qf_exc*/
322 0 : pt1_exc = pt_exc - T0; /*Qf_exc*/
323 0 : if ( T0 == 0 )
324 : {
325 0 : pt1_exc = pt_exc - Tc;
326 : }
327 0 : l = shr( st->L_frame, 1 );
328 0 : FOR( i = 0; i < l; i++ )
329 : {
330 0 : *pt_exc++ = *pt1_exc++;
331 0 : move16();
332 : }
333 :
334 : /*-------------------------------------------------------*
335 : * PLC: [ACELP: adaptive codebook]
336 : * PLC: update the floating point pitch for consecutive loss
337 : *-------------------------------------------------------*/
338 :
339 0 : IF( fUseExtrapolatedPitch != 0 )
340 : {
341 0 : st->old_fpitch = predPitchLag; /*Q16*/
342 0 : move32();
343 0 : if ( EQ_16( st->flagGuidedAcelp, 1 ) )
344 : {
345 0 : st->old_fpitch = L_deposit_h( T0 ); /*Q16*/
346 0 : move32();
347 : }
348 : }
349 :
350 : /*-------------------------------------------------------*
351 : * PLC: [ACELP: adaptive BPF]
352 : * PLC: Accommodate the BPF
353 : *-------------------------------------------------------*/
354 :
355 0 : st->bpf_gain_param = 3; /*full BPF*/
356 0 : move16();
357 :
358 : /*-------------------------------------------------------*
359 : * PLC: [ACELP: adaptive codebook]
360 : * PLC: Calculate the initial gain and fade out step.
361 : *-------------------------------------------------------*/
362 :
363 : /* Compute pitch coherence (copied from decoder classifier)*/
364 :
365 0 : pc = L_abs( L_sub( L_add( pitch_buf[3], L_sub( pitch_buf[2], pitch_buf[1] ) ), pitch_buf[0] ) ); /*9Q6*/ /*> 15Q16*/
366 :
367 : /* mapping: floor(( 0.824[15Q15]-x[15Q0]*0.0733[0Q15] )*4) */
368 :
369 0 : pc = Mpy_32_16_1( L_shl( pc, 1 ) /*precompensate Q14 from table*/, /*15Q16*/
370 0 : T_256DIV_L_Frame[L_shr( L_msu0( 54000, shr( st->L_frame, 5 ), 2402 ), 15 - 2 )] ); /*Q16*/
371 :
372 0 : test();
373 0 : test(); /*test();*/
374 0 : IF( LE_16( st->last_good, UNVOICED_TRANSITION ) && ( EQ_16( coder_type, GENERIC ) ) && GT_32( pc, 6 * 2 * 32768 /*6(15Q16)*/ ) /*&& (stab_fac <= 0.5f)*/
375 : )
376 : {
377 0 : gain = 0;
378 0 : move16();
379 0 : st->Mode2_lp_gainp = L_deposit_l( 0 );
380 : }
381 : ELSE
382 : {
383 0 : gain = 0x4000 /*1 (1Q14)*/; /* start-of-the-frame gain */
384 0 : move16();
385 0 : st->Mode2_lp_gainp = L_shl( L_deposit_l( alpha ), 15 ); /*1Q14->2Q29*/
386 0 : move32();
387 : }
388 :
389 0 : tmp_16 = extract_l( L_shl( L_mac( -28000, st->L_frame, 95 ), 1 - 15 ) );
390 0 : tmp_16 = T_DIV_L_Frame[tmp_16];
391 0 : move16();
392 0 : tmp_32 = L_mult0( tmp_16, sub( gain, alpha ) ); /* 0Q15 * 2^-7 * 1Q14 -> 2Q29 * 2^-7*/
393 0 : tmp_32 = L_shr( tmp_32, 6 ); /*-> 1Q30*/
394 0 : step = round_fx( tmp_32 ); /*->1Q14*/
395 :
396 : /*FLC: step: 6.25e-5 .. 0.0045*/ /*-> s_step = -7*/
397 : /*lp_gainp : 0..0.2856..0.98*/
398 :
399 : /*-------------------------------------------------------*
400 : * PLC: [ACELP: Fade-out]
401 : * Apply fade out
402 : *-------------------------------------------------------*/
403 :
404 0 : tmp_16 = 0;
405 0 : move16();
406 0 : l = 0;
407 0 : move16();
408 0 : FOR( i_subfr = 0; i_subfr < st->nb_subfr; i_subfr++ )
409 : {
410 0 : pgainT[i_subfr] = gain; /*Q14*/
411 0 : move16();
412 0 : i = l;
413 0 : move16();
414 0 : l = add( l, L_SUBFR );
415 0 : FOR( ; i < l; i++ )
416 : {
417 : BASOP_SATURATE_WARNING_OFF_EVS
418 0 : exc[i] = mult_r( exc[i], shl_sat( gain, 1 ) ); /*overflow is first iteration because gain may be 1 after shift*/ /*Qf_exc*/
419 : BASOP_SATURATE_WARNING_ON_EVS
420 0 : move16();
421 0 : gain = sub( gain, step );
422 : }
423 : }
424 :
425 0 : l = add( st->L_frame, shr( st->L_frame, 1 ) );
426 0 : FOR( ; i < l; i++ )
427 : {
428 : BASOP_SATURATE_WARNING_OFF_EVS
429 0 : exc[i] = mult_r( exc[i], shl_sat( gain, 1 ) ); /*overflow is first iteration because gain may become 1 due to shift*/ /*Qf_exc*/
430 : BASOP_SATURATE_WARNING_ON_EVS
431 0 : move16();
432 0 : gain = sub( gain, step );
433 : }
434 :
435 0 : FOR( i = 0; i < st->nb_subfr; i++ )
436 : {
437 0 : pT[i] = round_fx( pitch_buf[i] ); /*Q0*/
438 0 : move16();
439 0 : pitch_buffer[i] = round_fx( pitch_buf[i] ); /*Q0*/
440 0 : move16();
441 : }
442 :
443 : /* update old exc without random part*/
444 0 : Copy( harmonic_exc_buf + st->L_frame, st->old_exc_fx, L_EXC_MEM_DEC ); /*Qf_exc*/
445 : }
446 : ELSE
447 : {
448 : /* No harmonic part */
449 0 : assert( (Word32) ( sizeof( buf ) / sizeof( buf[0] ) ) - M - L_EXC_MEM_DEC >= st->L_frame + st->L_frame / 2 );
450 0 : set16_fx( &exc[0], 0, add( st->L_frame, shr( st->L_frame, 1 ) ) );
451 :
452 0 : FOR( i = 0; i < st->nb_subfr; i++ )
453 : {
454 0 : pitch_buf[i] = L_deposit_h( st->pit_max ); /*15Q16*/
455 0 : move32();
456 0 : pgainT[i] = 0;
457 0 : move16();
458 0 : pT[i] = L_SUBFR; /*Q0*/
459 0 : move16();
460 0 : pitch_buffer[i] = L_SUBFR; /*Q0*/
461 0 : move16();
462 : }
463 :
464 0 : st->bpf_gain_param = 0; /*no BPF*/
465 0 : move16();
466 : }
467 :
468 : /*-----------------------------------------------------------------*
469 : * Construct the random part of excitation (5/2 st->L_frame + 2L_FIR_FER - 2)
470 : *
471 : * This is done in Q0 and will be corrected to current Q format of excitation
472 : * when doing "non-causal ringing of the FIR filter"
473 : *
474 : * search for "Scale from randomized buffer to excitation buffer"
475 : *-----------------------------------------------------------------*/
476 0 : noise_buf = buf; /*Qf_exc*/
477 0 : tmpSeed = st->seed_acelp;
478 0 : move16();
479 0 : l = add( st->L_frame, sub( l_fir_fer, 1 ) );
480 0 : FOR( i = 0; i < l; i++ )
481 : {
482 0 : Random( &tmpSeed );
483 0 : noise_buf[i] = tmpSeed; /*Q0*/
484 0 : move16();
485 : }
486 :
487 0 : st->seed_acelp = tmpSeed;
488 0 : move16();
489 0 : l = add( add( st->L_frame, shr( st->L_frame, 1 ) ), sub( l_fir_fer, 1 ) );
490 0 : FOR( ; i < l; i++ )
491 : {
492 0 : Random( &tmpSeed );
493 0 : noise_buf[i] = tmpSeed; /*Q0*/
494 0 : move16();
495 : }
496 :
497 : /*get filter coefficients*/
498 0 : genPlcFiltBWAdap_fx( st->sr_core, /*W32 Q0*/
499 : &hp_filt[0], /*Q15*/
500 : 1,
501 0 : st->cummulative_damping ); /*Q15*/
502 :
503 : /* PLC: [ACELP: Fade-out]
504 : * PLC: retrieve background level */
505 :
506 0 : tmp2 = shl( div_s( st->L_frame, shl( L_SUBFR, 3 ) ), 3 - 15 ); /*Q0*/
507 :
508 :
509 0 : tmp = 32767 /*1.0f Q15*/;
510 0 : move16();
511 0 : gainSynthDeemph = getLevelSynDeemph_fx( &( tmp ),
512 : A,
513 : M,
514 : L_SUBFR,
515 0 : st->preemph_fac,
516 : tmp2,
517 : &gainSynthDeemph_e );
518 :
519 :
520 : /*gainCNG=st->cngTDLevel/gainSynthDeemph;*/
521 0 : BASOP_Util_Divide_MantExp( st->cngTDLevel, st->cngTDLevel_e, gainSynthDeemph, gainSynthDeemph_e, &gainCNG, &gainCNG_e );
522 0 : gainCNG_e = sub( gainCNG_e, 15 - 5 ); /*Q15->Q5*/
523 0 : if ( gainCNG == 0 )
524 : {
525 0 : gainCNG_e = 0;
526 0 : move16();
527 : }
528 :
529 0 : gain_32 = st->Mode2_lp_gainc; /*15Q16 */ /* start-of-the-frame gain */
530 0 : move32();
531 :
532 0 : ftmp = round_fx_sat( L_shl_sat( gain_32, 1 ) ); /*Q0*/
533 : BASOP_SATURATE_WARNING_OFF_EVS
534 0 : tmp_16 = sub( shl_sat( gainCNG, sub( gainCNG_e, 5 /*Q5*/ ) ), ftmp ); /*Q0*/
535 : /*in case of overflow:*/
536 0 : test();
537 0 : if ( ( EQ_16( shl_sat( ftmp, sub( gainCNG_e, 1 ) ), MAXVAL_WORD16 ) ) && EQ_16( gainCNG, MAXVAL_WORD16 ) )
538 : {
539 0 : tmp_16 = 1;
540 0 : move16();
541 : }
542 : BASOP_SATURATE_WARNING_ON_EVS
543 :
544 0 : IF( tmp_16 > 0 )
545 : {
546 0 : gainCNG = ftmp /*Q0*/;
547 0 : move16();
548 0 : gainCNG_e = 5; /*-> Q5*/
549 0 : move16();
550 0 : s_16 = norm_s( gainCNG );
551 0 : gainCNG = shl( gainCNG, s_16 );
552 0 : gainCNG_e = sub( gainCNG_e, s_16 );
553 : }
554 :
555 : /* end-of-the-frame gain */
556 : /* st->Mode2_lp_gainc = alpha * st->Mode2_lp_gainc + (1.0f - alpha) * gainCNG;*/
557 0 : tmp_32 = Mpy_32_16_1( st->Mode2_lp_gainc /*Q16*/, alpha /*Q14*/ ); /*Q31-16 = Q15*/
558 0 : s_32 = norm_l( tmp_32 );
559 0 : tmp_32 = L_shl( tmp_32, s_32 );
560 0 : tmp_16 = round_fx( tmp_32 );
561 0 : s_16 = negate( s_32 );
562 0 : s_16 = sub( s_16, -1 - 15 ); /*->Q15*/
563 :
564 0 : tmp2 = sub( 16384 /*1 in Q14*/, alpha ); /*Q14*/
565 0 : tmp2 = mult( tmp2, gainCNG ); /*Q14+Q5 +1 -16 = Q4*/
566 0 : s2 = norm_s( tmp2 );
567 0 : tmp2 = shl( tmp2, s2 );
568 0 : s2 = add( negate( s2 ), gainCNG_e );
569 0 : s2 = sub( s2, 4 - 15 ); /*->Q15*/
570 :
571 0 : s_16 = BASOP_Util_Add_MantExp( tmp_16, s_16, tmp2, s2, &tmp_16 );
572 0 : st->Mode2_lp_gainc = L_shl( L_deposit_l( tmp_16 ), add( s_16, 1 ) ); /*Q16*/
573 0 : move32();
574 0 : test();
575 0 : IF( ( EQ_16( st->last_good, UNVOICED_TRANSITION ) ) && ( EQ_16( coder_type, GENERIC ) ) )
576 : {
577 0 : st->Mode2_lp_gainc = L_deposit_h( gainCNG ); /*Q21*/
578 0 : st->Mode2_lp_gainc = L_shr( st->Mode2_lp_gainc, sub( 5, gainCNG_e ) ); /*15Q16, no scaling*/
579 0 : move32();
580 0 : move32();
581 : }
582 :
583 0 : highPassFiltering_fx( st->last_good, add( st->L_frame, shr( l_fir_fer, 1 ) ), noise_buf, hp_filt, l_fir_fer );
584 :
585 0 : pt_exc = noise_buf + shr( l_fir_fer, 1 ); /*Qf_exc*/
586 :
587 : /*** Find energy normalization factor ***/
588 : /*gain_inov = 1.0f / (float)sqrt( dot_product( pt_exc, pt_exc, st->L_frame ) / st->L_frame );*/ /* normalize energy */ /*<--- FLC*/
589 :
590 : BASOP_SATURATE_WARNING_OFF_EVS /*norm_llQ31 at the end of Dot_productSq16HQ may throw an overflow, but result is okay*/
591 0 : tmp_32 = Dot_productSq16HQ( 0, pt_exc, st->L_frame, &s_32 ); /*Q31*/
592 : BASOP_SATURATE_WARNING_ON_EVS
593 0 : s_32 = add( s_32, 31 - 1 );
594 : /*scalingfactor is twice the headroom (at noise insertion onto the buffer), -1 (because of mult) +31 (Result is Q31) +s_32 (output scalingfactor of dot_product)*/
595 :
596 0 : tmp_16 = T_DIV_L_Frame[L_shl( L_mac( -28000, st->L_frame, 95 ), 1 - 15 )];
597 0 : move16();
598 0 : tmp_32 = Mpy_32_16_1( tmp_32, tmp_16 ); /* Q31 * 2^s_32 * 0Q15 * 2^-7 */
599 :
600 0 : s_32 = sub( s_32, 7 ); /*tmp_32 is Q31 * 2^s_32 */
601 :
602 : /*assure doing Isqrt not for 0*/
603 0 : IF( tmp_32 != 0 )
604 : {
605 0 : s_gain_inov = s_32;
606 0 : move16();
607 0 : tmp_32 = ISqrt32( tmp_32, &s_gain_inov ); /* Q31 - s_gain_inov */
608 : }
609 : ELSE
610 : {
611 0 : s_gain_inov = 0;
612 0 : move16();
613 0 : tmp_32 = 0;
614 0 : move16();
615 : }
616 :
617 :
618 0 : gain_inov = round_fx( tmp_32 ); /*Inverse sqrt*/ /* Q15 * 2^s_gain_inov */ /* Q15 - s_gain_inov */
619 :
620 : /* PLC: [ACELP: Fade-out]
621 : * PLC: Linearly attenuate the gain through the frame */
622 :
623 0 : step_32 = L_sub( gain_32, st->Mode2_lp_gainc ); /* 15Q16 */
624 0 : tmp_16 = extract_l( L_shl( L_mac( -28000, st->L_frame, 95 ), 1 - 15 ) );
625 0 : step_32 = Mpy_32_16_1( step_32, T_DIV_L_Frame[tmp_16] ); /* 15Q16 * 2^-7 = 15Q16 * Q15 * 2^-7 */
626 0 : step_32 = L_shr( step_32, 7 ); /* 15Q16 */
627 :
628 0 : test();
629 0 : if ( ( EQ_16( st->last_good, UNVOICED_CLAS ) ) && ( NE_16( coder_type, UNVOICED ) ) ) /* Attenuate somewhat on unstable unvoiced */
630 : {
631 0 : gain_inov = mult_r( gain_inov, 26214 /*0.8f Q15*/ ); /*Q15 * 2^s_gain_inov*/
632 : }
633 :
634 0 : IF( GE_16( st->last_good, UNVOICED_TRANSITION ) )
635 : {
636 : Word16 tilt_code;
637 :
638 : /*tilt_code = (float)(0.10f*(1.0f + st->voice_fac));*/
639 0 : tilt_code = mac_r( 214748368l /*0.1f Q31*/, 3277 /*0.1f Q15*/, st->voice_fac ); /*Q15*/
640 :
641 0 : gain_inov = mult_r( gain_inov, sub( 32767 /*1.0f Q15*/, tilt_code ) ); /* Q15 * 2^s_gain_inov */
642 : }
643 :
644 0 : pt_exc = noise_buf; /*Qf_exc*/
645 :
646 : /* non-causal ringing of the FIR filter */
647 :
648 : /* gain_16 = gain_32 = gain_inov * gain */
649 0 : gain_32 = Mpy_32_16_1( gain_32, gain_inov ); /* 15Q16 * Q15 * 2^s_gain_inov */
650 0 : gain_32 = L_shl_sat( gain_32, add( 15, s_gain_inov ) ); /* Q31 */
651 0 : gain_16 = round_fx_sat( gain_32 ); /* Q15 */
652 :
653 : /* step_32 = gain_inov * step */
654 0 : step_32 = Mpy_32_16_1( step_32, gain_inov ); /* 15Q16 * Q15 * 2^s_gain_inov */
655 0 : step_32 = L_shl( step_32, add( 15, s_gain_inov ) ); /* Q31 */
656 :
657 0 : g_e = norm_s( round_fx_sat( L_shl_sat( Mpy_32_16_1( st->Mode2_lp_gainc, gain_inov ), add( 15, s_gain_inov ) ) ) ); /* norm_s for gain*gain_inov at the end of the following loops */
658 0 : g_e = s_min( norm_s( gain_16 ), g_e );
659 0 : gain_16 = shl( gain_16, g_e ); /*Q15 + g_e*/
660 0 : gain_32 = L_shl( gain_32, g_e ); /*Q31 + g_e*/
661 0 : step_32 = L_shl( step_32, g_e ); /*Q31 + g_e*/
662 0 : l = shr( l_fir_fer, 1 );
663 0 : FOR( i = 0; i < l; i++ )
664 : {
665 : /* *pt_exc++ *= (gain_inov * gain); <=> *pt_exc++ *= gain_16; */ /*<-- FLC*/
666 0 : *pt_exc = mult_r( *pt_exc, gain_16 ); /* Q0 = Q0 * Q15 */
667 0 : move16();
668 0 : pt_exc++;
669 : }
670 :
671 : /* gain -= step; gain is updated after the loop and inside the loop gain_16 = gain_inov * gain is modified using gain_inov * (gain-step) = gain_inov * gain - gain_inov * step */ /*<-- FLC*/
672 0 : FOR( i = 0; i < st->L_frame; i++ )
673 : {
674 : /* *pt_exc++ *= (gain_inov * gain); <=> *pt_exc++ *= gain_16; */ /*<-- FLC*/
675 0 : *pt_exc = mult_r( *pt_exc, gain_16 ); /* Q0 = Q0 * Q15 */
676 0 : move16();
677 0 : pt_exc++;
678 :
679 0 : gain_32 = L_sub( gain_32, step_32 );
680 0 : gain_16 = round_fx( gain_32 ); /*Q15*/
681 : }
682 :
683 0 : l = add( shr( st->L_frame, 1 ), shr( l_fir_fer, 1 ) );
684 0 : FOR( i = 0; i < l; i++ )
685 : {
686 : /* *pt_exc++ *= (gain_inov * gain); <=> *pt_exc++ *= gain_16; */ /*<-- FLC*/
687 0 : *pt_exc = mult_r( *pt_exc, gain_16 ); /* Q0 = Q0 * Q15 */
688 0 : move16();
689 0 : pt_exc++;
690 : }
691 :
692 : /*store st->past_gcode*/
693 : /* at this point gain is equal to st->Mode2_lp_gainc, so we don't need to calculate gain at all */
694 0 : st->past_gcode = st->Mode2_lp_gainc; /*15Q16 */
695 0 : move32();
696 :
697 : /*-----------------------------------------------------------------*
698 : * PLC: [ACELP: general]
699 : * PLC: Construct the total excitation
700 : *-----------------------------------------------------------------*/
701 :
702 0 : IF( LT_16( st->last_good, UNVOICED_TRANSITION ) )
703 : {
704 0 : bufferCopyFx( noise_buf + shr( l_fir_fer, 1 ), exc, add( st->L_frame, shr( st->L_frame, 1 ) ), 0, *Qf_exc, negate( g_e ), 0 ); /*copy between different formats*/ /*Qf_exc*/
705 0 : Copy( harmonic_exc_buf + st->L_frame, st->old_exc_fx, L_EXC_MEM_DEC ); /*Qf_exc*/
706 0 : Copy( exc, exc_unv, add( st->L_frame, shr( st->L_frame, 1 ) ) ); /* Update exc_unv */ /*Qf_exc*/
707 : }
708 : ELSE
709 : {
710 : /* Update exc_unv */
711 0 : bufferCopyFx( noise_buf + shr( l_fir_fer, 1 ), exc_unv, add( st->L_frame, shr( st->L_frame, 1 ) ), 0, *Qf_exc, negate( g_e ), 0 ); /*copy between different formats*/ /*Qf_exc*/
712 : }
713 :
714 : /* Compute total excitation in noisebuffer to save memories */
715 0 : IF( GE_16( st->last_good, UNVOICED_TRANSITION ) )
716 : {
717 0 : Vr_add( exc, exc_unv, noise_buf, add( st->L_frame, 1 ) ); /*Qf_exc*/
718 : }
719 : ELSE
720 : {
721 0 : noise_buf = exc_unv; /*Qf_exc*/
722 : }
723 0 : IF( st->hBWE_TD != NULL )
724 : {
725 0 : IF( EQ_16( st->L_frame, L_FRAME ) )
726 : {
727 0 : interp_code_5over2_fx( noise_buf, bwe_exc, st->L_frame );
728 0 : set16_fx( voice_factors, st->last_voice_factor_fx, NB_SUBFR ); /* Q6 */
729 : }
730 : ELSE
731 : {
732 0 : interp_code_4over2_fx( noise_buf, bwe_exc, st->L_frame );
733 0 : set16_fx( voice_factors, st->last_voice_factor_fx, NB_SUBFR16k ); /* Q6 */
734 : }
735 : }
736 : /*----------------------------------------------------------*
737 : * - compute the synthesis speech *
738 : *----------------------------------------------------------*/
739 :
740 : /* Init syn buffer */
741 0 : syn = buf + M;
742 0 : Copy( st->mem_syn2_fx, buf, M ); /*Q_syn*/
743 :
744 0 : IF( EQ_16( st->nbLostCmpt, 1 ) )
745 : {
746 0 : IF( LT_16( st->last_good, UNVOICED_TRANSITION ) )
747 : {
748 0 : Copy( st->mem_syn2_fx, mem_syn_unv, M ); /*Q_syn*/
749 : }
750 : ELSE
751 : {
752 0 : set16_fx( mem_syn_unv, 0, M );
753 : }
754 : }
755 : ELSE
756 : {
757 0 : Copy( st->mem_syn_unv_back, mem_syn_unv, M ); /*Q_syn*/
758 : }
759 :
760 : /* voiced synth */
761 0 : IF( GE_16( st->last_good, UNVOICED_TRANSITION ) )
762 : {
763 0 : p_A = A;
764 0 : FOR( i_subfr = 0; i_subfr < st->L_frame; i_subfr += L_SUBFR )
765 : {
766 0 : tmp = 0;
767 0 : move16();
768 0 : set16_fx( h1, 0, L_SUBFR + 1 );
769 0 : set16_fx( mem, 0, M );
770 0 : h1[0] = 1024 /*1.0f/((float)(1 << scale_h1)) Q15*/;
771 0 : move16();
772 0 : E_UTIL_synthesis( 0, p_A, h1, h1, L_SUBFR, mem, 0, M ); /* impulse response of LPC */
773 0 : deemph_fx( h1, st->preemph_fac, L_SUBFR, &tmp ); /* impulse response of deemph */
774 :
775 : /* impulse response level = gain introduced by synthesis+deemphasis */
776 : /* i_subfr / L_SUBFR */
777 0 : tmp_16 = shr( i_subfr, Q6 );
778 : /* gain_lpc[i_subfr/L_SUBFR] = 1.f/(float)sqrt(dotp( h1, h1, L_SUBFR)); */
779 0 : tmp_32 = Dot_productSq16HQ( 0, h1, L_SUBFR, &gain_lpc_e[tmp_16] ); /*Q31*/
780 0 : tmp_32 = L_max( tmp_32, 1 );
781 0 : gain_lpc_e[tmp_16] = add( gain_lpc_e[tmp_16], shl( scale_h1, 1 ) );
782 0 : move16();
783 0 : gain_lpc[tmp_16] = round_fx( ISqrt32( tmp_32, &gain_lpc_e[tmp_16] ) ); /* Q15 - gain_lpc_e[tmp_16] */
784 0 : move16();
785 :
786 0 : p_A += ( M + 1 ); /* Pointer move */
787 : }
788 :
789 0 : g = 0;
790 0 : move16();
791 0 : FOR( i_subfr = 0; i_subfr < st->L_frame; i_subfr += L_SUBFR )
792 : {
793 : /* i_subfr / L_SUBFR */
794 0 : tmp_16 = shr( i_subfr, Q6 );
795 0 : g = mult_r( st->last_gain_syn_deemph, gain_lpc[tmp_16] ); /* Q15 - gain_lpc_e[tmp_16] */
796 0 : g_e = add_sat( st->last_gain_syn_deemph_e, gain_lpc_e[tmp_16] );
797 0 : g = shl_sat( g, g_e ); /* Q15 */
798 :
799 0 : FOR( i = 0; i < L_SUBFR; i++ )
800 : {
801 : /* exc[i_subfr + i] *= st->last_gain_syn_deemph*gain_lpc[j]; */
802 0 : exc[i_subfr + i] = mult_r( exc[( i_subfr + i )], g ); /*Qf_exc*/
803 0 : move16();
804 : }
805 : }
806 0 : l = add( st->L_frame, shr( st->L_frame, 1 ) );
807 0 : FOR( i = st->L_frame; i < l; i++ )
808 : {
809 0 : exc[i] = mult_r( exc[i], g ); /*Qf_exc*/
810 0 : move16();
811 : }
812 :
813 : /*Rescale the synthesis memory*/
814 0 : Qf_syn_new = *Qf_mem_syn;
815 0 : move16();
816 0 : Qf_syn = *Qf_mem_syn;
817 0 : move16();
818 0 : rescale_mem( Qf_exc, &Qf_syn_new, &Qf_syn, mem_syn, NULL, M, st->L_frame );
819 0 : synthScaling = sub( *Qf_exc, Qf_syn );
820 :
821 0 : p_A = A;
822 :
823 : /*in case of more than 5 consecutive concealed frames, improve precision of synthesis*/
824 0 : memsynPrecission_fx( st->nbLostCmpt, mem_syn, exc, st->L_frame, &s_16 );
825 0 : FOR( i_subfr = 0; i_subfr < st->L_frame; i_subfr += L_SUBFR )
826 : {
827 0 : E_UTIL_synthesis( synthScaling, p_A, &exc[i_subfr], &syn[i_subfr], L_SUBFR, mem_syn, 1, M );
828 0 : p_A += ( M + 1 );
829 : }
830 0 : Copy( mem_syn, mem_syn2, M ); /*Qf_syn + s_16*/
831 : /* synthesize ola*/
832 0 : E_UTIL_synthesis( synthScaling, p_A - ( M + 1 ), &exc[i_subfr], &syn[i_subfr], shr( st->L_frame, 1 ), mem_syn2, 0, M );
833 : }
834 :
835 0 : test();
836 0 : IF( GT_16( st->nbLostCmpt, 5 ) && ( s_16 > 0 ) )
837 : {
838 : /*scale back mem_syn, exc and synthesis*/
839 0 : Scale_sig( mem_syn, M, negate( s_16 ) ); /* Qf_syn */
840 0 : Scale_sig( syn, add( shr( st->L_frame, 1 ), st->L_frame ), negate( s_16 ) ); /* Qf_syn */
841 : /*Scale_sig(exc, add(shr(st->L_frame,1),st->L_frame) ,negate(s_16));*/
842 : }
843 :
844 :
845 : /* unvoiced synth */
846 :
847 0 : tmp = 0;
848 0 : move16();
849 0 : p_A = st->Aq_cng;
850 :
851 0 : FOR( i_subfr = 0; i_subfr < st->L_frame; i_subfr += L_SUBFR )
852 : {
853 0 : set16_fx( h1, 0, L_SUBFR + 1 );
854 0 : set16_fx( mem, 0, M );
855 0 : h1[0] = 1024 /*1.0f/((float)(1 << scale_h1)) Q15*/;
856 0 : move16();
857 0 : E_UTIL_synthesis( 0, p_A, h1, h1, L_SUBFR, mem, 0, M ); /* impulse response of LPC */
858 0 : deemph_fx( h1, st->preemph_fac, L_SUBFR, &tmp ); /* impulse response of deemph */
859 :
860 : /* impulse response level = gain introduced by synthesis+deemphasis */
861 : /* i_subfr / L_SUBFR */
862 0 : tmp_16 = shr( i_subfr, Q6 );
863 : /* gain_lpc[i_subfr/L_SUBFR] = 1.f/(float)sqrt(dotp( h1, h1, L_SUBFR)); */
864 0 : tmp_32 = Dot_productSq16HQ( 0, h1, L_SUBFR, &gain_lpc_e[tmp_16] ); /*Q31*/
865 0 : tmp_32 = L_max( tmp_32, 1 );
866 0 : gain_lpc_e[tmp_16] = add( gain_lpc_e[tmp_16], shl( scale_h1, 1 ) );
867 0 : move16();
868 0 : gain_lpc[tmp_16] = round_fx( ISqrt32( tmp_32, &gain_lpc_e[tmp_16] ) ); /* Q15 - gain_lpc_e[tmp_16] */
869 0 : move16();
870 :
871 0 : p_A += ( M + 1 ); /* Pointer move */
872 : }
873 :
874 0 : g = 0;
875 0 : move16();
876 0 : FOR( i_subfr = 0; i_subfr < st->L_frame; i_subfr += L_SUBFR )
877 : {
878 : /* i_subfr / L_SUBFR */
879 0 : tmp_16 = shr( i_subfr, Q6 );
880 0 : g = mult_r( st->last_gain_syn_deemph, gain_lpc[tmp_16] ); /* Q15 - gain_lpc_e[tmp_16] */
881 0 : g_e = add( st->last_gain_syn_deemph_e, gain_lpc_e[tmp_16] );
882 0 : g = shl_sat( g, g_e ); /*Q15*/
883 0 : FOR( i = 0; i < L_SUBFR; i++ )
884 : {
885 : /* exc[i_subfr + i] *= st->last_gain_syn_deemph*gain_lpc[j]; */
886 0 : exc_unv[( i_subfr + i )] = mult_r( exc_unv[add( i_subfr, i )], g ); /*Qf_exc*/
887 0 : move16();
888 : }
889 : }
890 0 : l = add( st->L_frame, shr( st->L_frame, 1 ) );
891 0 : FOR( i = st->L_frame; i < l; i++ )
892 : {
893 0 : exc_unv[i] = mult_r( exc_unv[i], g ); /*Qf_exc*/
894 0 : move16();
895 : }
896 :
897 : /* Update Qf_syn */
898 0 : Qf_syn_new = *Qf_mem_syn;
899 0 : move16();
900 0 : Qf_syn = *Qf_mem_syn;
901 0 : move16();
902 0 : rescale_mem( Qf_exc, &Qf_syn_new, &Qf_syn, mem_syn_unv, NULL, M, st->L_frame );
903 0 : synthScaling = sub( *Qf_exc, Qf_syn );
904 0 : *Qf_mem_syn = Qf_syn;
905 0 : move16();
906 :
907 0 : p_A = st->Aq_cng;
908 :
909 : /*in case of more than 5 consecutive concealed frames, improve precision of synthesis*/
910 0 : memsynPrecission_fx( st->nbLostCmpt, mem_syn_unv, exc_unv, st->L_frame, &s_16 ); /*Qf_syn + s_16*/
911 :
912 0 : FOR( i_subfr = 0; i_subfr < st->L_frame; i_subfr += L_SUBFR )
913 : {
914 0 : E_UTIL_synthesis( synthScaling, p_A, &exc_unv[i_subfr], &syn_unv[i_subfr], L_SUBFR, mem_syn_unv, 1, M );
915 0 : p_A += ( M + 1 );
916 : }
917 0 : Copy( mem_syn_unv, st->mem_syn_unv_back, M ); /*Qf_syn + s_16*/
918 :
919 0 : IF( LT_16( st->last_good, UNVOICED_TRANSITION ) )
920 : {
921 0 : Copy( mem_syn_unv, mem_syn, M ); /*Qf_syn + s_16*/
922 : /* unvoiced for ola */
923 0 : E_UTIL_synthesis( synthScaling, p_A - ( M + 1 ), &exc_unv[i_subfr], &syn_unv[i_subfr], shr( st->L_frame, 1 ), mem_syn_unv, 0, M );
924 : }
925 :
926 0 : test();
927 0 : IF( GT_16( st->nbLostCmpt, 5 ) && ( s_16 > 0 ) )
928 : {
929 : /*scale back mem_syn_unv, exc_unv and synthesis*/
930 0 : Scale_sig( mem_syn_unv, M, negate( s_16 ) ); /*Qf_syn*/
931 0 : IF( LT_16( st->last_good, UNVOICED_TRANSITION ) )
932 : {
933 0 : Scale_sig( mem_syn, M, negate( s_16 ) ); /*Qf_syn*/
934 0 : Scale_sig( syn_unv, add( shr( st->L_frame, 1 ), st->L_frame ), negate( s_16 ) ); /*Qf_syn*/
935 : }
936 : ELSE
937 : {
938 0 : Scale_sig( syn_unv, st->L_frame, negate( s_16 ) ); /*Qf_syn*/
939 : }
940 :
941 0 : Scale_sig( st->mem_syn_unv_back, M, negate( s_16 ) ); /*Qf_syn*/
942 :
943 : /*Scale_sig(exc_unv, add(shr(st->L_frame,1),st->L_frame) ,negate(s_16));*/
944 : }
945 :
946 : /* add separate synthesis buffers */
947 0 : IF( GE_16( st->last_good, UNVOICED_TRANSITION ) )
948 : {
949 0 : FOR( i = 0; i < st->L_frame; i++ )
950 : {
951 0 : syn[i] = add_sat( syn[i], syn_unv[i] ); /*Qf_syn*/
952 0 : move16();
953 : }
954 : }
955 : ELSE
956 : {
957 0 : Copy( syn_unv, syn, add( st->L_frame, shr( st->L_frame, 1 ) ) ); /*Qf_syn*/
958 : }
959 :
960 :
961 : /* update buffer for the classification */
962 : {
963 : Word16 pit16[NB_SUBFR16k];
964 : Word16 k;
965 0 : FOR( k = 0; k < st->nb_subfr; k++ )
966 : {
967 0 : pit16[k] = shl( extract_h( pitch_buf[k] ), 6 ); /*Q6*/
968 0 : move16();
969 : }
970 :
971 0 : FEC_clas_estim_fx(
972 : st,
973 : /*Opt_AMR_WB*/ 0, /*A*/
974 0 : st->L_frame,
975 : &( st->clas_dec ),
976 : coder_type,
977 : pit16,
978 : syn,
979 : &st->lp_ener_FER_fx,
980 : /**decision_hyst*/ NULL, /* i/o: hysteresis of the music/speech decision */
981 : /**UV_cnt*/ NULL, /* i/o: number of consecutives frames classified as UV */
982 : /**LT_UV_cnt*/ NULL, /* i/o: long term consecutives frames classified as UV */
983 : /**Last_ener*/ NULL, /* i/o: last_energy frame */
984 : /**locattack*/ NULL, /* i/o: detection of attack (mainly to localized speech burst) */
985 : /**lt_diff_etot*/ NULL, /* i/o: long-term total energy variation */
986 : /**amr_io_class*/ NULL, /* i/o: classification for AMR-WB IO mode */
987 : Qf_syn, /* i : Synthesis scaling */
988 : /**class_para*/ NULL, /* o : classification para. fmerit1 */
989 0 : st->mem_syn_clas_estim_fx, /* i/o: memory of the synthesis signal for frame class estimation */
990 : &st->classifier_Q_mem_syn, /*i/o : exponent for memory of synthesis signal for frame class estimation */
991 : -32768 /*-1.f Q15*/, /* i : LTP Gain */
992 : 0 /*CLASSIFIER_ACELP*/, /* i : signal classifier mode */
993 : 1 /*bfi*/, /* i : bad frame indicator */
994 : st->last_core_brate, /* i : bitrate of previous frame */
995 : -1 );
996 : }
997 :
998 : /* Update Pitch Lag memory */
999 0 : Copy32( &st->old_pitch_buf_fx[st->nb_subfr], st->old_pitch_buf_fx, st->nb_subfr ); /*15Q16*/
1000 0 : Copy32( pitch_buf, &st->old_pitch_buf_fx[st->nb_subfr], st->nb_subfr ); /*15Q16*/
1001 :
1002 : /*updating enr_old parameters*/
1003 0 : frame_ener_fx( st->L_frame, st->last_good, syn, round_fx( tmp_tc ), &( st->enr_old_fx ), 1, 0, 0, 0 );
1004 :
1005 0 : st->enr_old_fx = L_shl_sat( st->enr_old_fx, shl( negate( Qf_syn ), 1 ) ); /*Q0*/
1006 0 : move32();
1007 : /* update ACELP synthesis memory */
1008 0 : Copy( mem_syn, st->mem_syn2_fx, M ); /*Qf_syn*/
1009 0 : Copy( syn + st->L_frame - L_SYN_MEM, st->mem_syn_r, L_SYN_MEM ); /*Qf_syn*/
1010 :
1011 : /*Q_mem_syn_new = Q_mem_syn;*/ /*NOT "+synthScaling", cause mem_syn format is not changed*/
1012 : /* Deemphasis and output synth */
1013 0 : tmp_deemph = st->syn[M];
1014 0 : move16();
1015 :
1016 0 : E_UTIL_deemph2( *Qf_mem_syn, syn, st->preemph_fac, add( st->L_frame, shr( st->L_frame, 1 ) ), &tmp_deemph );
1017 :
1018 0 : Copy( syn, synth, st->L_frame );
1019 :
1020 0 : bufferCopyFx( syn + sub( st->L_frame, shr( st->L_frame, 1 ) ), hTcxDec->old_syn_Overl, shr( st->L_frame, 1 ), 0 /*Qf_syn*/, -1 /*Qf_old_xnq*/, 0, 0 /*Q_old_xnq*/ );
1021 :
1022 : /* save last half frame if next frame is TCX */
1023 0 : bufferCopyFx( syn + st->L_frame, hTcxDec->syn_Overl_TDAC, shr( st->L_frame, 1 ), 0 /*Qf_syn*/, -1 /*Qf_old_xnq*/, 0, 0 /*Q_old_xnq*/ );
1024 0 : hTcxDec->Q_syn_Overl_TDAC = add( st->Q_syn, -1 );
1025 0 : move16();
1026 0 : Copy( syn + sub( st->L_frame, M + 1 ), st->syn, 1 + M ); /*Qf_syn*/
1027 :
1028 : /* update old_Aq */
1029 0 : Copy( p_A - ( M + 1 ), st->old_Aq_12_8_fx, M + 1 ); /*Q12*/
1030 :
1031 :
1032 0 : Copy( syn + st->L_frame, hTcxDec->syn_Overl, shr( st->L_frame, 1 ) ); /*Qf_syn*/
1033 :
1034 : /* create aliasing and windowing */
1035 :
1036 0 : W1 = st->hTcxCfg->tcx_mdct_window_length;
1037 0 : move16();
1038 0 : W2 = shr( W1, 1 );
1039 0 : st->hTcxCfg->tcx_curr_overlap_mode = FULL_OVERLAP;
1040 0 : move16();
1041 :
1042 0 : n = extract_h( L_mult( st->L_frame, 9216 /*(float)N_ZERO_MDCT_NS/(float)FRAME_SIZE_NS Q15*/ ) ); /*Q0*/
1043 :
1044 0 : hHQ_core->Q_old_wtda_LB = getScaleFactor16( syn + sub( st->L_frame, n ),
1045 0 : sub( st->L_frame, n ) );
1046 0 : move16();
1047 :
1048 0 : bufferCopyFx( syn + sub( st->L_frame, n ), hHQ_core->old_out_LB_fx, sub( st->L_frame, n ), 0, 0, hHQ_core->Q_old_wtda_LB, 0 );
1049 0 : FOR( i = 0; i < W2; i++ )
1050 : {
1051 0 : hHQ_core->old_out_LB_fx[( i + n )] = round_fx( Mpy_32_16_1( L_mult( w[i].v.re, w[i].v.re ), hHQ_core->old_out_LB_fx[( i + n )] ) ); /* hHQ_core->q_old_outLB_fx */
1052 0 : move16();
1053 : }
1054 0 : FOR( ; i < W1; i++ )
1055 : {
1056 0 : hHQ_core->old_out_LB_fx[i + n] = round_fx( Mpy_32_16_1( L_mult( w[( W2 - ( 1 + ( i - W2 ) ) )].v.im, w[( W2 - ( 1 + ( i - W2 ) ) )].v.im ), hHQ_core->old_out_LB_fx[( i + n )] ) ); /* hHQ_core->q_old_outLB_fx */
1057 0 : move16();
1058 : }
1059 0 : set16_fx( &hHQ_core->old_out_LB_fx[( W1 + n )], 0, n );
1060 :
1061 0 : hHQ_core->Q_old_wtda = hHQ_core->Q_old_wtda_LB;
1062 0 : move16();
1063 :
1064 :
1065 0 : FOR( i = 0; i < W2; i++ )
1066 : {
1067 0 : buf[i] = mult_r( hTcxDec->syn_Overl_TDAC[i], w[i].v.re ); /*hTcxDec->Q_syn_Overl_TDAC*/
1068 0 : move16();
1069 : }
1070 0 : FOR( ; i < W1; i++ )
1071 : {
1072 0 : buf[i] = mult_r( hTcxDec->syn_Overl_TDAC[i], w[( ( W1 - 1 ) - i )].v.im ); /*hTcxDec->Q_syn_Overl_TDAC*/
1073 0 : move16();
1074 : }
1075 :
1076 :
1077 0 : FOR( i = 0; i < W2; i++ )
1078 : {
1079 0 : hTcxDec->syn_Overl_TDAC[i] = add( buf[i], buf[( ( W1 - 1 ) - i )] ); /* A-D */ /*hTcxDec->Q_syn_Overl_TDAC*/
1080 0 : move16();
1081 : }
1082 : /*-2*/
1083 0 : FOR( i = 0; i < W2; i++ )
1084 : {
1085 0 : hTcxDec->syn_Overl_TDAC[( W2 + i )] = add( buf[( W2 + i )], buf[( ( ( W1 - 1 ) - W2 ) - i )] ); /* B-C */ /*hTcxDec->Q_syn_Overl_TDAC*/
1086 0 : move16();
1087 : }
1088 :
1089 :
1090 0 : FOR( i = 0; i < W2; i++ )
1091 : {
1092 0 : hTcxDec->syn_Overl_TDAC[i] = mult_r( hTcxDec->syn_Overl_TDAC[i], w[i].v.re ); /*hTcxDec->Q_syn_Overl_TDAC*/
1093 0 : move16();
1094 : }
1095 :
1096 0 : FOR( ; i < W1; i++ )
1097 : {
1098 0 : hTcxDec->syn_Overl_TDAC[i] = mult_r( hTcxDec->syn_Overl_TDAC[i], w[( ( W1 - 1 ) - i )].v.im ); /*hTcxDec->Q_syn_Overl_TDAC*/
1099 0 : move16();
1100 : }
1101 :
1102 : /* update memory for full band */
1103 0 : lerp( hTcxDec->syn_Overl_TDAC, hTcxDec->syn_Overl_TDACFB, shr( hTcxDec->L_frameTCX, 1 ), shr( st->L_frame, 1 ) );
1104 0 : st->hTcxDec->Q_syn_Overl_TDACFB = st->hTcxDec->Q_syn_Overl_TDAC;
1105 0 : move16();
1106 0 : lerp( hTcxDec->syn_Overl, hTcxDec->syn_OverlFB, shr( hTcxDec->L_frameTCX, 1 ), shr( st->L_frame, 1 ) );
1107 0 : lerp( hHQ_core->old_out_LB_fx, hHQ_core->old_out_fx, hTcxDec->L_frameTCX, st->L_frame );
1108 :
1109 : /* copy total excitation exc2 as 16kHz for acelp mode1 decoding */
1110 0 : IF( st->hWIDec != NULL )
1111 : {
1112 0 : lerp( exc, st->hWIDec->old_exc2_fx, L_EXC_MEM, st->L_frame );
1113 0 : lerp( syn, st->hWIDec->old_syn2_fx, L_EXC_MEM, st->L_frame );
1114 : }
1115 0 : st->bfi_pitch_fx = shl( round_fx( pitch_buf[( st->nb_subfr - 1 )] ), 6 ); /*Q6*/
1116 0 : st->bfi_pitch_frame = st->L_frame;
1117 0 : move16();
1118 0 : move16();
1119 :
1120 0 : return;
1121 : }
1122 :
1123 0 : static void memsynPrecission_fx( Word16 nbLostCmpt, Word16 *mem_syn /*Qx*/, Word16 *exc /*Qx*/, Word16 len, Word16 *s_16 )
1124 : {
1125 0 : IF( GT_16( nbLostCmpt, 5 ) )
1126 : {
1127 : Word16 sf_mem_syn, sf_exc, k, tmp_loop, max, tmp, i;
1128 0 : tmp = 0;
1129 0 : move16();
1130 0 : *s_16 = 0;
1131 0 : move16();
1132 0 : max = 0;
1133 0 : move16();
1134 :
1135 : /*check energy of mem_syn*/
1136 0 : FOR( i = 0; i < M; i++ )
1137 : {
1138 : /*saturation doesn't matter*/
1139 : BASOP_SATURATE_WARNING_OFF_EVS
1140 0 : tmp = add_sat( tmp, abs_s( mem_syn[i] ) );
1141 : BASOP_SATURATE_WARNING_ON_EVS
1142 : }
1143 : /*if there is energy in scale_syn, then increase precision*/
1144 0 : IF( abs_s( tmp ) > 0 )
1145 : {
1146 0 : sf_mem_syn = getScaleFactor16( mem_syn, M );
1147 : /*sf_exc = getScaleFactor16(exc, add(shr(len,1),len));*/ /*this returns 0 if signal is 0*/
1148 0 : tmp_loop = add( shr( len, 1 ), len );
1149 0 : FOR( k = 0; k < tmp_loop; k++ )
1150 : {
1151 0 : max = s_max( max, abs_s( exc[k] ) );
1152 : }
1153 0 : sf_exc = norm_s( max );
1154 0 : if ( max == 0 )
1155 : {
1156 0 : sf_exc = 16;
1157 0 : move16();
1158 : }
1159 0 : *s_16 = s_max( sub( s_min( sf_exc, sf_mem_syn ), 5 ), 0 ) /*5 bits of headroom, scaling not smaller than 0*/;
1160 0 : move16();
1161 0 : Scale_sig( mem_syn, M, *s_16 ); /*Qx + s_16*/
1162 0 : Scale_sig( exc, add( shr( len, 1 ), len ), *s_16 ); /*Qx + s_16*/
1163 : }
1164 : }
1165 0 : }
|