Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 : #include <stdint.h>
5 : #include "options.h" /* Compilation switches */
6 : #include "cnst.h" /* Common constants */
7 : #include "prot_fx.h" /* Function prototypes */
8 :
9 : /*-------------------------------------------------------------------*
10 : * Local constants
11 : *-------------------------------------------------------------------*/
12 : #define AGC_FX 32113 /* 0.98f */
13 : #define SCLSYN_LAMBDA ( 9830 /*0.3f Q15*/ )
14 :
15 : /*========================================================================*/
16 : /* FUNCTION : FEC_scale_syn_fx() */
17 : /*------------------------------------------------------------------------*/
18 : /* PURPOSE : Smooth the speech energy evolution when */
19 : /* recovering after a BAD frame */
20 : /*------------------------------------------------------------------------*/
21 : /* INPUT ARGUMENTS : */
22 : /* _ (Word16) L_frame : length of the frame */
23 : /* _ (Word16) *update_flg : indication about resynthesis */
24 : /* _ (Word16) st_fx->clas_dec: frame classification */
25 : /* _ (Word16) last_good : last good frame classification */
26 : /* _ (Word16[]) synth : synthesized speech at Fs = 12k8 Hz Q_syn */
27 : /* _ (Word16[]) pitch : pitch values for each subframe Q0 */
28 : /* _ (Word32) L_enr_old :energy at the end of previous frame Q0 */
29 : /* _ (Word16) L_enr_q : transmitted energy for current frame Q0 */
30 : /* _ (Word16) coder_type : coder type */
31 : /* _ (Word16) st_fx->prev_bfi_fx: previous frame BFI */
32 : /* _ (Word16) st_fx->last_core_brate_fx: previous frame core bitrate */
33 : /* _ (Word16[]) mem_tmp : temp. initial synthesis filter states Q_syn */
34 : /* _ (Word16) Q_exc : quantized LSPs from frame end */
35 : /* _ (Word16) Q_syn : quantized LSPs from frame end */
36 : /*------------------------------------------------------------------------*/
37 : /* INPUT/OUTPUT ARGUMENTS : */
38 : /* _ (Word16[]) exc : excitation signal without enhancement Q_exc */
39 : /* _ (Word16[]) exc2 : excitation signal with enhancement Q_exc */
40 : /* _ (Word16[]) Aq : LP filter coefs (can be modified if BR) Q12 */
41 : /*------------------------------------------------------------------------*/
42 : /* OUTPUT ARGUMENTS : */
43 : /*------------------------------------------------------------------------*/
44 :
45 : /* _ (Word16[]) st_fx->mem_syn2 : initial synthesis filter states Q_syn */
46 : /* _ (Word16) st_fx->old_enr_LP : LP filter E of last Q5 */
47 : /* good voiced frame */
48 : /*------------------------------------------------------------------------*/
49 : /* RETURN ARGUMENTS : */
50 : /* _ None */
51 : /*========================================================================*/
52 :
53 : #ifndef REMOVE_EVS_DUPLICATES
54 : void FEC_scale_syn_fx(
55 : const Word16 L_frame, /* i : length of the frame */
56 : Word16 *update_flg, /* o: flag indicating re-synthesis after scaling*/
57 : Word16 clas, /* i/o: frame classification */
58 : const Word16 last_good, /* i: last good frame classification */
59 : Word16 *synth, /* i/o: synthesized speech at Fs = 12k8 Hz Q_syn*/
60 : const Word16 *pitch, /* i: pitch values for each subframe Q0*/
61 : Word32 L_enr_old, /* i: energy at the end of previous frame */
62 : Word32 L_enr_q, /* i: transmitted energy for current frame */
63 : const Word16 coder_type, /* i: coder type */
64 : const Word16 LSF_Q_prediction, /* i : LSF prediction mode */
65 : Word16 *scaling_flag, /* i/o: flag to indicate energy control of syn */
66 : Word32 *lp_ener_FEC_av, /* i/o: averaged voiced signal energy Q0*/
67 : Word32 *lp_ener_FEC_max, /* i/o: averaged voiced signal energy Q0*/
68 : const Word16 bfi, /* i: current frame BFI */
69 : const Word32 total_brate, /* i: total bitrate */
70 : const Word16 prev_bfi, /* i: previous frame BFI */
71 : const Word32 last_core_brate, /* i: previous frame core bitrate */
72 : Word16 *exc, /* i/o: excitation signal without enhancement */
73 : Word16 *exc2, /* i/o: excitation signal with enhancement */
74 : Word16 Aq[], /* i/o: LP filter coefs (can be modified if BR) Q12*/
75 : Word16 *old_enr_LP, /* i/o: LP filter E of last good voiced frame Q3*/
76 : const Word16 *mem_tmp, /* i: temp. initial synthesis filter states Q_syn*/
77 : Word16 *mem_syn, /* o: initial synthesis filter states Q_syn*/
78 : Word16 Q_exc,
79 : Word16 Q_syn,
80 : const Word16 avoid_lpc_burst_on_recovery, /* i : if true the excitation energy is limited if LP has big gain */
81 : const Word16 force_scaling /* i: force scaling */
82 : )
83 : {
84 : Word16 i;
85 : Word32 L_enr1, L_enr2;
86 : Word16 gain1, gain2, enr_LP;
87 : Word16 tmp, tmp2, exp, exp2;
88 : Word16 tmp3;
89 : Word32 L_tmp;
90 : Word16 scaling;
91 : Word32 ener_max, L_enr2_av, L_ener2_max;
92 : Word16 h1[L_FRAME / 2], tilt, pitch_dist, mean_pitch;
93 : Word16 k;
94 : Word32 L_mean_pitch;
95 :
96 : enr_LP = 0;
97 : move16();
98 : gain2 = 0;
99 : move16();
100 : gain1 = 0;
101 : move16();
102 : *update_flg = 0;
103 : move16();
104 : L_enr_old = L_max( 1, L_enr_old ); /* to avoid division by zero (*L_enr_old is always >= 0) */
105 : scaling = 16384;
106 : move16(); /* Q14*/
107 :
108 : /*-----------------------------------------------------------------*
109 : * Find the synthesis filter impulse response on voiced
110 : *-----------------------------------------------------------------*/
111 : test();
112 : IF( GE_16( clas, VOICED_TRANSITION ) && LT_16( clas, INACTIVE_CLAS ) )
113 : {
114 : IF( EQ_16( L_frame, L_FRAME ) )
115 : {
116 : enr_LP = Enr_1_Az_fx( Aq + ( NB_SUBFR - 1 ) * ( M + 1 ), L_SUBFR );
117 : }
118 : ELSE /* L_frame == L_FRAME16k */
119 : {
120 : enr_LP = Enr_1_Az_fx( Aq + ( NB_SUBFR16k - 1 ) * ( M + 1 ), L_SUBFR ); /*Q3*/
121 : }
122 : }
123 :
124 : /*-----------------------------------------------------------------*
125 : * Define when to scale the synthesis
126 : *-----------------------------------------------------------------*/
127 :
128 : IF( bfi )
129 : {
130 : *scaling_flag = 1;
131 : move16(); /* Always check synthesis on bad frames */
132 : }
133 : ELSE IF( prev_bfi )
134 : {
135 : test();
136 : IF( ( EQ_16( LSF_Q_prediction, AUTO_REGRESSIVE ) ) || ( EQ_16( LSF_Q_prediction, MOVING_AVERAGE ) ) )
137 : {
138 : *scaling_flag = 2;
139 : move16(); /* Decoded LSFs affected */
140 : }
141 : ELSE IF( NE_16( coder_type, TRANSITION ) )
142 : {
143 : *scaling_flag = 1;
144 : move16(); /* SN, but not TC mode - LSF still affected by the interpolation */
145 : }
146 : ELSE
147 : {
148 : *scaling_flag = 0;
149 : move16(); /* LSF still possibly affected due to interpolation */
150 : }
151 : scaling = 24576; /*1.5 Q14*/
152 : move16();
153 : }
154 : ELSE
155 : {
156 : test();
157 : IF( ( EQ_16( LSF_Q_prediction, AUTO_REGRESSIVE ) ) && ( EQ_16( *scaling_flag, 2 ) ) )
158 : {
159 : *scaling_flag = 2;
160 : move16(); /* Continue with energy control till the end of AR prediction */
161 : }
162 : ELSE IF( *scaling_flag > 0 )
163 : {
164 : ( *scaling_flag ) = sub( *scaling_flag, 1 ); /* If scaling flag was equal to 2, add one control frame to account for the LSF interpolation */
165 : move16();
166 : }
167 : scaling = 32767; /*2.0 Q14*/
168 : move16();
169 : }
170 :
171 : /*-----------------------------------------------------------------*
172 : * Find the energy/gain at the end of the frame
173 : *-----------------------------------------------------------------*/
174 :
175 : frame_ener_fx( L_frame, clas, synth, pitch[( L_frame >> 6 ) - 1], &L_enr2 /*Q0*/, 1, Q_syn, 3, 0 );
176 :
177 :
178 : test();
179 : test();
180 : IF( bfi || ( EQ_32( total_brate, ACELP_7k20 ) ) || ( EQ_32( total_brate, ACELP_8k00 ) ) )
181 : {
182 : /* previous frame erased and no TC frame */
183 : IF( *scaling_flag > 0 )
184 : {
185 : /*enr2 += 0.01f;*/
186 : L_enr2 = L_max( L_enr2, 1 ); /* L_enr2 is in Q0 */
187 :
188 : IF( bfi ) /* In all bad frames, limit the gain to 1 */
189 : {
190 : /* gain2 = (float)sqrt( enr_old / enr2 );*/
191 : L_tmp = Sqrt_Ratio32( L_enr_old, 0, L_enr2, 0, &exp2 );
192 : gain2 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */
193 :
194 : /*if( gain2 > 1.0f )gain2 = 1.0f;*/
195 : gain2 = s_min( gain2, 16384 );
196 :
197 : /* find the energy/gain at the beginning of the frame */
198 : frame_ener_fx( L_frame, clas, synth, pitch[0], &L_enr1 /*Q0*/, 1, Q_syn, 3, 0 );
199 :
200 : /*enr1 += 0.1f;*/
201 : L_enr1 = L_max( L_enr1, 1 ); /* L_enr2 is in Q0 */
202 :
203 : /*gain1 = (float)sqrt( enr_old / enr1 );*/
204 : L_tmp = Sqrt_Ratio32( L_enr_old, 0, L_enr1, 0, &exp2 );
205 : gain1 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */
206 :
207 : /*if( gain1 > 1.0f )gain1 = 1.0f;*/
208 : gain1 = s_min( gain1, 16384 ); /*Q14*/
209 : }
210 : ELSE /* good frame */
211 : {
212 : IF( L_enr_q == 0 ) /* If E info (FEC protection bits) is not available in the bitstream */
213 : {
214 : L_enr_q = L_enr2; /*Q0*/
215 : set16_fx( h1, 0, L_FRAME / 2 );
216 : h1[0] = 1024; /*1.0f in Q10*/
217 : move16();
218 : /*syn_filt( Aq+(3*(M+1)), M, h1, h1, L_FRAME/2, h1+(M+1), 0 );*/
219 : E_UTIL_synthesis( 1, Aq + ( 3 * ( M + 1 ) ), h1, h1, L_FRAME / 2, h1 + ( M + 1 ), 0, M );
220 :
221 : /*Compute tilt */
222 : /*rr0 = dotp( h1, h1, L_FRAME/2-1 ) + 0.1f;*/
223 : /*rr1 = dotp( h1, h1+1, L_FRAME/2-1 );*/
224 : /*tilt = rr1 / rr0;*/
225 : tilt = extract_h( L_shl_sat( get_gain( h1 + 1, h1, L_FRAME / 2 - 1 ), 15 ) ); /*Q15*/
226 : pitch_dist = 0;
227 : move16();
228 : L_mean_pitch = L_mult( pitch[0], 8192 /*1.0f in Q13*/ ); /*Q14*/
229 : FOR( k = 0; k < ( NB_SUBFR - 1 ); k++ )
230 : {
231 : pitch_dist = add( pitch_dist, abs_s( sub( pitch[k + 1], pitch[k] ) ) ); /*Q0*/
232 : L_mean_pitch = L_mac( L_mean_pitch, pitch[k + 1], 8192 ); /*Q14*/
233 : }
234 : /*pitch_dist /= (float)(NB_SUBFR-1); */
235 : pitch_dist = mult_r( shl( pitch_dist, 4 ), 10923 /*1/(float)(NB_SUBFR-1) in Q15*/ ); /*Q4*/
236 : /*mean_pitch /= (float)(NB_SUBFR);*/
237 : mean_pitch = extract_h( L_shl( L_mean_pitch, 4 ) ); /*Q4*/
238 :
239 :
240 : test();
241 : test();
242 : test();
243 : test();
244 : test();
245 : test();
246 : IF( ( GT_16( tilt, 22938 ) ) && /* HF resonnant filter */
247 : ( ( GT_16( pitch_dist, 8 << 4 ) ) || ( LT_16( mean_pitch, PIT_MIN << 4 ) ) ) && /* pitch unstable or very short */
248 : ( ( prev_bfi ) || ( ( EQ_16( coder_type, GENERIC ) ) && ( EQ_16( LSF_Q_prediction, AUTO_REGRESSIVE ) ) ) ) )
249 : {
250 : /*if( enr_q > scaling * enr_old ){enr_q = scaling * enr_old;}*/
251 : L_enr_q = L_min( L_enr_q, L_shl_sat( Mult_32_16( L_enr_old, scaling ), 1 ) ); /* scaling in Q14*/
252 : }
253 : ELSE
254 : {
255 : ener_max = *lp_ener_FEC_max; /*Q0*/
256 : move32();
257 : test();
258 : if ( EQ_16( clas, VOICED_TRANSITION ) || ( GE_16( clas, INACTIVE_CLAS ) ) )
259 : {
260 : ener_max = *lp_ener_FEC_av; /*Q0*/
261 : move32();
262 : }
263 : /*if( enr_old > ener_max )ener_max = enr_old;*/
264 : ener_max = L_max( ener_max, L_enr_old );
265 :
266 : /*if( enr_q > scaling * ener_max ){enr_q = scaling * ener_max;}*/
267 : L_enr_q = L_min( L_enr_q, L_shl_sat( Mult_32_16( ener_max, scaling ), 1 ) ); /* scaling in Q14*/
268 : }
269 : }
270 : /*gain2 = (float)sqrt( enr_q / enr2 );*/
271 : L_enr_q = L_max( L_enr_q, 1 ); /* L_enr2 is in Q0 */
272 : L_tmp = Sqrt_Ratio32( L_enr_q, 0, L_enr2, 0, &exp2 );
273 : gain2 = round_fx( L_shl( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */
274 :
275 : /*-----------------------------------------------------------------*
276 : * Find the energy/gain at the beginning of the frame to ensure smooth transition after erasure(s)
277 : *-----------------------------------------------------------------*/
278 :
279 : test();
280 : test();
281 : test();
282 : test();
283 : test();
284 : test();
285 : IF( ( ( GE_16( last_good, VOICED_TRANSITION ) && LT_16( last_good, INACTIVE_CLAS ) && ( clas == UNVOICED_CLAS || EQ_16( clas, INACTIVE_CLAS ) ) ) ||
286 : EQ_32( last_core_brate, SID_1k75 ) || EQ_32( last_core_brate, SID_2k40 ) || last_core_brate == FRAME_NO_DATA ) &&
287 : prev_bfi )
288 : {
289 : /* voiced -> unvoiced signal transition */
290 : /* CNG -> active signal transition */
291 : gain1 = gain2; /*Q14*/
292 : move16();
293 : }
294 : ELSE
295 : {
296 : /* find the energy at the beginning of the frame */
297 : frame_ener_fx( L_frame, clas, synth, pitch[0], &L_enr1 /*Q0*/, 1, Q_syn, 3, 0 );
298 :
299 : /*enr1 += 0.1f;*/
300 : L_enr1 = L_max( L_enr1, 1 ); /* L_enr1 is in Q0 */
301 :
302 : /*gain1 = (float)sqrt( enr_old / enr1 );*/
303 : L_tmp = Sqrt_Ratio32( L_enr_old, 0, L_enr1, 0, &exp2 );
304 : gain1 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */
305 :
306 : /*if( gain1 > 1.2f )gain1 = 1.2f;*/
307 : /* prevent clipping */
308 : gain1 = s_min( gain1, 19661 /*1.2f in Q14*/ );
309 :
310 : /* prevent amplifying the unvoiced or inactive part of the frame in case an offset is followed by an onset */
311 : test();
312 : test();
313 : if ( EQ_16( clas, ONSET ) && GT_16( gain1, gain2 ) && prev_bfi )
314 : {
315 : gain1 = gain2; /*Q14*/
316 : move16();
317 : }
318 : }
319 :
320 : L_enr2 = L_enr_q; /*Q0*/
321 : move32(); /* Set the end frame energy to the scaled energy, to be used in the lp_ener_FEC */
322 : }
323 :
324 : /*------------------------------------------------------------------------------*
325 : * Smooth the energy evolution by exponentially evolving from gain1 to gain2
326 : *------------------------------------------------------------------------------*/
327 :
328 : /*gain2 *= ( 1.0f - AGC );*/
329 : L_tmp = L_mult( gain2, (Word16) ( 32768 /*Q15*/ - AGC_FX ) ); /*Q30*/
330 : FOR( i = 0; i < L_frame; i++ )
331 : {
332 : /*gain1 = gain1 * AGC + gain2;*/
333 : gain1 = mac_r( L_tmp, gain1, AGC_FX ); /* in Q14 */
334 : /*exc[i] *= gain1;*/
335 : exc[i] = mac_r( L_mult( exc[i], gain1 ), exc[i], gain1 );
336 : move16();
337 : /*exc2[i] *= gain1;*/
338 : exc2[i] = mac_r_sat( L_mult( exc2[i], gain1 ), exc2[i], gain1 );
339 : move16();
340 : }
341 : /* smoothing is done in excitation domain, so redo synthesis */
342 : Copy( mem_tmp, mem_syn, M ); /* Q_syn */
343 : syn_12k8_fx( L_frame, Aq, exc2, synth, mem_syn, 1, Q_exc, Q_syn );
344 : *update_flg = 1;
345 : move16();
346 : }
347 : }
348 : ELSE
349 : {
350 : /* previous frame erased and no TC frame */
351 : test();
352 : IF( prev_bfi && NE_16( coder_type, TRANSITION ) )
353 : {
354 : IF( L_enr_q == 0 )
355 : {
356 : L_enr_q = L_max( 1, L_enr2 ); /* sets to 'L_enr2' in 1 clock */
357 : set16_fx( h1, 0, L_FRAME / 2 );
358 : h1[0] = 1024; /*1.0f in Q10*/
359 : move16();
360 : /*syn_filt( Aq+(3*(M+1)), M, h1, h1, L_FRAME/2, h1+(M+1), 0 );*/
361 : E_UTIL_synthesis( 1, Aq + ( 3 * ( M + 1 ) ), h1, h1, L_FRAME / 2, h1 + ( M + 1 ), 0, M );
362 : /*Compute tilt */
363 : /*rr0 = dotp( h1, h1, L_FRAME/2-1 ) + 0.1f;*/
364 : /*rr1 = dotp( h1, h1+1, L_FRAME/2-1 );*/
365 : /*tilt = rr1 / rr0;*/
366 : tilt = extract_h( L_shl_sat( get_gain( h1 + 1, h1, L_FRAME / 2 - 1 ), 15 ) ); /*Q15*/
367 : test();
368 : test();
369 : test();
370 : test();
371 : test();
372 : test();
373 : test();
374 : test();
375 : IF( ( ( ( EQ_32( total_brate, ACELP_13k20 ) ) || ( EQ_32( total_brate, ACELP_12k85 ) ) || ( EQ_32( total_brate, ACELP_12k15 ) ) || ( EQ_32( total_brate, ACELP_11k60 ) ) ||
376 : ( EQ_32( total_brate, ACELP_9k60 ) ) ) &&
377 : ( GT_16( tilt, 22938 ) ) && /* HF resonnant filter */
378 : ( ( ( clas == UNVOICED_CLAS ) ) || ( EQ_16( clas, INACTIVE_CLAS ) ) ) ) ) /* unvoiced classification */
379 : {
380 : /*if( enr_q > scaling * enr_old )enr_q = scaling * enr_old;*/
381 : L_enr_q = L_min( L_enr_q, L_shl_sat( Mult_32_16( L_enr_old, scaling ), 1 ) ); /* scaling in Q14*/
382 : }
383 : ELSE IF( GE_16( last_good, VOICED_TRANSITION ) && LT_16( last_good, INACTIVE_CLAS ) && GE_16( clas, VOICED_TRANSITION ) && LT_16( clas, INACTIVE_CLAS ) )
384 : {
385 : /* Voiced-voiced recovery */
386 : test();
387 : IF( *old_enr_LP != 0 && GT_16( enr_LP, shl_sat( *old_enr_LP, 1 ) ) )
388 : {
389 : /* enr_q /= enr_LP */
390 : exp = norm_l( L_enr_q );
391 : tmp = extract_h( L_shl( L_enr_q, exp ) );
392 :
393 : exp2 = norm_s( enr_LP );
394 : tmp2 = shl( enr_LP, exp2 );
395 :
396 : exp = sub( exp2, exp );
397 :
398 : tmp3 = sub( tmp, tmp2 );
399 : IF( tmp3 > 0 )
400 : {
401 : tmp = shr( tmp, 1 );
402 : exp = add( exp, 1 );
403 : }
404 : tmp = div_s( tmp, tmp2 );
405 :
406 : /* L_enr_q *= 2 * *old_enr_LP */
407 : L_enr_q = L_shl( L_mult( tmp, shl( *old_enr_LP, 1 ) ), exp );
408 : }
409 :
410 : ELSE
411 : {
412 : test();
413 : IF( avoid_lpc_burst_on_recovery && GT_16( enr_LP, 160 /*20.0f in Q3*/ ) )
414 : {
415 : exp = norm_s( enr_LP );
416 : tmp = shl( enr_LP, exp );
417 :
418 : exp2 = 7;
419 : move16();
420 : tmp2 = 160 << 7; /* 160 = 20.0f in Q3 */
421 : move16();
422 : exp = sub( exp2, exp );
423 :
424 : IF( GT_16( tmp, tmp2 ) )
425 : {
426 : tmp = shr( tmp, 1 );
427 : exp = add( exp, 1 );
428 : }
429 : tmp = div_s( tmp, tmp2 ); /* tmp*2^exp = enr_LP/20.0 */
430 : L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp ); /* L_tmp*2^exp = sqrt(20.0/enr_LP) */
431 : L_enr_q = L_shl( Mpy_32_32( L_enr_q, L_tmp ), exp );
432 : }
433 : }
434 : }
435 :
436 : test();
437 : test();
438 : test();
439 : test();
440 : IF( ( GE_16( last_good, VOICED_TRANSITION ) && LT_16( last_good, INACTIVE_CLAS ) && GE_16( clas, VOICED_TRANSITION ) && LT_16( clas, INACTIVE_CLAS ) ) || force_scaling )
441 : {
442 :
443 : IF( GT_32( L_enr_q, L_enr_old ) ) /* Prevent energy to increase on voiced */
444 : {
445 : L_enr_q = L_add( Mpy_32_16_1( L_enr_old, 32767 - SCLSYN_LAMBDA ), Mpy_32_16_1( L_enr_q, SCLSYN_LAMBDA ) ); /*Q0*/
446 : }
447 : }
448 : }
449 :
450 : L_enr_q = L_max( 1, L_enr_q );
451 :
452 : /* gain2 = (float)sqrt( enr_q / enr2 );*/
453 : exp = norm_l( L_enr_q );
454 : tmp = extract_h( L_shl( L_enr_q, exp ) );
455 :
456 : exp2 = norm_l( L_enr2 );
457 : tmp2 = extract_h( L_shl( L_enr2, exp2 ) );
458 :
459 : exp2 = sub( exp, exp2 ); /* Denormalize and substract */
460 :
461 : tmp3 = sub( tmp2, tmp );
462 : IF( tmp3 > 0 )
463 : {
464 : tmp2 = shr( tmp2, 1 );
465 : exp2 = add( exp2, 1 );
466 : }
467 :
468 : tmp = div_s( tmp2, tmp );
469 :
470 : L_tmp = L_deposit_h( tmp );
471 : L_tmp = Isqrt_lc( L_tmp, &exp2 );
472 : gain2 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */
473 : /*-----------------------------------------------------------------*
474 : * Clipping of the smoothing gain at the frame end
475 : *-----------------------------------------------------------------*/
476 :
477 : gain2 = s_min( gain2, 19661 /*1.2f in Q14*/ ); /* Gain modification clipping */
478 : if ( LT_32( L_enr_q, 2 ) )
479 : {
480 : gain2 = s_min( gain2, 16384 /*1.0f in Q14*/ ); /* Gain modification clipping */
481 : }
482 :
483 : /*-----------------------------------------------------------------*
484 : * Find the energy/gain at the beginning of the frame to ensure smooth transition after erasure(s)
485 : *-----------------------------------------------------------------*/
486 :
487 : test();
488 : test();
489 : test();
490 : test();
491 : test();
492 : test();
493 : IF( EQ_16( clas, SIN_ONSET ) ) /* slow increase */
494 : {
495 : gain1 = shr( gain2, 1 ); /*0.5f * gain2*/
496 : }
497 : /*------------------------------------------------------------*
498 : * voiced->unvoiced transition recovery
499 : *------------------------------------------------------------*/
500 : ELSE IF( ( GE_16( last_good, VOICED_TRANSITION ) && LT_16( last_good, INACTIVE_CLAS ) && ( clas == UNVOICED_CLAS || EQ_16( clas, INACTIVE_CLAS ) ) ) || /* voiced->unvoiced transition recovery */
501 : EQ_32( last_core_brate, SID_1k75 ) || EQ_32( last_core_brate, SID_2k40 ) || last_core_brate == FRAME_NO_DATA ) /* CNG -> active signal transition */
502 : {
503 : gain1 = gain2; /*Q14*/
504 : move16();
505 : }
506 : ELSE
507 : {
508 : /*--------------------------------------------------------*
509 : * Find the energy at the beginning of the frame
510 : *--------------------------------------------------------*/
511 : tmp = frame_ener_fx( L_frame, clas, synth, pitch[0], &L_enr1, 0, Q_syn, 3, 0 );
512 :
513 : /*gain1 = (float)sqrt( enr_old / enr1 );*/
514 : exp = norm_l( L_enr_old );
515 : tmp = extract_h( L_shl( L_enr_old, exp ) );
516 : exp2 = norm_l( L_enr1 );
517 : tmp2 = extract_h( L_shl( L_enr1, exp2 ) );
518 :
519 : exp2 = sub( exp, exp2 ); /* Denormalize and substract */
520 :
521 : tmp3 = sub( tmp2, tmp );
522 :
523 : IF( tmp3 > 0 )
524 : {
525 : tmp2 = shr( tmp2, 1 );
526 : exp2 = add( exp2, 1 );
527 : }
528 :
529 : tmp = div_s( tmp2, tmp );
530 :
531 : L_tmp = L_deposit_h( tmp );
532 : L_tmp = Isqrt_lc( L_tmp, &exp2 );
533 : gain1 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */
534 : /* exp2 is always <= 1 */
535 :
536 : gain1 = s_min( gain1, 19661 /*1.2F in Q14*/ );
537 :
538 : test();
539 : test();
540 : if ( avoid_lpc_burst_on_recovery && ( GT_16( enr_LP, 160 ) ) && ( LE_16( enr_LP, shl_sat( *old_enr_LP, 1 ) ) ) )
541 : {
542 : gain1 = s_min( gain1, 16384 /*1.0f in Q14*/ );
543 : }
544 :
545 : /*--------------------------------------------------------*
546 : * Prevent a catastrophy in case of offset followed by onset
547 : *--------------------------------------------------------*/
548 : test();
549 : if ( ( EQ_16( clas, ONSET ) ) && ( GT_16( gain1, gain2 ) ) )
550 : {
551 : gain1 = gain2; /*Q14*/
552 : move16();
553 : }
554 : }
555 : /*-----------------------------------------------------------------*
556 : * Smooth the energy evolution by exponentially evolving from
557 : * gain1 to gain2
558 : *-----------------------------------------------------------------*/
559 :
560 : L_tmp = L_mult( gain2, (Word16) ( 32768 /*Q15*/ - AGC_FX ) );
561 :
562 : FOR( i = 0; i < L_frame; i++ )
563 : {
564 : gain1 = mac_r( L_tmp, gain1, AGC_FX ); /* in Q14 */
565 : exc[i] = mac_r_sat( L_mult_sat( exc[i], gain1 ), exc[i], gain1 );
566 : move16();
567 : exc2[i] = mac_r_sat( L_mult_sat( exc2[i], gain1 ), exc2[i], gain1 );
568 : move16();
569 : }
570 :
571 : Copy( mem_tmp, mem_syn, M ); /* Q_syn */
572 : syn_12k8_fx( L_frame, Aq, exc2, synth, mem_syn, 1, Q_exc, Q_syn );
573 : *update_flg = 1;
574 : move16();
575 : }
576 : }
577 : /*-----------------------------------------------------------------*
578 : * Update low-pass filtered energy for voiced frames
579 : *-----------------------------------------------------------------*/
580 :
581 : test();
582 : test();
583 : IF( !bfi && ( GE_16( clas, VOICED_TRANSITION ) && LT_16( clas, INACTIVE_CLAS ) ) )
584 : {
585 : IF( EQ_16( clas, VOICED_TRANSITION ) )
586 : {
587 : L_enr2_av = L_enr2; /*Q0*/
588 : move32();
589 : frame_ener_fx( L_frame, VOICED_CLAS, synth, pitch[sub( shr( L_frame, 6 ), 1 )], &L_ener2_max /*Q0*/, 1, Q_syn, 3, 0 );
590 : }
591 : ELSE
592 : {
593 : L_ener2_max = L_enr2; /*Q0*/
594 : move32();
595 : frame_ener_fx( L_frame, UNVOICED_CLAS, synth, pitch[sub( shr( L_frame, 6 ), 1 )], &L_enr2_av /*Q0*/, 1, Q_syn, 3, 0 );
596 : }
597 :
598 : /**lp_ener_FEC_av = 0.2f * enr2_av + 0.8f * *lp_ener_FEC_av; move32();*/
599 : *lp_ener_FEC_av = Madd_32_16( Mult_32_16( *lp_ener_FEC_av, 31130 /*0.95f in Q15*/ ), L_enr2_av, 1638 /*0.05F Q15*/ ); /*Q0*/
600 : move32();
601 : /**lp_ener_FEC_max = 0.2f * enr2_max + 0.8f * *lp_ener_FEC_max; move32();*/
602 : *lp_ener_FEC_max = Madd_32_16( Mult_32_16( *lp_ener_FEC_max, 31130 /*0.95f in Q15*/ ), L_ener2_max, 1638 /*0.05F Q15*/ ); /*Q0*/
603 : move32();
604 : }
605 :
606 : /*-----------------------------------------------------------------*
607 : * Update the LP filter energy for voiced frames
608 : *-----------------------------------------------------------------*/
609 : test();
610 : if ( GE_16( clas, VOICED_TRANSITION ) && LT_16( clas, INACTIVE_CLAS ) )
611 : {
612 : *old_enr_LP = enr_LP; /*Q3*/
613 : move16();
614 : }
615 :
616 : return;
617 : }
618 : #endif
619 140736 : void FEC_scale_syn_ivas_fx(
620 : const Word16 L_frame, /* i : length of the frame */
621 : Word16 *update_flg, /* o: flag indicating re-synthesis after scaling*/
622 : Word16 clas, /* i/o: frame classification */
623 : const Word16 last_good, /* i: last good frame classification */
624 : Word16 *synth, /* i/o: synthesized speech at Fs = 12k8 Hz Q_syn*/
625 : const Word16 *pitch, /* i: pitch values for each subframe Q0*/
626 : Word32 L_enr_old, /* i: energy at the end of previous frame */
627 : Word32 L_enr_q, /* i: transmitted energy for current frame */
628 : const Word16 coder_type, /* i: coder type */
629 : const Word16 LSF_Q_prediction, /* i : LSF prediction mode */
630 : Word16 *scaling_flag, /* i/o: flag to indicate energy control of syn */
631 : Word32 *lp_ener_FEC_av, /* i/o: averaged voiced signal energy Q0*/
632 : Word32 *lp_ener_FEC_max, /* i/o: averaged voiced signal energy Q0*/
633 : const Word16 bfi, /* i: current frame BFI */
634 : const Word32 total_brate, /* i: total bitrate */
635 : const Word16 prev_bfi, /* i: previous frame BFI */
636 : const Word32 last_core_brate, /* i: previous frame core bitrate */
637 : Word16 *exc, /* i/o: excitation signal without enhancement */
638 : Word16 *exc2, /* i/o: excitation signal with enhancement */
639 : Word16 Aq[], /* i/o: LP filter coefs (can be modified if BR) Q12*/
640 : Word16 *old_enr_LP, /* i/o: LP filter E of last good voiced frame Q3*/
641 : const Word16 *mem_tmp, /* i: temp. initial synthesis filter states Q_syn*/
642 : Word16 *mem_syn, /* o: initial synthesis filter states Q_syn*/
643 : Word16 Q_exc,
644 : Word16 Q_syn,
645 : #ifdef REMOVE_EVS_DUPLICATES
646 : const Word16 element_mode, /* i : element mode */
647 : #endif
648 : const Word16 avoid_lpc_burst_on_recovery, /* i : if true the excitation energy is limited if LP has big gain */
649 : const Word16 force_scaling /* i: force scaling */
650 : )
651 : {
652 : Word16 i;
653 : Word32 L_enr1, L_enr2;
654 : Word16 gain1, gain2, enr_LP;
655 : Word16 tmp, tmp2, exp, exp2;
656 : Word16 tmp3;
657 : Word32 L_tmp;
658 : Word16 scaling;
659 : Word32 ener_max, L_enr2_av, L_ener2_max;
660 : Word16 h1[L_FRAME / 2], tilt, pitch_dist, mean_pitch;
661 : Word16 k;
662 : Word32 L_mean_pitch;
663 :
664 140736 : enr_LP = 0;
665 140736 : move16();
666 140736 : gain2 = 0;
667 140736 : move16();
668 140736 : gain1 = 0;
669 140736 : move16();
670 140736 : *update_flg = 0;
671 140736 : move16();
672 140736 : L_enr_old = L_max( 1, L_enr_old ); /* to avoid division by zero (*L_enr_old is always >= 0) */
673 140736 : scaling = 16384;
674 140736 : move16(); /* Q14*/
675 :
676 : /*-----------------------------------------------------------------*
677 : * Find the synthesis filter impulse response on voiced
678 : *-----------------------------------------------------------------*/
679 140736 : test();
680 140736 : IF( GE_16( clas, VOICED_TRANSITION ) && LT_16( clas, INACTIVE_CLAS ) )
681 : {
682 81679 : IF( EQ_16( L_frame, L_FRAME ) )
683 : {
684 44331 : enr_LP = Enr_1_Az_fx( Aq + ( NB_SUBFR - 1 ) * ( M + 1 ), L_SUBFR );
685 : }
686 : ELSE /* L_frame == L_FRAME16k */
687 : {
688 37348 : enr_LP = Enr_1_Az_fx( Aq + ( NB_SUBFR16k - 1 ) * ( M + 1 ), L_SUBFR ); /*Q3*/
689 : }
690 : }
691 :
692 : /*-----------------------------------------------------------------*
693 : * Define when to scale the synthesis
694 : *-----------------------------------------------------------------*/
695 :
696 140736 : IF( bfi )
697 : {
698 0 : *scaling_flag = 1;
699 0 : move16(); /* Always check synthesis on bad frames */
700 : }
701 140736 : ELSE IF( prev_bfi )
702 : {
703 1602 : test();
704 1602 : IF( ( EQ_16( LSF_Q_prediction, AUTO_REGRESSIVE ) ) || ( EQ_16( LSF_Q_prediction, MOVING_AVERAGE ) ) )
705 : {
706 1344 : *scaling_flag = 2;
707 1344 : move16(); /* Decoded LSFs affected */
708 : }
709 258 : ELSE IF( NE_16( coder_type, TRANSITION ) )
710 : {
711 102 : *scaling_flag = 1;
712 102 : move16(); /* SN, but not TC mode - LSF still affected by the interpolation */
713 : }
714 : ELSE
715 : {
716 156 : *scaling_flag = 0;
717 156 : move16(); /* LSF still possibly affected due to interpolation */
718 : }
719 1602 : scaling = 24576; /*1.5 Q14*/
720 1602 : move16();
721 : }
722 : ELSE
723 : {
724 139134 : test();
725 139134 : IF( ( EQ_16( LSF_Q_prediction, AUTO_REGRESSIVE ) ) && ( EQ_16( *scaling_flag, 2 ) ) )
726 : {
727 550 : *scaling_flag = 2;
728 550 : move16(); /* Continue with energy control till the end of AR prediction */
729 : }
730 138584 : ELSE IF( *scaling_flag > 0 )
731 : {
732 1996 : ( *scaling_flag ) = sub( *scaling_flag, 1 ); /* If scaling flag was equal to 2, add one control frame to account for the LSF interpolation */
733 1996 : move16();
734 : }
735 139134 : scaling = 32767; /*2.0 Q14*/
736 139134 : move16();
737 : }
738 :
739 : /*-----------------------------------------------------------------*
740 : * Find the energy/gain at the end of the frame
741 : *-----------------------------------------------------------------*/
742 :
743 140736 : tmp = sub( 3, getScaleFactor16( synth, L_frame ) );
744 :
745 : #ifdef REMOVE_EVS_DUPLICATES
746 140736 : test();
747 140736 : IF( tmp > 0 && GT_16( element_mode, EVS_MONO ) )
748 : #else
749 : IF( tmp > 0 )
750 : #endif
751 3803 : {
752 : Word16 synth_tmp[L_FRAME16k];
753 3803 : Copy_Scale_sig( synth, synth_tmp, L_frame, -tmp ); // Q_synth - tmp
754 3803 : frame_ener_fx( L_frame, clas, synth_tmp, pitch[L_frame / L_SUBFR - 1], &L_enr2 /*Q0*/, 1, sub( Q_syn, tmp ), 3, 0 );
755 : }
756 : ELSE
757 : {
758 136933 : frame_ener_fx( L_frame, clas, synth, pitch[L_frame / L_SUBFR - 1], &L_enr2 /*Q0*/, 1, Q_syn, 3, 0 );
759 : }
760 :
761 140736 : test();
762 140736 : test();
763 140736 : IF( bfi || ( EQ_32( total_brate, ACELP_7k20 ) ) || ( EQ_32( total_brate, ACELP_8k00 ) ) )
764 : {
765 : /* previous frame erased and no TC frame */
766 55 : IF( *scaling_flag > 0 )
767 : {
768 : /*enr2 += 0.01f;*/
769 0 : L_enr2 = L_max( L_enr2, 1 ); /* L_enr2 is in Q0 */
770 :
771 0 : IF( bfi ) /* In all bad frames, limit the gain to 1 */
772 : {
773 : /* gain2 = (float)sqrt( enr_old / enr2 );*/
774 0 : L_tmp = Sqrt_Ratio32( L_enr_old, 0, L_enr2, 0, &exp2 );
775 0 : gain2 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */
776 :
777 : /*if( gain2 > 1.0f )gain2 = 1.0f;*/
778 0 : gain2 = s_min( gain2, 16384 /*1.0f in Q14*/ ); /*Q14*/
779 :
780 : /* find the energy/gain at the beginning of the frame */
781 0 : frame_ener_fx( L_frame, clas, synth, pitch[0], &L_enr1 /*Q0*/, 1, Q_syn, 3, 0 );
782 :
783 : /*enr1 += 0.1f;*/
784 0 : L_enr1 = L_max( L_enr1, 1 ); /* L_enr2 is in Q0 */
785 :
786 : /*gain1 = (float)sqrt( enr_old / enr1 );*/
787 0 : L_tmp = Sqrt_Ratio32( L_enr_old, 0, L_enr1, 0, &exp2 );
788 0 : gain1 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */
789 :
790 : /*if( gain1 > 1.0f )gain1 = 1.0f;*/
791 0 : gain1 = s_min( gain1, 16384 /*1.0f in Q14*/ ); /*Q14*/
792 : }
793 : ELSE /* good frame */
794 : {
795 0 : IF( L_enr_q == 0 ) /* If E info (FEC protection bits) is not available in the bitstream */
796 : {
797 0 : L_enr_q = L_enr2; /*Q0*/
798 0 : set16_fx( h1, 0, L_FRAME / 2 );
799 0 : h1[0] = 1024; /*1.0F in Q10*/
800 0 : move16();
801 : /*syn_filt( Aq+(3*(M+1)), M, h1, h1, L_FRAME/2, h1+(M+1), 0 );*/
802 0 : E_UTIL_synthesis( 1, Aq + ( 3 * ( M + 1 ) ), h1, h1, L_FRAME / 2, h1 + ( M + 1 ), 0, M );
803 :
804 : /*Compute tilt */
805 : /*rr0 = dotp( h1, h1, L_FRAME/2-1 ) + 0.1f;*/
806 : /*rr1 = dotp( h1, h1+1, L_FRAME/2-1 );*/
807 : /*tilt = rr1 / rr0;*/
808 0 : tilt = extract_h( L_shl_sat( get_gain( h1 + 1, h1, L_FRAME / 2 - 1 ), 15 ) ); /*Q15*/
809 0 : pitch_dist = 0;
810 0 : move16();
811 0 : L_mean_pitch = L_mult( pitch[0], 8192 ); /*Q14*/
812 0 : FOR( k = 0; k < ( NB_SUBFR - 1 ); k++ )
813 : {
814 0 : pitch_dist = add( pitch_dist, abs_s( sub( pitch[k + 1], pitch[k] ) ) ); /*Q0*/
815 0 : L_mean_pitch = L_mac( L_mean_pitch, pitch[k + 1], 8192 ); /*Q14*/
816 : }
817 : /*pitch_dist /= (float)(NB_SUBFR-1); */
818 0 : pitch_dist = mult_r( shl( pitch_dist, 4 ), 10923 /*1/(float)(NB_SUBFR-1) in Q15*/ ); /*Q4*/
819 : /*mean_pitch /= (float)(NB_SUBFR);*/
820 0 : mean_pitch = extract_h( L_shl( L_mean_pitch, 4 ) ); /*Q4*/
821 :
822 :
823 0 : test();
824 0 : test();
825 0 : test();
826 0 : test();
827 0 : test();
828 0 : test();
829 0 : IF( ( GT_16( tilt, 22938 ) ) && /* HF resonnant filter */
830 : ( ( GT_16( pitch_dist, 8 << 4 ) ) || ( LT_16( mean_pitch, PIT_MIN << 4 ) ) ) && /* pitch unstable or very short */
831 : ( ( prev_bfi ) || ( ( EQ_16( coder_type, GENERIC ) ) && ( EQ_16( LSF_Q_prediction, AUTO_REGRESSIVE ) ) ) ) )
832 : {
833 : /*if( enr_q > scaling * enr_old ){enr_q = scaling * enr_old;}*/
834 0 : L_enr_q = L_min( L_enr_q, L_shl_sat( Mult_32_16( L_enr_old, scaling ), 1 ) ); /* scaling in Q14*/
835 : }
836 : ELSE
837 : {
838 0 : ener_max = *lp_ener_FEC_max; /*Q0*/
839 0 : move32();
840 0 : test();
841 0 : if ( EQ_16( clas, VOICED_TRANSITION ) || ( GE_16( clas, INACTIVE_CLAS ) ) )
842 : {
843 0 : ener_max = *lp_ener_FEC_av; /*Q0*/
844 0 : move32();
845 : }
846 : /*if( enr_old > ener_max )ener_max = enr_old;*/
847 0 : ener_max = L_max( ener_max, L_enr_old );
848 :
849 : /*if( enr_q > scaling * ener_max ){enr_q = scaling * ener_max;}*/
850 0 : L_enr_q = L_min( L_enr_q, L_shl_sat( Mult_32_16( ener_max, scaling ), 1 ) ); /* scaling in Q14*/
851 : }
852 : }
853 : /*gain2 = (float)sqrt( enr_q / enr2 );*/
854 0 : L_enr_q = L_max( L_enr_q, 1 ); /* L_enr2 is in Q0 */
855 0 : L_tmp = Sqrt_Ratio32( L_enr_q, 0, L_enr2, 0, &exp2 );
856 0 : gain2 = round_fx( L_shl( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */
857 :
858 : /*-----------------------------------------------------------------*
859 : * Find the energy/gain at the beginning of the frame to ensure smooth transition after erasure(s)
860 : *-----------------------------------------------------------------*/
861 :
862 0 : test();
863 0 : test();
864 0 : test();
865 0 : test();
866 0 : test();
867 0 : test();
868 0 : IF( ( ( GE_16( last_good, VOICED_TRANSITION ) && LT_16( last_good, INACTIVE_CLAS ) && ( clas == UNVOICED_CLAS || EQ_16( clas, INACTIVE_CLAS ) ) ) ||
869 : EQ_32( last_core_brate, SID_1k75 ) || EQ_32( last_core_brate, SID_2k40 ) || last_core_brate == FRAME_NO_DATA ) &&
870 : prev_bfi )
871 : {
872 : /* voiced -> unvoiced signal transition */
873 : /* CNG -> active signal transition */
874 0 : gain1 = gain2; /*Q14*/
875 0 : move16();
876 : }
877 : ELSE
878 : {
879 : /* find the energy at the beginning of the frame */
880 0 : frame_ener_fx( L_frame, clas, synth, pitch[0], &L_enr1 /*Q0*/, 1, Q_syn, 3, 0 );
881 :
882 : /*enr1 += 0.1f;*/
883 0 : L_enr1 = L_max( L_enr1, 1 ); /* L_enr1 is in Q0 */
884 :
885 : /*gain1 = (float)sqrt( enr_old / enr1 );*/
886 0 : L_tmp = Sqrt_Ratio32( L_enr_old, 0, L_enr1, 0, &exp2 );
887 0 : gain1 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */
888 :
889 : /*if( gain1 > 1.2f )gain1 = 1.2f;*/
890 : /* prevent clipping */
891 0 : gain1 = s_min( gain1, 19661 /*1.2F in Q14*/ );
892 :
893 : /* prevent amplifying the unvoiced or inactive part of the frame in case an offset is followed by an onset */
894 0 : test();
895 0 : test();
896 0 : if ( EQ_16( clas, ONSET ) && GT_16( gain1, gain2 ) && prev_bfi )
897 : {
898 0 : gain1 = gain2; /*Q14*/
899 0 : move16();
900 : }
901 : }
902 :
903 0 : L_enr2 = L_enr_q; /*Q0*/
904 0 : move32(); /* Set the end frame energy to the scaled energy, to be used in the lp_ener_FEC */
905 : }
906 :
907 : /*------------------------------------------------------------------------------*
908 : * Smooth the energy evolution by exponentially evolving from gain1 to gain2
909 : *------------------------------------------------------------------------------*/
910 :
911 : /*gain2 *= ( 1.0f - AGC );*/
912 0 : L_tmp = L_mult( gain2, (Word16) ( 32768 /*Q15*/ - AGC_FX ) );
913 0 : FOR( i = 0; i < L_frame; i++ )
914 : {
915 : /*gain1 = gain1 * AGC + gain2;*/
916 0 : gain1 = mac_r( L_tmp, gain1, AGC_FX ); /* in Q14 */
917 : /*exc[i] *= gain1;*/
918 0 : exc[i] = mac_r( L_mult( exc[i], gain1 ), exc[i], gain1 );
919 0 : move16();
920 : /*exc2[i] *= gain1;*/
921 0 : exc2[i] = mac_r_sat( L_mult( exc2[i], gain1 ), exc2[i], gain1 );
922 0 : move16();
923 : }
924 : /* smoothing is done in excitation domain, so redo synthesis */
925 0 : Copy( mem_tmp, mem_syn, M ); /* Q_syn */
926 0 : syn_12k8_fx( L_frame, Aq, exc2, synth, mem_syn, 1, Q_exc, Q_syn );
927 0 : *update_flg = 1;
928 0 : move16();
929 : }
930 : }
931 : ELSE
932 : {
933 : /* previous frame erased and no TC frame */
934 140681 : test();
935 140681 : IF( prev_bfi && NE_16( coder_type, TRANSITION ) )
936 : {
937 1446 : IF( L_enr_q == 0 )
938 : {
939 488 : L_enr_q = L_max( 1, L_enr2 ); /* sets to 'L_enr2' in 1 clock */
940 488 : set16_fx( h1, 0, L_FRAME / 2 );
941 488 : h1[0] = 1024; /*1.0f in Q10*/
942 488 : move16();
943 : /*syn_filt( Aq+(3*(M+1)), M, h1, h1, L_FRAME/2, h1+(M+1), 0 );*/
944 488 : E_UTIL_synthesis( 1, Aq + ( 3 * ( M + 1 ) ), h1, h1, L_FRAME / 2, h1 + ( M + 1 ), 0, M );
945 : /*Compute tilt */
946 : /*rr0 = dotp( h1, h1, L_FRAME/2-1 ) + 0.1f;*/
947 : /*rr1 = dotp( h1, h1+1, L_FRAME/2-1 );*/
948 : /*tilt = rr1 / rr0;*/
949 488 : tilt = extract_h( L_shl_sat( get_gain( h1 + 1, h1, L_FRAME / 2 - 1 ), 15 ) ); /*Q15*/
950 488 : test();
951 488 : test();
952 488 : test();
953 488 : test();
954 488 : test();
955 488 : test();
956 488 : test();
957 488 : test();
958 488 : IF( ( ( ( EQ_32( total_brate, ACELP_13k20 ) ) || ( EQ_32( total_brate, ACELP_12k85 ) ) || ( EQ_32( total_brate, ACELP_12k15 ) ) || ( EQ_32( total_brate, ACELP_11k60 ) ) ||
959 : ( EQ_32( total_brate, ACELP_9k60 ) ) ) &&
960 : ( GT_16( tilt, 22938 ) ) && /* HF resonnant filter */
961 : ( ( ( clas == UNVOICED_CLAS ) ) || ( EQ_16( clas, INACTIVE_CLAS ) ) ) ) ) /* unvoiced classification */
962 : {
963 : /*if( enr_q > scaling * enr_old )enr_q = scaling * enr_old;*/
964 0 : L_enr_q = L_min( L_enr_q, L_shl_sat( Mult_32_16( L_enr_old, scaling ), 1 ) ); /* scaling in Q14*/
965 : }
966 488 : ELSE IF( GE_16( last_good, VOICED_TRANSITION ) && LT_16( last_good, INACTIVE_CLAS ) && GE_16( clas, VOICED_TRANSITION ) && LT_16( clas, INACTIVE_CLAS ) )
967 : {
968 : /* Voiced-voiced recovery */
969 262 : test();
970 262 : IF( *old_enr_LP != 0 && GT_16( enr_LP, shl_sat( *old_enr_LP, 1 ) ) )
971 : {
972 : /* enr_q /= enr_LP */
973 12 : exp = norm_l( L_enr_q );
974 12 : tmp = extract_h( L_shl( L_enr_q, exp ) );
975 :
976 12 : exp2 = norm_s( enr_LP );
977 12 : tmp2 = shl( enr_LP, exp2 );
978 :
979 12 : exp = sub( exp2, exp );
980 :
981 12 : tmp3 = sub( tmp, tmp2 );
982 12 : IF( tmp3 > 0 )
983 : {
984 4 : tmp = shr( tmp, 1 );
985 4 : exp = add( exp, 1 );
986 : }
987 12 : tmp = div_s( tmp, tmp2 ); /*Q15*/
988 :
989 : /* L_enr_q *= 2 * *old_enr_LP */
990 12 : L_enr_q = L_shl( L_mult( tmp, shl( *old_enr_LP, 1 ) ), exp ); /*Q0*/
991 : }
992 :
993 : ELSE
994 : {
995 250 : test();
996 250 : IF( avoid_lpc_burst_on_recovery && GT_16( enr_LP, 160 /*20.0f in Q3*/ ) )
997 : {
998 3 : exp = norm_s( enr_LP );
999 3 : tmp = shl( enr_LP, exp );
1000 :
1001 3 : exp2 = 7;
1002 3 : move16();
1003 3 : tmp2 = 160 << 7; /* 160 = 20.0f in Q3 */
1004 3 : move16();
1005 3 : exp = sub( exp2, exp );
1006 :
1007 3 : IF( GT_16( tmp, tmp2 ) )
1008 : {
1009 3 : tmp = shr( tmp, 1 );
1010 3 : exp = add( exp, 1 );
1011 : }
1012 3 : tmp = div_s( tmp, tmp2 ); /* tmp*2^exp = enr_LP/20.0 */
1013 3 : L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp ); /* L_tmp*2^exp = sqrt(20.0/enr_LP) */
1014 3 : L_enr_q = L_shl( Mpy_32_32( L_enr_q, L_tmp ), exp ); /*Q0*/
1015 : }
1016 : }
1017 : }
1018 :
1019 488 : test();
1020 488 : test();
1021 488 : test();
1022 488 : test();
1023 488 : IF( ( GE_16( last_good, VOICED_TRANSITION ) && LT_16( last_good, INACTIVE_CLAS ) && GE_16( clas, VOICED_TRANSITION ) && LT_16( clas, INACTIVE_CLAS ) ) || force_scaling )
1024 : {
1025 :
1026 262 : IF( GT_32( L_enr_q, L_enr_old ) ) /* Prevent energy to increase on voiced */
1027 : {
1028 97 : L_enr_q = L_add( Mpy_32_16_1( L_enr_old, 32767 - SCLSYN_LAMBDA ), Mpy_32_16_1( L_enr_q, SCLSYN_LAMBDA ) ); /*Q0*/
1029 : }
1030 : }
1031 : }
1032 :
1033 1446 : L_enr_q = L_max( 1, L_enr_q );
1034 :
1035 : /* gain2 = (float)sqrt( enr_q / enr2 );*/
1036 1446 : exp = norm_l( L_enr_q );
1037 1446 : tmp = extract_h( L_shl( L_enr_q, exp ) );
1038 :
1039 1446 : exp2 = norm_l( L_enr2 );
1040 1446 : tmp2 = extract_h( L_shl( L_enr2, exp2 ) );
1041 :
1042 1446 : exp2 = sub( exp, exp2 ); /* Denormalize and substract */
1043 :
1044 1446 : tmp3 = sub( tmp2, tmp );
1045 1446 : IF( tmp3 > 0 )
1046 : {
1047 139 : tmp2 = shr( tmp2, 1 );
1048 139 : exp2 = add( exp2, 1 );
1049 : }
1050 :
1051 1446 : tmp = div_s( tmp2, tmp );
1052 :
1053 1446 : L_tmp = L_deposit_h( tmp );
1054 1446 : L_tmp = Isqrt_lc( L_tmp, &exp2 );
1055 1446 : gain2 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */
1056 : /*-----------------------------------------------------------------*
1057 : * Clipping of the smoothing gain at the frame end
1058 : *-----------------------------------------------------------------*/
1059 :
1060 1446 : gain2 = s_min( gain2, 19661 /*1.2f in Q14*/ ); /* Gain modification clipping */
1061 1446 : if ( LT_32( L_enr_q, 2 ) )
1062 : {
1063 21 : gain2 = s_min( gain2, 16384 /*1.0f in Q14*/ ); /* Gain modification clipping */
1064 : }
1065 :
1066 : /*-----------------------------------------------------------------*
1067 : * Find the energy/gain at the beginning of the frame to ensure smooth transition after erasure(s)
1068 : *-----------------------------------------------------------------*/
1069 :
1070 1446 : test();
1071 1446 : test();
1072 1446 : test();
1073 1446 : test();
1074 1446 : test();
1075 1446 : test();
1076 1446 : IF( EQ_16( clas, SIN_ONSET ) ) /* slow increase */
1077 : {
1078 19 : gain1 = shr( gain2, 1 );
1079 : }
1080 : /*------------------------------------------------------------*
1081 : * voiced->unvoiced transition recovery
1082 : *------------------------------------------------------------*/
1083 1427 : ELSE IF( ( GE_16( last_good, VOICED_TRANSITION ) && LT_16( last_good, INACTIVE_CLAS ) && ( clas == UNVOICED_CLAS || EQ_16( clas, INACTIVE_CLAS ) ) ) || /* voiced->unvoiced transition recovery */
1084 : EQ_32( last_core_brate, SID_1k75 ) || EQ_32( last_core_brate, SID_2k40 ) || last_core_brate == FRAME_NO_DATA ) /* CNG -> active signal transition */
1085 : {
1086 90 : gain1 = gain2; /*Q14*/
1087 90 : move16();
1088 : }
1089 : ELSE
1090 : {
1091 : /*--------------------------------------------------------*
1092 : * Find the energy at the beginning of the frame
1093 : *--------------------------------------------------------*/
1094 1337 : tmp = frame_ener_fx( L_frame, clas, synth, pitch[0], &L_enr1, 0, Q_syn, 3, 0 );
1095 :
1096 : /*gain1 = (float)sqrt( enr_old / enr1 );*/
1097 1337 : exp = norm_l( L_enr_old );
1098 1337 : tmp = extract_h( L_shl( L_enr_old, exp ) );
1099 1337 : exp2 = norm_l( L_enr1 );
1100 1337 : tmp2 = extract_h( L_shl( L_enr1, exp2 ) );
1101 :
1102 1337 : exp2 = sub( exp, exp2 ); /* Denormalize and substract */
1103 :
1104 1337 : tmp3 = sub( tmp2, tmp );
1105 :
1106 1337 : IF( tmp3 > 0 )
1107 : {
1108 652 : tmp2 = shr( tmp2, 1 );
1109 652 : exp2 = add( exp2, 1 );
1110 : }
1111 :
1112 1337 : tmp = div_s( tmp2, tmp );
1113 :
1114 1337 : L_tmp = L_deposit_h( tmp );
1115 1337 : L_tmp = Isqrt_lc( L_tmp, &exp2 );
1116 1337 : gain1 = round_fx_sat( L_shl_sat( L_tmp, sub( exp2, 1 ) ) ); /* in Q14 */
1117 : /* exp2 is always <= 1 */
1118 :
1119 1337 : gain1 = s_min( gain1, 19661 /*1.2f in Q14*/ ); /*Q14*/
1120 :
1121 1337 : test();
1122 1337 : test();
1123 1337 : if ( avoid_lpc_burst_on_recovery && ( GT_16( enr_LP, 160 ) ) && ( LE_16( enr_LP, shl_sat( *old_enr_LP, 1 ) ) ) )
1124 : {
1125 4 : gain1 = s_min( gain1, 16384 /*1.0f in Q14*/ ); /*Q14*/
1126 : }
1127 :
1128 : /*--------------------------------------------------------*
1129 : * Prevent a catastrophy in case of offset followed by onset
1130 : *--------------------------------------------------------*/
1131 1337 : test();
1132 1337 : if ( ( EQ_16( clas, ONSET ) ) && ( GT_16( gain1, gain2 ) ) )
1133 : {
1134 5 : gain1 = gain2; /*Q14*/
1135 5 : move16();
1136 : }
1137 : }
1138 : /*-----------------------------------------------------------------*
1139 : * Smooth the energy evolution by exponentially evolving from
1140 : * gain1 to gain2
1141 : *-----------------------------------------------------------------*/
1142 :
1143 1446 : L_tmp = L_mult( gain2, (Word16) ( 32768 /*Q15*/ - AGC_FX ) );
1144 :
1145 434278 : FOR( i = 0; i < L_frame; i++ )
1146 : {
1147 432832 : gain1 = mac_r( L_tmp, gain1, AGC_FX ); /* in Q14 */
1148 432832 : exc[i] = mac_r_sat( L_mult_sat( exc[i], gain1 ), exc[i], gain1 );
1149 432832 : move16();
1150 432832 : exc2[i] = mac_r_sat( L_mult_sat( exc2[i], gain1 ), exc2[i], gain1 );
1151 432832 : move16();
1152 : }
1153 :
1154 1446 : Copy( mem_tmp, mem_syn, M ); /* Q_syn */
1155 1446 : syn_12k8_fx( L_frame, Aq, exc2, synth, mem_syn, 1, Q_exc, Q_syn );
1156 1446 : *update_flg = 1;
1157 1446 : move16();
1158 : }
1159 : }
1160 : /*-----------------------------------------------------------------*
1161 : * Update low-pass filtered energy for voiced frames
1162 : *-----------------------------------------------------------------*/
1163 :
1164 140736 : test();
1165 140736 : test();
1166 140736 : IF( !bfi && ( GE_16( clas, VOICED_TRANSITION ) && LT_16( clas, INACTIVE_CLAS ) ) )
1167 : {
1168 81679 : IF( EQ_16( clas, VOICED_TRANSITION ) )
1169 : {
1170 5824 : L_enr2_av = L_enr2; /*Q0*/
1171 5824 : move32();
1172 5824 : frame_ener_fx( L_frame, VOICED_CLAS, synth, pitch[sub( shr( L_frame, 6 ), 1 )], &L_ener2_max /*Q0*/, 1, Q_syn, 3, 0 );
1173 : }
1174 : ELSE
1175 : {
1176 75855 : L_ener2_max = L_enr2; /*Q0*/
1177 75855 : move32();
1178 75855 : frame_ener_fx( L_frame, UNVOICED_CLAS, synth, pitch[sub( shr( L_frame, 6 ), 1 )], &L_enr2_av /*Q0*/, 1, Q_syn, 3, 0 );
1179 : }
1180 :
1181 : /**lp_ener_FEC_av = 0.2f * enr2_av + 0.8f * *lp_ener_FEC_av; move32();*/
1182 81679 : *lp_ener_FEC_av = Madd_32_16( Mult_32_16( *lp_ener_FEC_av, 31130 /*0.95F in Q15*/ ), L_enr2_av, 1638 /*0.05 in Q15*/ );
1183 81679 : move32();
1184 : /**lp_ener_FEC_max = 0.2f * enr2_max + 0.8f * *lp_ener_FEC_max; move32();*/
1185 81679 : *lp_ener_FEC_max = Madd_32_16( Mult_32_16( *lp_ener_FEC_max, 31130 /*0.95F in Q15*/ ), L_ener2_max, 1638 /*0.05 in Q15*/ );
1186 81679 : move32();
1187 : }
1188 :
1189 : /*-----------------------------------------------------------------*
1190 : * Update the LP filter energy for voiced frames
1191 : *-----------------------------------------------------------------*/
1192 140736 : test();
1193 140736 : if ( GE_16( clas, VOICED_TRANSITION ) && LT_16( clas, INACTIVE_CLAS ) )
1194 : {
1195 81679 : *old_enr_LP = enr_LP; /*Q3*/
1196 81679 : move16();
1197 : }
1198 :
1199 140736 : return;
1200 : }
|