Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 : #include <stdint.h>
6 : #include "options.h"
7 : #include "cnst.h"
8 : //#include "prot_fx.h"
9 : #include "rom_com_fx.h"
10 : #include "rom_com.h" /* Common constants */
11 : #include "prot_fx.h" /* Function prototypes */
12 : #include "prot_fx_enc.h" /* Function prototypes */
13 : #include "basop_util.h" /* Function prototypes */
14 :
15 : /*-------------------------------------------------------------------*
16 : * Local functions
17 : *--------------------------------------------------------------------*/
18 : static void synthesis_filter_fx( Word16 b[], Word16 x[], Word16 y[], Word16 buf[], Word16 P, Word16 N );
19 : static Word32 DTFS_freq_corr_fx( DTFS_STRUCTURE X1_DTFS_fx, DTFS_STRUCTURE X2_DTFS_fx, Word16 lband, Word16 hband, Word16 *Qout );
20 : static Word16 DTFS_alignment_extract_td_fx( Word16 *x1, Word16 *x2, Word16 lag );
21 : static Word32 DTFS_getEngy_band_fx( DTFS_STRUCTURE X_fx, const Word16 lband, const Word16 hband );
22 :
23 : /*=======================================================================================*/
24 : /* FUNCTION : ppp_voiced_encoder_fx() */
25 : /*---------------------------------------------------------------------------------------*/
26 : /* PURPOSE : */
27 : /*---------------------------------------------------------------------------------------*/
28 : /* INPUT ARGUMENTS : */
29 : /* _ (Word16) delay_fx: open loop pitch, Q6 - WRONG, it is Q0 */
30 : /* _ (Word16) hSC_VBR->vadsnr_fx: SNR for current frame Q7 */
31 : /* _ (Word16) prevCW_lag_fx: Previous lag, Q0 */
32 : /* _ (Word16 *) in_fx : residual signal (Q_res) */
33 : /* _ (Word16 *) lpc1_fx : prev frame de-emphasized LPC Q12 */
34 : /* _ (Word16 *) lpc2_fx : current frame de-emphasized LPC Q12 */
35 : /* _ (Word16 *) exc_fx : prrevious frame quantized excitation (Q_exc) */
36 : /* _ (Word16) Q_res: Q factor for res */
37 : /* _ (Word16) Q_exc: Q factor for exc */
38 : /*---------------------------------------------------------------------------------------*/
39 : /* OUTPUT ARGUMENTS : */
40 : /* _ (Word16*) pitch_fx: floating pitch values for each subframe(Q6) */
41 : /* _ (Word16*) out_fx: Quantized residual signal (Q0) */
42 : /* _ Encoder_State *st_fx: */
43 : /* _ lastLgainE_fx - Q11 */
44 : /* _ lastHgainE_fx - Q11 */
45 : /* _ lasterbE_fx - Q13 */
46 : /*---------------------------------------------------------------------------------------*/
47 : /* INPUT/OUTPUT ARGUMENTS : */
48 : /* _ Encoder_State *st_fx: */
49 : /* _ hSC_VBR->dtfs_enc_xxxx */
50 : /* _ a nd b in hSC_VBR->dtfs_enc_Q */
51 : /* rest all in Q0 */
52 : /* - bump_up_fx - Q0 */
53 : /*---------------------------------------------------------------------------------------*/
54 : /* RETURN ARGUMENTS : */
55 : /* _ None. */
56 : /*---------------------------------------------------------------------------------------*/
57 : /* CALLED FROM : TX */
58 : /*=======================================================================================*/
59 :
60 0 : ivas_error ppp_voiced_encoder_fx(
61 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
62 : SC_VBR_ENC_HANDLE hSC_VBR,
63 : const Word16 bwidth_fx, /* i : audio bandwidth */
64 : const Word16 last_coder_type_raw, /* i : raw last_coder_type */
65 : const Word16 old_pitch_buf[], /* i : buffer of old subframe pitch values */
66 : Word16 *in_fx, /* i : residual signal */
67 : Word16 *out_fx, /* o : Quantized residual signal */
68 : Word16 delay_fx, /* i : open loop pitch */
69 : Word16 *lpc1_fx, /* i : prev frame de-emphasized LPC */
70 : Word16 *lpc2_fx, /* i : current frame de-emphasized LPC */
71 : Word16 *exc_fx, /* i: previous frame quantized excitation */
72 : Word16 *pitch_fx, /* o: floating pitch values for each subframe */
73 : Word16 Qres )
74 : {
75 : Word16 i;
76 0 : Word16 spike_near_edge = 0;
77 0 : move16();
78 : Word16 flag;
79 0 : Word16 delta_lag_E = 0, PPP_MODE_E, Q_delta_lag = 0;
80 0 : move16(); /*delta_lag_E*/
81 0 : move16(); /*Q_delta_lag*/
82 0 : Word16 out_of_bound = 0;
83 0 : move16();
84 : Word16 tmp, tmptmp, tmptmp1;
85 : Word16 pl, l;
86 : Word16 interp_delay[3], temp_pl, temp_l;
87 0 : Word16 upper_cut_off_freq_of_interest_fx = 0;
88 0 : move16(); /*upper_cut_off_freq_of_interest_fx*/
89 0 : Word16 upper_cut_off_freq_of_interest_norm_fx = 0, upper_cut_off_freq_norm_fx = 0;
90 0 : move16(); /*upper_cut_off_freq_of_interest_norm_fx*/
91 0 : move16(); /*upper_cut_off_freq_norm_fx*/
92 : Word16 S_fx[PIT_MAX * 4 + 1], C_fx[PIT_MAX * 4 + 1];
93 : Word16 Qtmpres;
94 : Word32 Ltemp, logLag, Ltemp_q;
95 : Word32 Lacc, Lacc1;
96 : Word16 Ql, Qh, n, sft, flag1;
97 :
98 : Word16 pf_temp1[MAXLAG_WI]; /*maynot need more than MAXLAG_WI/2+1 */
99 : Word16 pf_temp2[MAXLAG_WI];
100 : Word16 pf_temp[MAXLAG_WI];
101 : Word16 pf_n2[MAXLAG_WI];
102 : Word16 exp, expa, expb, fraca, fracb, scale, frac;
103 : Word32 L_tmp;
104 :
105 : Word16 x_fx;
106 : Word16 impzi_fx[160], impzo_fx[160];
107 : Word16 exp_ee, frac_ee;
108 : Word16 Qtmp;
109 0 : Word32 res_enratio_fx = 0;
110 0 : move32();
111 : Word16 mem_fx[10];
112 0 : Word32 energy_impz_fx = 0, tmpres_fx;
113 0 : move32(); /*energy_impz_fx*/
114 : Word32 pos_nq0_fx, neg_nq0_fx, Ltmp;
115 : Word32 Ltmp_32, Ltmp1_32, Ltemp1, Ltemp2, Ltemp_fx;
116 : Word16 Qadj;
117 :
118 0 : Word32 tmp_fx = 0, sp_hb_enratio_fx = 0, sp_enratio_fx = 0;
119 0 : move32(); /*tmp_fx*/
120 0 : move32(); /*sp_hb_enratio_fx*/
121 0 : move32(); /*sp_enratio_fx*/
122 : Word32 low_band_en_fx;
123 : Word32 curr_Engy, prev_Engy;
124 : Word16 temp_Fs;
125 : #if !defined( ISSUE_1867_replace_overflow_libenc )
126 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
127 : Flag Overflow = 0;
128 : move32();
129 : #endif
130 : #endif
131 : DTFS_STRUCTURE *CURRP_NQ_FX;
132 : DTFS_STRUCTURE *TMPDTFS_FX;
133 : DTFS_STRUCTURE *TMPDTFS2_FX;
134 : DTFS_STRUCTURE *TMPDTFS3_FX;
135 : DTFS_STRUCTURE *CURRP_Q_E_FX;
136 : DTFS_STRUCTURE *dtfs_temp_fx;
137 :
138 : ivas_error error;
139 :
140 0 : error = IVAS_ERR_OK;
141 :
142 :
143 0 : IF( ( error = DTFS_new_fx( &CURRP_NQ_FX ) ) != IVAS_ERR_OK )
144 : {
145 0 : IVAS_ERROR( error, "Error creating DTFS structure" );
146 : }
147 0 : IF( ( error = DTFS_new_fx( &TMPDTFS_FX ) ) != IVAS_ERR_OK )
148 : {
149 0 : IVAS_ERROR( error, "Error creating DTFS structure" );
150 : }
151 0 : IF( ( error = DTFS_new_fx( &TMPDTFS2_FX ) ) != IVAS_ERR_OK )
152 : {
153 0 : IVAS_ERROR( error, "Error creating DTFS structure" );
154 : }
155 0 : IF( ( error = DTFS_new_fx( &TMPDTFS3_FX ) ) != IVAS_ERR_OK )
156 : {
157 0 : IVAS_ERROR( error, "Error creating DTFS structure" );
158 : }
159 0 : IF( ( error = DTFS_new_fx( &CURRP_Q_E_FX ) ) != IVAS_ERR_OK )
160 : {
161 0 : IVAS_ERROR( error, "Error creating DTFS structure" );
162 : }
163 0 : IF( ( error = DTFS_new_fx( &dtfs_temp_fx ) ) != IVAS_ERR_OK )
164 : {
165 0 : IVAS_ERROR( error, "Error creating DTFS structure" );
166 : }
167 :
168 :
169 0 : temp_Fs = 8000;
170 0 : move16();
171 :
172 0 : if ( EQ_16( bwidth_fx, WB ) )
173 : {
174 0 : temp_Fs = 16000;
175 0 : move16();
176 : }
177 :
178 0 : test();
179 0 : IF( EQ_16( bwidth_fx, WB ) || EQ_16( bwidth_fx, SWB ) )
180 : {
181 0 : upper_cut_off_freq_of_interest_fx = 4000;
182 0 : move16();
183 0 : upper_cut_off_freq_of_interest_norm_fx = 10240;
184 0 : move16(); /*value normalized by 12800 */
185 0 : upper_cut_off_freq_norm_fx = 16384;
186 0 : move16(); /*value normalized by 12800 */
187 : }
188 0 : ELSE IF( bwidth_fx == NB )
189 : {
190 0 : upper_cut_off_freq_of_interest_fx = 3300;
191 0 : move16();
192 0 : upper_cut_off_freq_of_interest_norm_fx = 8448;
193 0 : move16(); /*value normalized by 12800 */
194 0 : upper_cut_off_freq_norm_fx = 10240;
195 0 : move16(); /*value normalized by 12800 */
196 : }
197 :
198 : /* Initialization */
199 0 : IF( hSC_VBR->firstTime_voicedenc )
200 : {
201 0 : hSC_VBR->firstTime_voicedenc = 0;
202 0 : move16();
203 0 : hSC_VBR->dtfs_enc_lag = 0;
204 0 : move16();
205 0 : hSC_VBR->dtfs_enc_nH = 0;
206 0 : move16();
207 0 : hSC_VBR->dtfs_enc_nH_4kHz = 0;
208 0 : move16();
209 0 : hSC_VBR->dtfs_enc_upper_cut_off_freq_of_interest_fx = 3300;
210 0 : move16();
211 0 : hSC_VBR->dtfs_enc_upper_cut_off_freq_fx = 4000;
212 0 : move16();
213 0 : set16_fx( hSC_VBR->dtfs_enc_a_fx, 0, MAXLAG_WI );
214 0 : set16_fx( hSC_VBR->dtfs_enc_b_fx, 0, MAXLAG_WI );
215 : }
216 0 : test();
217 : /* Figure out the PPP_MODE */
218 0 : IF( EQ_16( hSC_VBR->last_ppp_mode, 1 ) && !hSC_VBR->mode_QQF )
219 : {
220 0 : hSC_VBR->bump_up = 1;
221 0 : move16();
222 0 : free( CURRP_NQ_FX );
223 0 : free( TMPDTFS_FX );
224 0 : free( TMPDTFS2_FX );
225 0 : free( TMPDTFS3_FX );
226 0 : free( CURRP_Q_E_FX );
227 0 : free( dtfs_temp_fx );
228 0 : return error;
229 : }
230 :
231 : /* Use the aggresive bumpups if there are two consecutive Q frames */
232 : /* Aggresive bump upsare only used in the second Q frame */
233 0 : if ( hSC_VBR->last_ppp_mode == 1 )
234 : {
235 0 : hSC_VBR->rate_control = 0;
236 0 : move16();
237 : }
238 :
239 0 : PPP_MODE_E = 'Q';
240 0 : move16();
241 :
242 0 : pl = s_min( MAX_LAG_PIT, rint_new_fx( L_shl( old_pitch_buf[( 2 * NB_SUBFR ) - 1], 10 ) ) );
243 0 : l = s_min( MAX_LAG_PIT, rint_new_fx( L_deposit_h( delay_fx ) ) );
244 : /* old_pitch_buf in Q6*/
245 :
246 : /* Bump up if the lag is out_fx of range */
247 0 : test();
248 0 : test();
249 0 : test();
250 0 : IF( GT_16( sub( l, pl ), 13 ) || LT_16( sub( l, pl ), -11 ) || LT_16( l, 19 ) || LT_16( pl, 19 ) )
251 : {
252 0 : hSC_VBR->bump_up = 1;
253 0 : move16();
254 0 : free( CURRP_NQ_FX );
255 0 : free( TMPDTFS_FX );
256 0 : free( TMPDTFS2_FX );
257 0 : free( TMPDTFS3_FX );
258 0 : free( CURRP_Q_E_FX );
259 0 : free( dtfs_temp_fx );
260 0 : return error;
261 : }
262 :
263 0 : IF( NE_16( hSC_VBR->last_ppp_mode, 1 ) )
264 : {
265 : /* Obtain DTFS of last pl values of past excitation */
266 0 : GetSinCosTab_fx( pl, S_fx, C_fx );
267 0 : DTFS_to_fs_fx( exc_fx - pl, pl, dtfs_temp_fx, temp_Fs, 0, S_fx, C_fx );
268 : }
269 :
270 0 : if ( EQ_16( last_coder_type_raw, UNVOICED ) )
271 : {
272 0 : pl = l;
273 0 : move16(); /* if prev frame was sil/uv */
274 : }
275 :
276 : /* Use the out_fx array as a temp storage for currp */
277 0 : spike_near_edge = ppp_extract_pitch_period_fx( in_fx, out_fx, l, &out_of_bound, Qres ); /*Q0*/
278 0 : move16();
279 : /* out_fx in Qres */
280 :
281 0 : IF( out_of_bound == 1 )
282 : {
283 0 : hSC_VBR->bump_up = 1;
284 0 : move16();
285 0 : free( CURRP_NQ_FX );
286 0 : free( TMPDTFS_FX );
287 0 : free( TMPDTFS2_FX );
288 0 : free( TMPDTFS3_FX );
289 0 : free( CURRP_Q_E_FX );
290 0 : free( dtfs_temp_fx );
291 0 : return error;
292 : }
293 :
294 : /* Get DTFS of current prototype */
295 0 : GetSinCosTab_fx( l, S_fx, C_fx );
296 :
297 0 : DTFS_to_fs_fx( out_fx, l, CURRP_NQ_FX, temp_Fs, 0, S_fx, C_fx );
298 : /* This requires input out_fx in Q0, but currently in Qres */
299 :
300 : /* Ensure the extracted prototype is time-synchronous to the
301 : * last l samples of the frame. This proves to eliminate
302 : * some of the PPP-CELP transition problems.
303 : * Convert last samples into DTFS */
304 0 : IF( spike_near_edge != 0 )
305 : {
306 : /* These two function calls are combined in one call DTFS_alignment_extract_td_fx() */
307 : /* DTFS_to_fs(in+L_FRAME-l, l, TMPDTFS,(short) st->input_Fs,0); */
308 : /* tmp = DTFS_alignment_extract(*TMPDTFS, *CURRP_NQ, 0.0, lpc2) ; */
309 0 : tmp = DTFS_alignment_extract_td_fx( out_fx, in_fx + L_FRAME - l, l );
310 0 : move16(); /*Q0 */
311 0 : tmp = negate( shl( tmp, 2 ) ); /*Q2 */
312 0 : Q2phaseShift_fx( CURRP_NQ_FX, tmp, l, S_fx, C_fx );
313 : /* output CURRP_NQ is correct */
314 : }
315 0 : temp_pl = pl;
316 0 : move16();
317 0 : temp_l = l;
318 0 : move16();
319 :
320 0 : FOR( i = 0; i < NB_SUBFR; i++ )
321 : {
322 : /* do the linear pitch_fx interp to drive the nb_post_filt_fx */
323 0 : Interpol_delay_fx( interp_delay, temp_pl, temp_l, i, frac_4sf_fx ); /* interp_delay in Q4 */
324 0 : pitch_fx[i] = shl( interp_delay[0], 2 );
325 0 : move16(); /* pitch_fx in Q6 */
326 : }
327 0 : curr_Engy = DTFS_getEngy_P2A_fx( CURRP_NQ_FX ); /*2Q where Q=CURRP_NQ_FX->Q */
328 0 : move32();
329 : /* Restoring PPP memories when the last frame is non-PPP */
330 0 : IF( NE_16( hSC_VBR->last_ppp_mode, 1 ) )
331 : {
332 :
333 0 : hSC_VBR->ph_offset_E_fx = 0;
334 0 : move16();
335 :
336 : /* st->prev_cw_en = DTFS_getEngy(*dtfs_temp); */
337 0 : Lacc = DTFS_getEngy_P2A_fx( dtfs_temp_fx ); /*2Q where Q = dtfs_temp_fx->Q */
338 :
339 :
340 0 : prev_Engy = L_add( Lacc, 0 );
341 :
342 0 : hSC_VBR->Q_prev_cw_en_fx = norm_l( Lacc ); /* = K = headroom */
343 0 : move16();
344 : /*hSC_VBR->Q_prev_cw_en_fx = (Lacc==0)?31: hSC_VBR->Q_prev_cw_en_fx; */
345 0 : if ( Lacc == 0 )
346 : {
347 0 : hSC_VBR->Q_prev_cw_en_fx = 31;
348 0 : move16();
349 : }
350 :
351 0 : hSC_VBR->prev_cw_en_fx = (Word32) L_shl( Lacc, hSC_VBR->Q_prev_cw_en_fx ); /*2Q+K */
352 0 : move32();
353 0 : hSC_VBR->Q_prev_cw_en_fx = add( hSC_VBR->Q_prev_cw_en_fx, shl( dtfs_temp_fx->Q, 1 ) );
354 0 : move16();
355 : /* hSC_VBR->Q_prev_cw_en_fx = 2*(dtfs_temp_fx->Q) + K */
356 :
357 0 : DTFS_copy_fx( TMPDTFS_FX, *dtfs_temp_fx ); /* output = TMPDTFS_FX */
358 :
359 0 : DTFS_car2pol_fx( TMPDTFS_FX );
360 :
361 0 : logLag = log10_fx( TMPDTFS_FX->lag_fx ); /* logLag=10*log10(pl), Q23 */
362 0 : Ltemp_q = L_shl( L_mult( shl( TMPDTFS_FX->Q, 1 ), 24660 ), 9 ); /* Ltemp_q=2Q*10log10(2), Q23 */
363 :
364 : /* Process low band */
365 0 : Ltemp = DTFS_setEngyHarm_fx( 236, 2828, 0, 2828, 1, 0, &Ql, TMPDTFS_FX ); /* Q of Ltemp = 2*(TMPDTFS_FX->Q) = Ql ? */
366 0 : move32();
367 : /* Compensate for Q factor of energy to get log10(lag*eng) */
368 0 : Ltemp = log10_fx( Ltemp ); /* Ltemp=10log10(eng), Q23 */
369 0 : Ltemp = L_add( L_sub( Ltemp, Ltemp_q ), logLag ); /* Ltemp=10*log10(lag*eng), Q23 */
370 : /*hSC_VBR->lastLgainE_fx=round_fx(L_shl((Word32)Mpy_32_16(extract_h(Ltemp),extract_l(Ltemp),0x6666),1)); // Q11, 0x6666 = 0.1 in Q18 */
371 0 : hSC_VBR->lastLgainE_fx = round_fx( L_shl( Mult_32_16( Ltemp, 0x6666 ), 1 ) ); /* Q11, 0x6666 = 0.1 in Q18 */
372 0 : move16();
373 :
374 : /* Process high band */
375 0 : Ltemp = DTFS_setEngyHarm_fx( 2828, upper_cut_off_freq_of_interest_norm_fx, 2828, upper_cut_off_freq_norm_fx, 1, 0, &Qh, TMPDTFS_FX );
376 0 : move32();
377 0 : Ltemp = log10_fx( Ltemp );
378 0 : Ltemp = L_add( L_sub( Ltemp, Ltemp_q ), logLag ); /* Ltemp=10*log10(lag*eng), Q23 */
379 0 : hSC_VBR->lastHgainE_fx = round_fx( L_shl( Mult_32_16( Ltemp, 0x6666 ), 1 ) ); /* Q11 */
380 0 : move16();
381 : /* Need to unify the Q factors of both bands */
382 0 : TMPDTFS_FX->Q = s_min( Ql, Qh );
383 0 : move16(); /* set Q factor to be the smaller one of Ql and Qh */
384 0 : n = sub( Ql, Qh ); /* compare band Q factors */
385 :
386 0 : IF( n < 0 )
387 : {
388 0 : rshiftHarmBand_fx( TMPDTFS_FX, 2828, upper_cut_off_freq_norm_fx, n );
389 : }
390 0 : ELSE IF( n > 0 )
391 : {
392 0 : rshiftHarmBand_fx( TMPDTFS_FX, 0, 2828, sub( Qh, Ql ) );
393 : }
394 :
395 0 : DTFS_to_erb_fx( *TMPDTFS_FX, hSC_VBR->lasterbE_fx ); /* output lasterbE_fx in Q13 */
396 0 : Lacc1 = L_max( prev_Engy, 1 );
397 : }
398 : ELSE
399 : {
400 : /* Copy DTFS related parameters from 'st_fx' to 'dtfs_temp' structure */
401 0 : dtfs_temp_fx->lag_fx = hSC_VBR->dtfs_enc_lag;
402 0 : move16(); /*Q0*/
403 0 : dtfs_temp_fx->nH_fx = hSC_VBR->dtfs_enc_nH;
404 0 : move16(); /*Q0*/
405 0 : dtfs_temp_fx->nH_4kHz_fx = hSC_VBR->dtfs_enc_nH_4kHz;
406 0 : move16(); /*Q0*/
407 0 : dtfs_temp_fx->upper_cut_off_freq_of_interest_fx = hSC_VBR->dtfs_enc_upper_cut_off_freq_of_interest_fx;
408 0 : move16();
409 0 : dtfs_temp_fx->upper_cut_off_freq_fx = hSC_VBR->dtfs_enc_upper_cut_off_freq_fx;
410 0 : move16();
411 :
412 0 : Copy( hSC_VBR->dtfs_enc_a_fx, dtfs_temp_fx->a_fx, MAXLAG_WI );
413 0 : Copy( hSC_VBR->dtfs_enc_b_fx, dtfs_temp_fx->b_fx, MAXLAG_WI );
414 :
415 0 : dtfs_temp_fx->Q = hSC_VBR->dtfs_enc_Q;
416 0 : move16();
417 0 : Lacc1 = DTFS_getEngy_P2A_fx( dtfs_temp_fx );
418 0 : move32();
419 0 : prev_Engy = L_add( Lacc1, 0 );
420 : }
421 :
422 : /*-----Open-loop Bump-Up-------- */
423 :
424 : /* Energy ratio calculation in_fx residual and speech domain */
425 : /* Also, compute correlation between the previous and the */
426 : /* current prototype */
427 :
428 : /* res_enratio = DTFS_getEngy(*CURRP_NQ) / DTFS_getEngy(*dtfs_temp); */
429 0 : Lacc = L_add( curr_Engy, 0 );
430 : /* Lacc1 has been handled above */
431 :
432 0 : sft = add( shl( sub( CURRP_NQ_FX->Q, dtfs_temp_fx->Q ), 1 ), 4 );
433 0 : IF( sft > 0 )
434 : {
435 0 : if ( LT_32( Lacc1, L_shr( Lacc, sft ) ) )
436 : {
437 0 : res_enratio_fx = 0x7FFF;
438 0 : move16();
439 : }
440 : }
441 : ELSE
442 : {
443 0 : if ( LT_32( L_shr( Lacc1, negate( sft ) ), Lacc ) )
444 : {
445 0 : res_enratio_fx = 0x7FFF;
446 0 : move16();
447 : }
448 : }
449 : /* max value res_enratio compared against is 0x7400 (14.5 in Q11) */
450 :
451 0 : IF( NE_32( res_enratio_fx, 0x7FFF ) )
452 : {
453 :
454 0 : expb = norm_l( Lacc );
455 0 : fracb = extract_h( L_shl( Lacc, expb ) );
456 0 : expb = sub( 30, add( expb, shl( CURRP_NQ_FX->Q, 1 ) ) );
457 :
458 :
459 0 : expa = norm_l( Lacc1 );
460 0 : fraca = extract_h( L_shl( Lacc1, expa ) );
461 0 : expa = sub( 30, add( expa, shl( dtfs_temp_fx->Q, 1 ) ) );
462 :
463 0 : scale = shr( sub( fraca, fracb ), 15 );
464 0 : fracb = shl( fracb, scale );
465 0 : expb = sub( expb, scale );
466 :
467 0 : tmp = div_s( fracb, fraca );
468 0 : exp = sub( expb, expa );
469 0 : res_enratio_fx = shl( tmp, sub( exp, 4 ) );
470 : }
471 : /* res_enratio_fx is Q11 */
472 :
473 : /* Copy over CURRP_NQ into TMPDTFS */
474 0 : DTFS_copy_fx( TMPDTFS_FX, *CURRP_NQ_FX ); /* output = TMPDTFS_FX with Q = CURRP_NQ_FX->Q */
475 :
476 : /* Copy over dtfs_temp into TMPDTFS2 */
477 0 : DTFS_copy_fx( TMPDTFS2_FX, *dtfs_temp_fx ); /* output = TMPDTFS2_FX with Q = dtfs_temp_fx->Q */
478 :
479 0 : tmptmp = DTFS_alignment_full_fx( *TMPDTFS2_FX, *TMPDTFS_FX, hSC_VBR->ph_offset_E_fx, S_fx, C_fx, 0 );
480 0 : move16();
481 0 : tmptmp1 = sub( shl( TMPDTFS_FX->lag_fx, 1 ), tmptmp ); /* (C_l-tmptmp) , Q1 */
482 :
483 0 : Q2phaseShift_fx( TMPDTFS_FX, negate( shl( tmptmp1, 1 ) ), TMPDTFS_FX->lag_fx, S_fx, C_fx ); /* fixed bug , phase shift by tmp computed in_fx TMP.lag domain (above) */
484 :
485 : /*tmpres = (float)(DTFS_freq_corr(*TMPDTFS, *TMPDTFS2, 100.0f, 3700.0f));*/
486 0 : tmpres_fx = DTFS_freq_corr_fx( *TMPDTFS_FX, *TMPDTFS2_FX, 100, 3700, &Qtmpres ); /* tmpres_fx has Q factor tmpres */
487 0 : move32();
488 :
489 0 : poleFilter_setup_fx( lpc2_fx, M + 1, *TMPDTFS_FX, S_fx, C_fx, pf_temp1, pf_temp2, pf_temp, pf_n2 );
490 0 : DTFS_poleFilter_fx_9( TMPDTFS_FX, pf_temp1, pf_temp2, pf_temp, pf_n2 );
491 : /* lpc2_fx in Q12 */
492 :
493 0 : DTFS_adjustLag_fx( TMPDTFS2_FX, TMPDTFS_FX->lag_fx ); /* operate in_fx CL domain */
494 :
495 0 : DTFS_poleFilter_fx( TMPDTFS2_FX, lpc1_fx, M + 1, S_fx, C_fx ); /* lpc1_fx in Q12 */
496 :
497 0 : tmp_fx = DTFS_freq_corr_fx( *TMPDTFS_FX, *TMPDTFS2_FX, 100, 3700, &Qtmp );
498 0 : move32();
499 : /* tmp_fx Q = Qtmp */
500 :
501 :
502 : /*******************************************************************************
503 : if ( DTFS_getEngy(*TMPDTFS2) > 0 )
504 : {
505 : sp_enratio = DTFS_getEngy(*TMPDTFS)/DTFS_getEngy(*TMPDTFS2);
506 : }
507 : else
508 : {
509 : sp_enratio = 0.0f;
510 : }
511 : *******************************************************************************/
512 0 : Ltmp_32 = ( DTFS_getEngy_fx( TMPDTFS2_FX ) ); /* Output Q=2*(TMPDTFS2_FX->Q) */
513 0 : move32();
514 0 : IF( Ltmp_32 > 0 )
515 : {
516 : /*sp_enratio = DTFS_getEngy(*TMPDTFS)/DTFS_getEngy(*TMPDTFS2); in Q15 */
517 0 : Lacc = DTFS_getEngy_P2A_fx( TMPDTFS_FX );
518 0 : move32();
519 0 : Lacc1 = Ltmp_32;
520 0 : move32();
521 : /* IF (L_sub(sp_enratio_fx,0x7FFF)!=0) */
522 : {
523 0 : expb = norm_l( Lacc );
524 0 : fracb = extract_h( L_shl( Lacc, expb ) );
525 :
526 0 : expb = sub( 30, add( expb, shl( TMPDTFS_FX->Q, 1 ) ) );
527 :
528 0 : expa = norm_l( Lacc1 );
529 0 : fraca = extract_h( L_shl( Lacc1, expa ) );
530 :
531 0 : expa = sub( 30, add( expa, shl( TMPDTFS2_FX->Q, 1 ) ) );
532 :
533 0 : scale = shr( sub( fraca, fracb ), 15 );
534 0 : fracb = shl( fracb, scale );
535 0 : expb = sub( expb, scale );
536 :
537 0 : tmp = div_s( fracb, fraca );
538 0 : exp = sub( expb, expa );
539 0 : sp_enratio_fx = L_shl_sat( tmp, exp ); /* Q15 */
540 : }
541 : }
542 : ELSE
543 : {
544 0 : sp_enratio_fx = L_deposit_l( 0 ); /* Q15 */
545 : }
546 :
547 : /*******************************************************************************/
548 0 : IF( EQ_16( PPP_MODE_E, 'Q' ) )
549 : {
550 : /* Bump up if the lag is out_fx of range */
551 0 : test();
552 0 : IF( GT_16( sub( l, pl ), 13 ) || LT_16( sub( l, pl ), -11 ) )
553 : {
554 0 : PPP_MODE_E = 'B';
555 0 : move16();
556 : }
557 : ELSE
558 : {
559 0 : delta_lag_E = sub( l, pl );
560 : }
561 :
562 : /* Bump up if big change between the previous and the current CWs */
563 0 : IF( LT_16( shl_sat( hSC_VBR->vadsnr_fx, 1 ), hSC_VBR->SNR_THLD_fx ) ) /*Q8 */
564 : {
565 : /*if ( res_enratio > 5.0 && tmp < 0.65 ) */
566 : /* 5 in Q11, 0.65 in Q15 // L_shl(tmp_fx,sub(31,Qtmp)) makes tmp_fx FIXED Q31 */
567 0 : test();
568 : #ifdef ISSUE_1867_replace_overflow_libenc
569 0 : if ( ( GT_32( res_enratio_fx, 10240 ) ) && ( LT_16( extract_h( L_shl_sat( tmp_fx, sub( 31, Qtmp ) ) ), 21299 ) ) )
570 : #else
571 : if ( ( GT_32( res_enratio_fx, 10240 ) ) && ( LT_16( extract_h( L_shl_o( tmp_fx, sub( 31, Qtmp ), &Overflow ) ), 21299 ) ) )
572 : #endif
573 : {
574 0 : PPP_MODE_E = 'B';
575 0 : move16();
576 : }
577 : }
578 : ELSE
579 : {
580 : /* if ( res_enratio > 3.0 && tmp < 1.2 ) */
581 : /*3 in Q11, 1.2 in Q14 // L_shl(tmp_fx,sub(31,Qtmp)) makes tmp_fx FIXED Q14 */
582 0 : test();
583 : #ifdef ISSUE_1867_replace_overflow_libenc
584 0 : if ( ( GT_32( res_enratio_fx, 6144 ) ) && ( LT_16( extract_h( L_shl_sat( tmp_fx, sub( 30, Qtmp ) ) ), 19661 ) ) )
585 : #else
586 : if ( ( GT_32( res_enratio_fx, 6144 ) ) && ( LT_16( extract_h( L_shl_o( tmp_fx, sub( 30, Qtmp ), &Overflow ) ), 19661 ) ) )
587 : #endif
588 : {
589 0 : PPP_MODE_E = 'B';
590 0 : move16();
591 : }
592 : }
593 : }
594 :
595 : /* Rapid rampdown frame where time resolution is important */
596 : /* Not a suitable PPP frame -> Bump to CELP */
597 :
598 0 : IF( LT_16( shl_sat( hSC_VBR->vadsnr_fx, 1 ), hSC_VBR->SNR_THLD_fx ) ) /*Q8 */
599 : {
600 : /* if (res_enratio < 0.025) */
601 : #ifdef ISSUE_1867_replace_overflow_libenc
602 0 : IF( LT_32( L_shl_sat( res_enratio_fx, 4 ), 819 ) )
603 : /*0x0333 = 0.025 in Q15, res_enratio_fx in Q15 after shl 4 */
604 : #else
605 : IF( LT_32( L_shl_o( res_enratio_fx, 4, &Overflow ), 819 ) ) /*0x0333 = 0.025 in Q15, res_enratio_fx in Q15 after shl 4 */
606 : #endif
607 : {
608 0 : hSC_VBR->bump_up = 1;
609 0 : move16();
610 0 : free( CURRP_NQ_FX );
611 0 : free( TMPDTFS_FX );
612 0 : free( TMPDTFS2_FX );
613 0 : free( TMPDTFS3_FX );
614 0 : free( CURRP_Q_E_FX );
615 0 : free( dtfs_temp_fx );
616 0 : return error;
617 : }
618 : }
619 : ELSE
620 : {
621 : /* if ( res_enratio < 0.092f) */
622 : #ifdef ISSUE_1867_replace_overflow_libenc
623 0 : if ( LT_32( L_shl_sat( res_enratio_fx, 4 ), 3015 ) ) /*3015 = 0.092 in Q15, res_enratio_fx in Q15 after shl 4 */
624 : #else
625 : if ( LT_32( L_shl_o( res_enratio_fx, 4, &Overflow ), 3015 ) ) /*3015 = 0.092 in Q15, res_enratio_fx in Q15 after shl 4 */
626 : #endif
627 : {
628 0 : hSC_VBR->bump_up = 1;
629 0 : move16();
630 : }
631 : }
632 :
633 : /* if (min(res_enratio, sp_enratio) < 0.075 && tmp < -0.5f)) : 2458 = 0.075 in Q15 */
634 0 : test();
635 : #ifdef ISSUE_1867_replace_overflow_libenc
636 0 : if ( LT_32( L_min( L_shl_sat( res_enratio_fx, 4 ), sp_enratio_fx ), 2458 ) && LT_32( tmp_fx, shl_sat( -1, sub( Qtmp, 1 ) ) ) )
637 : #else
638 :
639 : if ( LT_32( L_min( L_shl_o( res_enratio_fx, 4, &Overflow ), sp_enratio_fx ), 2458 ) && LT_32( tmp_fx, shl_sat( -1, sub( Qtmp, 1 ) ) ) )
640 : #endif
641 : {
642 0 : hSC_VBR->bump_up = 1;
643 0 : move16();
644 : }
645 :
646 : /* Rapid rampup frame where time resolution is important */
647 : /* Not a suitable PPP frame -> Bump to CELP */
648 0 : IF( LT_16( shl_sat( hSC_VBR->vadsnr_fx, 1 ), hSC_VBR->SNR_THLD_fx ) ) /*Q8 */
649 : {
650 0 : IF( GT_32( res_enratio_fx, 29696 ) ) /*14.5 in Q11 */
651 : {
652 0 : hSC_VBR->bump_up = 1;
653 0 : move16();
654 0 : free( CURRP_NQ_FX );
655 0 : free( TMPDTFS_FX );
656 0 : free( TMPDTFS2_FX );
657 0 : free( TMPDTFS3_FX );
658 0 : free( CURRP_Q_E_FX );
659 0 : free( dtfs_temp_fx );
660 0 : return error;
661 : }
662 : }
663 : ELSE
664 : {
665 0 : if ( GT_32( res_enratio_fx, 14336 ) ) /* 7.0 in Q11 */
666 : {
667 0 : hSC_VBR->bump_up = 1;
668 0 : move16();
669 : }
670 : }
671 :
672 0 : IF( EQ_16( hSC_VBR->bump_up, 1 ) )
673 : {
674 0 : free( CURRP_NQ_FX );
675 0 : free( TMPDTFS_FX );
676 0 : free( TMPDTFS2_FX );
677 0 : free( TMPDTFS3_FX );
678 0 : free( CURRP_Q_E_FX );
679 0 : free( dtfs_temp_fx );
680 0 : return error;
681 : }
682 :
683 : /* Bump up when the previous frame is an unvoiced or a silent frame */
684 0 : IF( EQ_16( last_coder_type_raw, UNVOICED ) )
685 : {
686 0 : hSC_VBR->bump_up = 1;
687 0 : move16();
688 0 : free( CURRP_NQ_FX );
689 0 : free( TMPDTFS_FX );
690 0 : free( TMPDTFS2_FX );
691 0 : free( TMPDTFS3_FX );
692 0 : free( CURRP_Q_E_FX );
693 0 : free( dtfs_temp_fx );
694 0 : return error;
695 : }
696 : /* -----End Open-loop Bump-Up */
697 :
698 : /* PPP-WI Quantization */
699 0 : IF( EQ_16( PPP_MODE_E, 'Q' ) )
700 : {
701 0 : flag = 1;
702 0 : move16();
703 0 : IF( EQ_16( PPP_MODE_E, 'Q' ) )
704 : {
705 0 : IF( ( error = ppp_quarter_encoder_fx( &flag, CURRP_Q_E_FX, TMPDTFS_FX, dtfs_temp_fx->lag_fx, *CURRP_NQ_FX, lpc2_fx, &hSC_VBR->lastLgainE_fx, &hSC_VBR->lastHgainE_fx, hSC_VBR->lasterbE_fx, *dtfs_temp_fx, S_fx, C_fx, hBstr ) ) != IVAS_ERR_OK )
706 : {
707 0 : free( CURRP_NQ_FX );
708 0 : free( TMPDTFS_FX );
709 0 : free( TMPDTFS2_FX );
710 0 : free( TMPDTFS3_FX );
711 0 : free( CURRP_Q_E_FX );
712 0 : free( dtfs_temp_fx );
713 0 : return error;
714 : }
715 : }
716 :
717 0 : IF( flag )
718 : {
719 : /* TMPDTFS : Target prototype: Amp Quantized + Phase Unquantized */
720 : /* TMPDTFS2: Quantized prototype: Amp Quantized + Phase Quantized */
721 : /* TMPDTFS3: Delta prototype: Diff betw. target and quant. in_fx speech dom */
722 :
723 : /* ----- Closed-loop Bump-Up ---------- */
724 : Word32 pos_nq_fx, neg_nq_fx, pos_q_fx, neg_q_fx;
725 : Word16 Qposnq, Qnegnq, Qposq, Qnegq;
726 :
727 0 : DTFS_peaktoaverage_fx( *TMPDTFS_FX, &pos_nq_fx, &Qposnq, &neg_nq_fx, &Qnegnq );
728 0 : DTFS_peaktoaverage_fx( *CURRP_Q_E_FX, &pos_q_fx, &Qposq, &neg_q_fx, &Qnegq );
729 :
730 :
731 : /* Before we perform the peak-to-average ratio comparison, we have to */
732 : /* ensure that the energy is not decaying and also the pitch_fx pulse */
733 : /* is clearly defined */
734 :
735 : /* Usually triggers in the slow ramp down frames. Does not fall under the test condition (res_enratio < 0.025) as
736 : both frames have little energy and the ratio is not very small. Not suitable for PPP */
737 :
738 0 : IF( GT_16( CURRP_Q_E_FX->upper_cut_off_freq_fx, 4000 ) )
739 : {
740 0 : Ltemp2 = DTFS_getEngy_band_wb_fx( *CURRP_Q_E_FX, 0, 2000 );
741 0 : move32();
742 : /* Use this bump-up only for WB signals */
743 0 : IF( Ltemp2 > 0 )
744 : {
745 : /* sp_hb_enratio = DTFS_getEngy_band_wb(*CURRP_Q_E, 2000.0, 6400.0)/DTFS_getEngy_band_wb(*CURRP_Q_E, 0.0, 2000.0); */
746 0 : Ltemp1 = DTFS_getEngy_band_wb_fx( *CURRP_Q_E_FX, 2000, 6400 ); /*Q13 */
747 0 : move32();
748 : /*sp_hb_enratio_fx = divide_dp(Ltemp1,Ltemp2,0, 1);//Q29 */
749 0 : Qadj = 0;
750 0 : move16();
751 : /*----------------------------------------------------------*/
752 : /* Ltemp_fx = (Word32)divide_dp(Ltemp1, Ltemp2, Qadj,1); Q29*/
753 : /*----------------------------------------------------------*/
754 0 : if ( Ltemp1 < 0 )
755 : {
756 0 : Ltemp1 = L_negate( Ltemp1 );
757 : }
758 0 : expa = norm_l( Ltemp2 );
759 : #ifdef ISSUE_1867_replace_overflow_libenc
760 0 : fraca = extract_h( L_shl( Ltemp2, expa ) );
761 : #else
762 : fraca = extract_h( L_shl_o( Ltemp2, expa, &Overflow ) );
763 : #endif
764 0 : expa = sub( 30, expa );
765 :
766 0 : expb = norm_l( Ltemp1 );
767 0 : fracb = round_fx( L_shl( Ltemp1, expb ) );
768 0 : expb = sub( 30, add( expb, Qadj ) );
769 :
770 0 : scale = shr( sub( fraca, fracb ), 15 );
771 0 : fracb = shl_sat( fracb, scale );
772 0 : expb = sub( expb, scale );
773 :
774 0 : tmp = div_s( fracb, fraca );
775 0 : exp = sub( expb, expa );
776 : #ifdef ISSUE_1867_replace_overflow_libenc
777 0 : Ltemp_fx = L_shl_sat( tmp, add( exp, 14 ) );
778 : #else
779 : Ltemp_fx = L_shl_o( tmp, add( exp, 14 ), &Overflow );
780 : #endif
781 : /*-------------------------------------------*/
782 0 : sp_hb_enratio_fx = L_add( Ltemp_fx, 0 ); /* Q29 */
783 : }
784 : ELSE
785 : {
786 0 : sp_hb_enratio_fx = L_deposit_l( 0 );
787 : }
788 0 : low_band_en_fx = Ltemp2; /*Q13 */
789 0 : move32();
790 : /* if ( low_band_en < 25.0f && sp_hb_enratio < 1.6f ) */
791 : /* 25.0 in Q13 = 204800, 1.6 in Q29 = 858993459 */
792 0 : test();
793 0 : if ( LT_32( low_band_en_fx, 204800 ) && LT_32( sp_hb_enratio_fx, 858993459 ) )
794 : {
795 0 : PPP_MODE_E = 'B';
796 0 : move16();
797 : }
798 : }
799 :
800 0 : Ltmp_32 = DTFS_getEngy_fx( CURRP_NQ_FX ); /*Q = 2*(CURRP_NQ_FX->Q) */
801 0 : move32();
802 0 : Qadj = sub( hSC_VBR->Q_prev_cw_en_fx, shl( CURRP_NQ_FX->Q, 1 ) );
803 :
804 : #ifdef ISSUE_1867_replace_overflow_libenc
805 0 : Ltmp_32 = L_shl_sat( Ltmp_32, Qadj ); /* shift left required to adjust Q of CURRP_NQ_FX = Q_prev_cw_en_fx */
806 : #else
807 : Ltmp_32 = L_shl_o( Ltmp_32, Qadj, &Overflow ); /* shift left required to adjust Q of CURRP_NQ_FX = Q_prev_cw_en_fx */
808 : #endif
809 : /* Ltmp1_32 = 0.8f * st->prev_cw_en */
810 0 : Ltmp1_32 = Mult_32_16( hSC_VBR->prev_cw_en_fx, 26214 ); /* Q = (Q_prev_cw_en_fx + Q15+1)-Q16 = Q_prev_cw_en_fx */
811 :
812 0 : IF( LT_16( shl_sat( hSC_VBR->vadsnr_fx, 1 ), hSC_VBR->SNR_THLD_fx ) ) /*Q8 */
813 : {
814 : /* if ( DTFS_getEngy(*CURRP_NQ) > 0.8f * st->prev_cw_en && max(pos_nq, neg_nq) > 3.0f && st->rate_control ) */
815 : /* pos_nq_fx and neg_nq_fx in Q28 ???? */
816 0 : test();
817 0 : test();
818 0 : IF( GT_32( Ltmp_32, Ltmp1_32 ) && GT_32( L_max( pos_nq_fx, neg_nq_fx ), 805306368 ) && hSC_VBR->rate_control )
819 : {
820 : /*if ( pos_nq > neg_nq && pos_nq > 2.0f * pos_q ) */
821 0 : test();
822 0 : if ( GT_32( pos_nq_fx, neg_nq_fx ) && GT_32( Mult_32_16( pos_nq_fx, 16384 ), pos_q_fx ) )
823 : {
824 0 : PPP_MODE_E = 'B';
825 0 : move16();
826 : }
827 :
828 0 : test();
829 : /*if ( pos_nq < neg_nq && neg_nq > 2.0f * neg_q ) */
830 0 : if ( LT_32( pos_nq_fx, neg_nq_fx ) && GT_32( Mult_32_16( neg_nq_fx, 16384 ), neg_q_fx ) )
831 : {
832 0 : PPP_MODE_E = 'B';
833 0 : move16();
834 : }
835 : }
836 : }
837 :
838 : ELSE
839 : {
840 : /* if ((((DTFS_getEngy(*CURRP_NQ) >(st->prev_cw_en))&&(max(pos_nq,neg_nq)>3.5))&&(st->rate_control))|| */
841 : /* (((DTFS_getEngy(*CURRP_NQ) >0.8*(st->prev_cw_en))&&(max(pos_nq,neg_nq)>3.0))&&(!st->rate_control))) */
842 0 : test();
843 0 : test();
844 0 : test();
845 0 : test();
846 0 : test();
847 0 : IF( ( ( ( L_sub( Ltmp_32, ( hSC_VBR->prev_cw_en_fx ) > 0 ) ) && ( GT_32( L_max( pos_nq_fx, neg_nq_fx ), 939524096 ) ) ) && ( hSC_VBR->rate_control ) ) ||
848 : ( ( ( GT_32( Ltmp_32, Ltmp1_32 ) ) && ( GT_32( L_max( pos_nq_fx, neg_nq_fx ), 805306368 ) ) ) && ( !hSC_VBR->rate_control ) ) )
849 : {
850 : /* if (((pos_nq > neg_nq) && (pos_nq > 2.5*pos_q)&&(st->rate_control))||
851 : ((pos_nq > neg_nq) && (pos_nq > 2.0*pos_q)&&(!st->rate_control))) */
852 0 : test();
853 0 : test();
854 0 : test();
855 0 : test();
856 0 : test();
857 0 : if ( ( GT_32( pos_nq_fx, neg_nq_fx ) && GT_32( Mult_32_16( pos_nq_fx, 13107 ), pos_q_fx ) && ( hSC_VBR->rate_control ) ) ||
858 0 : ( GT_32( pos_nq_fx, neg_nq_fx ) && GT_32( Mult_32_16( pos_nq_fx, 16384 ), pos_q_fx ) && ( !hSC_VBR->rate_control ) ) )
859 : {
860 0 : PPP_MODE_E = 'B';
861 0 : move16();
862 : }
863 :
864 : /* if ((((pos_nq < neg_nq) && (neg_nq > 2.5*neg_q))&&(st->rate_control))||
865 : ((pos_nq < neg_nq) && (neg_nq > 2.0*neg_q)&&(!st->rate_control))) */
866 0 : test();
867 0 : test();
868 0 : test();
869 0 : test();
870 0 : test();
871 0 : if ( ( LT_32( pos_nq_fx, neg_nq_fx ) && GT_32( Mult_32_16( neg_nq_fx, 13107 ), neg_q_fx ) && ( hSC_VBR->rate_control ) ) ||
872 0 : ( LT_32( pos_nq_fx, neg_nq_fx ) && GT_32( Mult_32_16( neg_nq_fx, 16384 ), neg_q_fx ) && ( !hSC_VBR->rate_control ) ) )
873 : {
874 0 : PPP_MODE_E = 'B';
875 0 : move16();
876 : }
877 : }
878 :
879 :
880 0 : IF( hSC_VBR->rate_control )
881 : {
882 :
883 0 : DTFS_peaktoaverage_fx( *CURRP_NQ_FX, &pos_nq0_fx, &Qposnq, &neg_nq0_fx, &Qnegnq );
884 :
885 0 : impzi_fx[0] = 1;
886 0 : move16();
887 0 : FOR( x_fx = 1; x_fx < 160; x_fx++ )
888 : {
889 0 : impzi_fx[x_fx] = 0;
890 0 : move16();
891 : }
892 :
893 0 : FOR( x_fx = 0; x_fx < 160; x_fx++ )
894 : {
895 0 : impzo_fx[x_fx] = 0;
896 0 : move16();
897 : }
898 :
899 0 : FOR( x_fx = 0; x_fx < 10; x_fx++ )
900 : {
901 0 : mem_fx[x_fx] = 0;
902 0 : move16();
903 : }
904 :
905 : /* lpc2_fx in Q12, so Qadj is set to 3 toi bring it to Q15 */
906 0 : Qadj = 15 - 12;
907 0 : move16();
908 0 : synthesis_filter_fx( lpc2_fx, &impzi_fx[0], &impzo_fx[0], &mem_fx[0], 10, 160 );
909 :
910 : /* compute energy of impz */
911 0 : FOR( x_fx = 0; x_fx < 160; x_fx++ )
912 : {
913 : #ifdef ISSUE_1867_replace_overflow_libenc
914 0 : energy_impz_fx = L_add_sat( energy_impz_fx, L_mult0( impzo_fx[x_fx], impzo_fx[x_fx] ) );
915 : #else
916 : energy_impz_fx = L_add_o( energy_impz_fx, L_mult0( impzo_fx[x_fx], impzo_fx[x_fx] ), &Overflow );
917 : #endif
918 : }
919 :
920 : /*energy_impz = (float)(10*log10((float)energy_impz)); */
921 0 : exp_ee = norm_l( energy_impz_fx );
922 0 : frac_ee = Log2_norm_lc( L_shl( energy_impz_fx, exp_ee ) );
923 0 : exp_ee = sub( 30, exp_ee ); /*30-exp-Q0 */
924 0 : Ltmp = Mpy_32_16( exp_ee, frac_ee, LG10 ); /* Ltmp Q14 */
925 0 : energy_impz_fx = L_shr( Ltmp, 3 ); /* 16+11(4bits for 15 no) = 14+x => x= 11 */
926 : /* energy_impz_fx is Q11 */
927 :
928 0 : Ltmp_32 = DTFS_getEngy_fx( CURRP_Q_E_FX ); /*Q = 2*(CURRP_Q_E_FX->Q) */
929 0 : move32();
930 0 : Qadj = sub( hSC_VBR->Q_prev_cw_en_fx, shl( CURRP_Q_E_FX->Q, 1 ) );
931 : #ifdef ISSUE_1867_replace_overflow_libenc
932 0 : Ltmp_32 = L_shl_sat( Ltmp_32, Qadj ); /* shift left required to adjust Q of CURRP_Q_E_FX = Q_prev_cw_en_fx */
933 : #else
934 : Ltmp_32 = L_shl_o( Ltmp_32, Qadj, &Overflow ); /* shift left required to adjust Q of CURRP_Q_E_FX = Q_prev_cw_en_fx */
935 : #endif
936 : /* if ((DTFS_getEngy(*CURRP_Q_E) > st->prev_cw_en)&&(max(pos_q,neg_q)>3.5) && energy_impz>15.0 && tmpres>0.7) */
937 0 : test();
938 0 : test();
939 0 : test();
940 0 : IF( ( GT_32( Ltmp_32, hSC_VBR->prev_cw_en_fx ) ) && ( GT_32( L_max( pos_q_fx, neg_q_fx ), 939524096 ) ) && ( GT_32( energy_impz_fx, 30720 ) ) && ( GT_32( Mult_32_16( tmpres_fx, 23265 ), shl_sat( 1, sub( Qtmpres, 1 ) ) ) ) )
941 : {
942 : /* if ((pos_q > neg_q) && ((pos_q>3.0*pos_nq0) || ((pos_q > 1.5*pos_nq0) && (neg_q < 1.5*neg_nq0)))) */
943 0 : test();
944 0 : test();
945 0 : test();
946 0 : if ( ( GT_32( pos_q_fx, neg_q_fx ) ) && ( ( GT_32( Mult_32_16( pos_q_fx, 10923 ), L_shr( pos_nq0_fx, sub( Qposnq, 28 ) ) ) ) || ( ( GT_32( Mult_32_16( pos_q_fx, 21845 ), L_shr( pos_nq0_fx, sub( Qposnq, 28 ) ) ) ) && ( LT_32( Mult_32_16( neg_q_fx, 21846 ), L_shr( neg_nq0_fx, sub( Qnegnq, 28 ) ) ) ) ) ) )
947 : /* 10923 = (1/3) oin Q15, pos_q_fx is Q28, so result of Mult_32_16(pos_q_fx,10923) = Q28 */
948 : /* L_shr(pos_nq0_fx,sub(Qposnq,28)) brings pos_nq0_fx with variable Q to fixed Q28 */
949 : {
950 0 : PPP_MODE_E = 'B';
951 0 : move16();
952 : }
953 0 : test();
954 0 : test();
955 0 : test();
956 : /* if ((pos_q <= neg_q) && ((neg_q>3.0*neg_nq0)|| ((neg_q > 1.5*neg_nq0) && (pos_q < 1.5*pos_nq0)))) */
957 0 : if ( ( LE_32( pos_q_fx, neg_q_fx ) ) && ( ( GT_32( Mult_32_16( neg_q_fx, 10923 ), L_shr( neg_nq0_fx, sub( Qnegnq, 28 ) ) ) ) || ( ( GT_32( Mult_32_16( neg_q_fx, 21846 ), L_shr( neg_nq0_fx, sub( Qnegnq, 28 ) ) ) ) && ( LT_32( Mult_32_16( pos_q_fx, 21846 ), L_shr( pos_nq0_fx, sub( Qposnq, 28 ) ) ) ) ) ) )
958 : {
959 0 : PPP_MODE_E = 'B';
960 0 : move16();
961 : }
962 : }
963 : }
964 : }
965 :
966 0 : DTFS_copy_fx( TMPDTFS2_FX, *CURRP_Q_E_FX );
967 0 : DTFS_poleFilter_fx_9( TMPDTFS_FX, pf_temp1, pf_temp2, pf_temp, pf_n2 );
968 0 : DTFS_poleFilter_fx_9( TMPDTFS2_FX, pf_temp1, pf_temp2, pf_temp, pf_n2 );
969 :
970 0 : DTFS_sub_fx( TMPDTFS3_FX, *TMPDTFS_FX, *TMPDTFS2_FX );
971 :
972 :
973 : /* operate in ADR mode only the rate control is active. This adds some bumpups to improve the speech quality */
974 : /* if ((DTFS_getEngy_band(*TMPDTFS, 1500.0, upper_cut_off_freq_of_interest)/DTFS_getEngy(*TMPDTFS) > 0.05)&&(!st->rate_control)) */
975 0 : Ltemp1 = DTFS_getEngy_band_fx( *TMPDTFS_FX, 1500, upper_cut_off_freq_of_interest_fx ); /* Q = 2*TMPDTFS_FX->Q*/
976 0 : move32();
977 0 : Ltemp2 = DTFS_getEngy_fx( TMPDTFS_FX ); /* Q = 2*TMPDTFS_FX->Q */
978 0 : move32();
979 0 : IF( Ltemp2 == 0 )
980 : {
981 0 : Ltemp_fx = 0;
982 0 : move32();
983 : }
984 : ELSE
985 : {
986 0 : expb = norm_l( Ltemp1 );
987 0 : fracb = extract_h( L_shl( Ltemp1, expb ) );
988 0 : expb = sub( 30, add( expb, shl( TMPDTFS_FX->Q, 1 ) ) );
989 0 : expa = norm_l( Ltemp2 );
990 0 : fraca = extract_h( L_shl( Ltemp2, expa ) );
991 0 : expa = sub( 30, add( expa, shl( TMPDTFS_FX->Q, 1 ) ) );
992 :
993 0 : scale = shr( sub( fraca, fracb ), 15 );
994 0 : fracb = shl( fracb, scale );
995 0 : expb = sub( expb, scale );
996 :
997 0 : tmp = div_s( fracb, fraca ); /* tmp in Q15 */
998 0 : exp = sub( expb, expa ); /* ans = tmp*2^(exp) */
999 : #ifdef ISSUE_1867_replace_overflow_libenc
1000 0 : Ltemp_fx = L_shl_sat( tmp, add( exp, 12 ) ); /* make tmp Q27 */
1001 : #else
1002 : Ltemp_fx = L_shl_o( tmp, add( exp, 12 ), &Overflow ); /* make tmp Q27 */
1003 : #endif
1004 : }
1005 0 : test();
1006 0 : IF( GT_32( Ltemp_fx, 6710886 ) && ( !hSC_VBR->rate_control ) ) /* 0.05 in Q27 = 6710886 */
1007 : {
1008 : /*if (10.0*log10(DTFS_getEngy_band(*TMPDTFS,1500.0,upper_cut_off_freq_of_interest)/ */
1009 : /*DTFS_getEngy_band(*TMPDTFS3,1500.0,upper_cut_off_freq_of_interest)) < 0.1) */
1010 :
1011 0 : Ltemp1 = DTFS_getEngy_band_fx( *TMPDTFS_FX, 1500, upper_cut_off_freq_of_interest_fx );
1012 0 : move32();
1013 0 : Ltemp2 = DTFS_getEngy_band_fx( *TMPDTFS3_FX, 1500, upper_cut_off_freq_of_interest_fx );
1014 0 : move32();
1015 : /*--------------------------------------------------------------*/
1016 : /* Ltemp_fx = (Word32)divide_dp(Ltemp1, Ltemp2, Qadj,1);//Q29+1 */
1017 : /*--------------------------------------------------------------*/
1018 0 : IF( Ltemp2 == 0 )
1019 : {
1020 0 : Ltemp_fx = 0;
1021 0 : move32();
1022 : }
1023 : ELSE
1024 : {
1025 0 : expa = norm_l( Ltemp2 );
1026 0 : fraca = extract_h( L_shl( Ltemp2, expa ) );
1027 0 : expa = sub( 30, expa );
1028 :
1029 0 : expb = norm_l( Ltemp1 );
1030 0 : fracb = round_fx( L_shl( Ltemp1, expb ) );
1031 0 : expb = sub( 30, expb );
1032 :
1033 0 : scale = shr( sub( fraca, fracb ), 15 );
1034 0 : fracb = shl( fracb, scale );
1035 0 : expb = sub( expb, scale );
1036 :
1037 0 : tmp = div_s( fracb, fraca );
1038 0 : exp = sub( expb, expa );
1039 : #ifdef ISSUE_1867_replace_overflow_libenc
1040 0 : Ltemp_fx = L_shl_sat( tmp, add( exp, 14 ) ); /* answer in Q29 */
1041 : #else
1042 : Ltemp_fx = L_shl_o( tmp, add( exp, 14 ), &Overflow ); /* answer in Q29 */
1043 : #endif
1044 : }
1045 : /*-------------------------------------------*/
1046 :
1047 : /* 10.0*log10(Ltemp_fx) */
1048 0 : exp_ee = norm_l( Ltemp_fx );
1049 0 : frac_ee = Log2_norm_lc( L_shl( Ltemp_fx, exp_ee ) );
1050 0 : exp_ee = sub( 30, add( exp_ee, 29 ) ); /* 30 fixed here, 29 is the Q of Ltemp_fx */
1051 0 : Ltmp = Mpy_32_16( exp_ee, frac_ee, LG10 ); /* LG10 in Q13, so answer Ltmp in Q14 */
1052 :
1053 0 : IF( LT_32( Ltmp, 1638 ) ) /* 1638 = 0.1 in Q14 */
1054 : {
1055 : /* if (res_enratio > 0.8) */
1056 0 : if ( GT_32( res_enratio_fx, 1638 ) ) /* 1638 = 0.8 in Q11, res_enratio_fx in Q11 */
1057 : {
1058 0 : PPP_MODE_E = 'B';
1059 0 : move16();
1060 : }
1061 : }
1062 : }
1063 :
1064 : /* To increase bump up, raise first threshold, lower second */
1065 : /*tmp = (float)(10.0*log10(DTFS_getEngy(*TMPDTFS)/DTFS_getEngy(*TMPDTFS3)));*/
1066 0 : Lacc = DTFS_getEngy_P2A_fx( TMPDTFS_FX ); /* Q = 2*(TMPDTFS_FX->Q) */
1067 0 : move32();
1068 0 : Lacc1 = DTFS_getEngy_P2A_fx( TMPDTFS3_FX ); /* Q = 2*(TMPDTFS3_FX->Q) */
1069 0 : move32();
1070 :
1071 0 : sft = shl( sub( TMPDTFS_FX->Q, TMPDTFS3_FX->Q ), 1 ); /* to check if Lacc<=2*Lacc1 */
1072 0 : flag1 = 0;
1073 0 : move16();
1074 0 : IF( sft > 0 )
1075 : {
1076 : /*if (L_sub40_40(L_shr40(Lacc,sft),Lacc1)<=0) */
1077 0 : Lacc = L_shr( Lacc, sft );
1078 0 : flag1 = 1;
1079 0 : move16(); /* do the divide */
1080 : }
1081 : ELSE
1082 : {
1083 : /*if (L_sub40_40(Lacc,L_shr40(Lacc1,negate(sft)))<=0) */
1084 0 : Lacc1 = L_shr( Lacc1, negate( sft ) );
1085 0 : flag1 = 1;
1086 0 : move16(); /* do the divide */
1087 : }
1088 0 : IF( EQ_16( flag1, 1 ) )
1089 : {
1090 0 : expb = norm_l( Lacc );
1091 0 : fracb = extract_h( L_shl( Lacc, expb ) );
1092 0 : expb = sub( 30, add( expb, shl( TMPDTFS_FX->Q, 1 ) ) );
1093 :
1094 0 : expa = norm_l( Lacc1 );
1095 0 : fraca = extract_h( L_shl( Lacc1, expa ) );
1096 0 : expa = sub( 30, add( expa, shl( TMPDTFS3_FX->Q, 1 ) ) );
1097 :
1098 0 : scale = shr( sub( fraca, fracb ), 15 );
1099 0 : fracb = shl( fracb, scale );
1100 0 : expb = sub( expb, scale );
1101 :
1102 0 : tmp = div_s( fracb, fraca ); /* tmp is always Q15 */
1103 0 : exp = sub( expb, expa ); /* Answer after division Lacc/Lacc1 = (2^exp)*(tmp/2^15) */
1104 :
1105 0 : L_tmp = L_deposit_h( tmp ); /* tmp is always Q15, L_tmp is always Q31 */
1106 0 : expa = norm_l( L_tmp );
1107 0 : L_tmp = L_shl( L_tmp, expa );
1108 0 : exp = sub( 30, add( expa, sub( 31, exp ) ) );
1109 0 : frac = Log2_norm_lc( L_tmp );
1110 0 : L_tmp = Mpy_32_16( exp, frac, 12330 ); /* L_tmp is always Q13 */
1111 : #ifdef ISSUE_1867_replace_overflow_libenc
1112 0 : Ltemp = L_shl_sat( L_tmp, 10 ); /* Ltemp is always Q23 */
1113 : #else
1114 : Ltemp = L_shl_o( L_tmp, 10, &Overflow ); /* Ltemp is always Q23 */
1115 : #endif
1116 : }
1117 : ELSE
1118 : {
1119 0 : Ltemp = L_add( MAX_32, 0 );
1120 : }
1121 :
1122 0 : test();
1123 0 : if ( ( Ltemp <= 0 ) && ( !hSC_VBR->rate_control ) )
1124 : {
1125 0 : PPP_MODE_E = 'B';
1126 0 : move16();
1127 : }
1128 :
1129 0 : IF( LT_16( shl_sat( hSC_VBR->vadsnr_fx, 1 ), hSC_VBR->SNR_THLD_fx ) ) /* Q8 */
1130 : {
1131 : /* if ((( tmp < 3.05 && max(res_enratio,sp_enratio) > 0.8 ) && (st->rate_control))||
1132 : (( tmp < 2.8 && max(res_enratio,sp_enratio) > 0.65 ) && (!st->rate_control))) */
1133 : /* First comparison in Q23, Second comparison in Q15 */
1134 0 : test();
1135 0 : test();
1136 0 : test();
1137 0 : test();
1138 0 : test();
1139 0 : if ( ( ( LT_32( Ltemp, 25585254 ) && GT_32( L_max( L_shl( res_enratio_fx, 4 ), sp_enratio_fx ), 6554 ) ) && ( hSC_VBR->rate_control ) ) ||
1140 0 : ( ( LT_32( Ltemp, 23488102 ) && GT_32( L_max( L_shl( res_enratio_fx, 4 ), sp_enratio_fx ), 5325 ) ) && ( !hSC_VBR->rate_control ) ) )
1141 : {
1142 0 : PPP_MODE_E = 'B';
1143 0 : move16();
1144 : }
1145 : }
1146 : ELSE
1147 : {
1148 : /* if ((( tmp < 2.4 && max(res_enratio,sp_enratio) > 0.94) && (st->rate_control))||
1149 : (( tmp < 4.5 && max(res_enratio,sp_enratio) > 0.5 ) && (!st->rate_control))) */
1150 0 : test();
1151 0 : test();
1152 0 : test();
1153 0 : test();
1154 0 : test();
1155 0 : if ( ( ( LT_32( Ltemp, 20132659 ) && GT_32( L_max( L_shl( res_enratio_fx, 4 ), sp_enratio_fx ), 7700 ) ) && ( hSC_VBR->rate_control ) ) ||
1156 0 : ( ( LT_32( Ltemp, 37748736 ) && GT_32( L_max( L_shl( res_enratio_fx, 4 ), sp_enratio_fx ), 4096 ) ) && ( !hSC_VBR->rate_control ) ) )
1157 : {
1158 0 : PPP_MODE_E = 'B';
1159 0 : move16();
1160 : }
1161 : }
1162 :
1163 : /* -----End closed-loop Bump-Up */
1164 : }
1165 : ELSE
1166 : {
1167 0 : PPP_MODE_E = 'B';
1168 0 : move16(); /*Amplitude quantization is failing*/
1169 : }
1170 : }
1171 : ELSE
1172 : {
1173 : }
1174 0 : IF( PPP_MODE_E == 'B' )
1175 : {
1176 0 : hSC_VBR->bump_up = 1;
1177 0 : move16();
1178 0 : free( CURRP_NQ_FX );
1179 0 : free( TMPDTFS_FX );
1180 0 : free( TMPDTFS2_FX );
1181 0 : free( TMPDTFS3_FX );
1182 0 : free( CURRP_Q_E_FX );
1183 0 : free( dtfs_temp_fx );
1184 0 : return error;
1185 : }
1186 :
1187 0 : IF( hSC_VBR->Q_to_F )
1188 : {
1189 0 : hSC_VBR->patterncount = add( hSC_VBR->patterncount, hSC_VBR->pattern_m );
1190 0 : move16();
1191 :
1192 0 : IF( GE_16( hSC_VBR->patterncount, 1000 ) )
1193 : {
1194 0 : hSC_VBR->patterncount = sub( hSC_VBR->patterncount, 1000 );
1195 0 : move16();
1196 0 : PPP_MODE_E = 'B';
1197 0 : move16();
1198 0 : hSC_VBR->bump_up = 1;
1199 0 : move16();
1200 0 : free( CURRP_NQ_FX );
1201 0 : free( TMPDTFS_FX );
1202 0 : free( TMPDTFS2_FX );
1203 0 : free( TMPDTFS3_FX );
1204 0 : free( CURRP_Q_E_FX );
1205 0 : free( dtfs_temp_fx );
1206 0 : return error;
1207 : }
1208 : }
1209 :
1210 : /* packetization of the delta lag in_fx PPP */
1211 0 : IF( EQ_16( PPP_MODE_E, 'Q' ) )
1212 : {
1213 0 : Q_delta_lag = add( delta_lag_E, 11 ); /* to make it positive always */
1214 :
1215 0 : push_indice( hBstr, IND_DELTALAG, Q_delta_lag, 5 );
1216 : }
1217 :
1218 0 : WIsyn_fx( *dtfs_temp_fx, CURRP_Q_E_FX, lpc2_fx, &( hSC_VBR->ph_offset_E_fx ), out_fx, L_FRAME, 0, S_fx, C_fx,
1219 : pf_temp1, pf_temp2, pf_temp, pf_n2 );
1220 : /* i/o ph_offset_fx in Q15, out_fx in Q0 */
1221 :
1222 0 : DTFS_copy_fx( dtfs_temp_fx, *CURRP_Q_E_FX );
1223 0 : Lacc = DTFS_getEngy_P2A_fx( CURRP_NQ_FX );
1224 0 : move32();
1225 0 : hSC_VBR->Q_prev_cw_en_fx = norm_l( Lacc );
1226 0 : move16();
1227 : /* hSC_VBR->Q_prev_cw_en_fx = (Lacc==0)?31: hSC_VBR->Q_prev_cw_en_fx;move16(); */
1228 0 : if ( Lacc == 0 )
1229 : {
1230 0 : hSC_VBR->Q_prev_cw_en_fx = 31;
1231 0 : move16();
1232 : }
1233 :
1234 0 : hSC_VBR->prev_cw_en_fx = (Word32) L_shl( Lacc, hSC_VBR->Q_prev_cw_en_fx ); /*2Q+Q_prev_cw_en_fx */
1235 0 : move32();
1236 0 : hSC_VBR->Q_prev_cw_en_fx = add( hSC_VBR->Q_prev_cw_en_fx, shl( CURRP_NQ_FX->Q, 1 ) );
1237 0 : move16();
1238 : /* Copy DTFS related parameters from 'dtfs_temp' to 'st_fx' structure */
1239 0 : hSC_VBR->dtfs_enc_lag = dtfs_temp_fx->lag_fx;
1240 0 : move16();
1241 0 : hSC_VBR->dtfs_enc_nH = dtfs_temp_fx->nH_fx;
1242 0 : move16();
1243 0 : hSC_VBR->dtfs_enc_nH_4kHz = dtfs_temp_fx->nH_4kHz_fx;
1244 0 : move16();
1245 0 : hSC_VBR->dtfs_enc_upper_cut_off_freq_of_interest_fx = dtfs_temp_fx->upper_cut_off_freq_of_interest_fx;
1246 0 : move16();
1247 0 : hSC_VBR->dtfs_enc_upper_cut_off_freq_fx = dtfs_temp_fx->upper_cut_off_freq_fx;
1248 0 : move16();
1249 0 : Copy( dtfs_temp_fx->a_fx, hSC_VBR->dtfs_enc_a_fx, MAXLAG_WI );
1250 0 : Copy( dtfs_temp_fx->b_fx, hSC_VBR->dtfs_enc_b_fx, MAXLAG_WI );
1251 :
1252 0 : hSC_VBR->dtfs_enc_Q = dtfs_temp_fx->Q;
1253 0 : move16();
1254 :
1255 0 : free( CURRP_NQ_FX );
1256 0 : free( TMPDTFS_FX );
1257 0 : free( TMPDTFS2_FX );
1258 0 : free( TMPDTFS3_FX );
1259 0 : free( CURRP_Q_E_FX );
1260 0 : free( dtfs_temp_fx );
1261 :
1262 0 : return error;
1263 : }
1264 :
1265 :
1266 : /*===================================================================*/
1267 : /* FUNCTION : synthesis_filter_fx () */
1268 : /*-------------------------------------------------------------------*/
1269 : /* PURPOSE : IIR-filter residual by the LPC sysnthesis filter */
1270 : /*-------------------------------------------------------------------*/
1271 : /* INPUT ARGUMENTS : */
1272 : /* */
1273 : /* _ (Word16 []) b : filter coefficients (Qc). */
1274 : /* _ (Word16 []) x : residual input (Qn). */
1275 : /* _ (Word16) P : filter order. */
1276 : /* _ (Word16) N : number of input samples. */
1277 : /* _ (Word16) Qa : Q factor compensation (Qa=15-Qc) */
1278 : /*-------------------------------------------------------------------*/
1279 : /* OUTPUT ARGUMENTS : */
1280 : /* */
1281 : /* _ (Word16 []) y : output speech (Qn) */
1282 : /*-------------------------------------------------------------------*/
1283 : /* INPUT/OUTPUT ARGUMENTS : */
1284 : /* */
1285 : /* _ (Word32 []) buf : filter memory (Q16+Qn) */
1286 : /*-------------------------------------------------------------------*/
1287 : /* RETURN ARGUMENTS : _ None. */
1288 : /*===================================================================*/
1289 : /* y(n)=sum(i=1 to 10){ */
1290 : /* rxLpcCoeff(i)*rxFormSynthMem(n-i) */
1291 : /* } */
1292 : /* +fres(n) */
1293 : /*===================================================================*/
1294 0 : static void synthesis_filter_fx( Word16 b[], Word16 x[], Word16 y[], Word16 buf[], Word16 P, Word16 N )
1295 : {
1296 : Word32 acc;
1297 : Word16 i, j;
1298 : #ifndef ISSUE_1867_replace_overflow_libenc
1299 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1300 : Flag Overflow = 0;
1301 : move32();
1302 : #endif
1303 : #endif
1304 0 : FOR( i = 0; i < N; i++ )
1305 : {
1306 0 : acc = L_deposit_h( *x++ ); /*Q16 */
1307 0 : acc = L_shr( acc, 3 ); /*Q13 */
1308 :
1309 0 : FOR( j = P - 1; j > 0; j-- )
1310 : {
1311 : /* acc = L_sub(acc, L_mult(memory[j], coef[j])); */
1312 : #ifdef ISSUE_1867_replace_overflow_libenc
1313 0 : acc = L_msu_sat( acc, buf[j], b[j] ); /*Q13 */
1314 : #else
1315 : acc = L_msu_o( acc, buf[j], b[j], &Overflow ); /*Q13 */
1316 : #endif
1317 0 : buf[j] = buf[j - 1];
1318 0 : move16();
1319 : }
1320 : /* acc = L_sub(acc, L_mult(memory[0], coef[0])); */
1321 : #ifdef ISSUE_1867_replace_overflow_libenc
1322 0 : acc = L_msu_sat( acc, buf[0], b[0] );
1323 0 : acc = L_shl_sat( acc, 3 );
1324 0 : *y++ = round_fx_sat( acc );
1325 0 : buf[0] = round_fx_sat( acc );
1326 : #else
1327 : acc = L_msu_o( acc, buf[0], b[0], &Overflow );
1328 : acc = L_shl_o( acc, 3, &Overflow );
1329 :
1330 : *y++ = round_fx_o( acc, &Overflow );
1331 :
1332 : buf[0] = round_fx_o( acc, &Overflow );
1333 : #endif
1334 0 : move16();
1335 0 : move16();
1336 : }
1337 0 : }
1338 : /*==============================================================================*/
1339 : /* FUNCTION : DTFS_freq_corr_fx () */
1340 : /*------------------------------------------------------------------------------*/
1341 : /* PURPOSE : */
1342 : /*------------------------------------------------------------------------------*/
1343 : /* INPUT ARGUMENTS : */
1344 : /* _ (struct DTFS_STRUCTURE_FX) X1_DTFS_fx : a_fx/b_fx in X1_DTFS_fx.Q */
1345 : /* _ (struct DTFS_STRUCTURE_FX) X2_DTFS_fx : a_fx/b_fx in X2_DTFS_fx.Q */
1346 : /* _ (Word16) lband: Q0 */
1347 : /* _ (Word16) hband: Q0 */
1348 : /*------------------------------------------------------------------------------*/
1349 : /* OUTPUT ARGUMENTS : */
1350 : /* _ (Word16) *Qout : Q of output result */
1351 : /*------------------------------------------------------------------------------*/
1352 : /* INPUT/OUTPUT ARGUMENTS : */
1353 : /* _ None */
1354 : /*------------------------------------------------------------------------------*/
1355 : /* RETURN ARGUMENTS : */
1356 : /* _ (Word32) Result : Qout */
1357 : /*------------------------------------------------------------------------------*/
1358 : /* CALLED FROM : TX */
1359 : /*==============================================================================*/
1360 :
1361 0 : static Word32 DTFS_freq_corr_fx(
1362 : DTFS_STRUCTURE X1_DTFS_fx,
1363 : DTFS_STRUCTURE X2_DTFS_fx,
1364 : Word16 lband,
1365 : Word16 hband,
1366 : Word16 *Qout )
1367 : {
1368 : Word16 k, HalfLag, lk, hk;
1369 : Word32 corr_fx;
1370 : Word32 freq_fx, L_lband, L_hband;
1371 : Word32 E_fx;
1372 : Word32 Num, Den, Result;
1373 : Word16 E1_fx, E2_fx, q1, q2, Qr;
1374 : Word16 expa, expb, fraca, fracb, scale;
1375 : Word16 exp, tmp;
1376 : Word32 L_tmp;
1377 : Word16 Q_num, Q_den;
1378 : #if !defined( ISSUE_1867_replace_overflow_libenc )
1379 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1380 : Flag Overflow = 0;
1381 : move32();
1382 : #endif
1383 : #endif
1384 0 : IF( LT_16( X1_DTFS_fx.lag_fx, X2_DTFS_fx.lag_fx ) )
1385 : {
1386 0 : DTFS_zeroPadd_fx( X2_DTFS_fx.lag_fx, &X1_DTFS_fx );
1387 : }
1388 :
1389 0 : corr_fx = L_deposit_l( 0 );
1390 :
1391 0 : L_lband = L_mult( lband, X2_DTFS_fx.lag_fx ); /* Q0 * Q0 -> Q1 */
1392 0 : L_hband = L_mult( hband, X2_DTFS_fx.lag_fx ); /* Q0 * Q0 -> Q1 */
1393 0 : HalfLag = s_min( shr( X2_DTFS_fx.lag_fx, 1 ), X2_DTFS_fx.nH_4kHz_fx );
1394 :
1395 : /* get lband and hband */
1396 0 : FOR( k = 0; k <= HalfLag; k++ )
1397 : {
1398 0 : freq_fx = L_mult( k, 12800 );
1399 0 : if ( GE_32( freq_fx, L_lband ) )
1400 : {
1401 0 : BREAK;
1402 : }
1403 : }
1404 0 : lk = k;
1405 0 : FOR( k = 0; k <= HalfLag; k++ )
1406 : {
1407 0 : freq_fx = L_mult( k, 12800 );
1408 0 : if ( GE_32( freq_fx, L_hband ) )
1409 : {
1410 0 : BREAK;
1411 : }
1412 : }
1413 0 : hk = k;
1414 0 : move16();
1415 :
1416 0 : FOR( k = lk; k < hk; k++ )
1417 : {
1418 : #ifdef ISSUE_1867_replace_overflow_libenc
1419 0 : corr_fx = L_mac0_sat( corr_fx, X1_DTFS_fx.a_fx[k], X2_DTFS_fx.a_fx[k] ); /* Q(1) */
1420 0 : corr_fx = L_mac0_sat( corr_fx, X1_DTFS_fx.b_fx[k], X2_DTFS_fx.b_fx[k] ); /* Q(1) */
1421 : #else
1422 : corr_fx = L_mac0_o( corr_fx, X1_DTFS_fx.a_fx[k], X2_DTFS_fx.a_fx[k], &Overflow ); /* Q(1) */
1423 : corr_fx = L_mac0_o( corr_fx, X1_DTFS_fx.b_fx[k], X2_DTFS_fx.b_fx[k], &Overflow ); /* Q(1) */
1424 : #endif
1425 : }
1426 :
1427 0 : Qr = norm_l( corr_fx );
1428 0 : if ( corr_fx == 0 )
1429 : {
1430 0 : Qr = 31;
1431 0 : move16();
1432 : }
1433 :
1434 : #ifdef ISSUE_1867_replace_overflow_libenc
1435 0 : E1_fx = round_fx_sat( L_shl_sat( corr_fx, Qr ) ); /* Q(Qr-16) */
1436 : #else
1437 : E1_fx = round_fx_o( L_shl_o( corr_fx, Qr, &Overflow ), &Overflow ); /* Q(Qr-16) */
1438 : #endif
1439 0 : Num = L_mult0( E1_fx, E1_fx ); /* Q(2+2*Qr-32+1) */
1440 0 : Q_num = sub( shl( add( add( X1_DTFS_fx.Q, X2_DTFS_fx.Q ), Qr ), 1 ), 32 );
1441 :
1442 : /* PORTING: Handling the functions with variable no. of arguments */
1443 0 : E_fx = DTFS_getEngy_band_fx( X1_DTFS_fx, lband, hband ); /* Q(1) */
1444 0 : move32();
1445 0 : q1 = norm_l( E_fx );
1446 0 : if ( E_fx == 0 )
1447 : {
1448 0 : q1 = 31;
1449 0 : move16();
1450 : }
1451 :
1452 : #ifdef ISSUE_1867_replace_overflow_libenc
1453 0 : E1_fx = round_fx_sat( L_shl_sat( E_fx, q1 ) ); /* Q(1+q1-16) */
1454 : #else
1455 : E1_fx = round_fx_o( L_shl_o( E_fx, q1, &Overflow ), &Overflow ); /* Q(1+q1-16) */
1456 : #endif
1457 : /* PORTING: Handling the functions with variable no. of arguments */
1458 0 : E_fx = DTFS_getEngy_band_fx( X2_DTFS_fx, lband, hband ); /* Q(1) */
1459 0 : q2 = norm_l( E_fx );
1460 0 : if ( E_fx == 0 )
1461 : {
1462 0 : q2 = 31;
1463 0 : move16();
1464 : }
1465 :
1466 : #ifdef ISSUE_1867_replace_overflow_libenc
1467 0 : E2_fx = round_fx_sat( L_shl_sat( E_fx, q2 ) ); /* Q(1+q2-16) */
1468 : #else
1469 : E2_fx = round_fx_o( L_shl_o( E_fx, q2, &Overflow ), &Overflow ); /* Q(1+q2-16) */
1470 : #endif
1471 0 : Den = L_mult0( E1_fx, E2_fx ); /* Q(2+q1+q2-32+1) */
1472 0 : Q_den = sub( add( shl( add( X2_DTFS_fx.Q, X1_DTFS_fx.Q ), 1 ), add( q1, q2 ) ), 32 );
1473 :
1474 0 : Num = L_max( Num, 1 );
1475 :
1476 0 : IF( Num == 0 )
1477 : {
1478 0 : Result = 0;
1479 0 : move32();
1480 0 : *Qout = 31;
1481 0 : move16();
1482 : }
1483 : ELSE
1484 : {
1485 :
1486 0 : expa = norm_l( Num );
1487 : #ifdef ISSUE_1867_replace_overflow_libenc
1488 0 : fraca = extract_h( L_shl_sat( Num, expa ) );
1489 : #else
1490 : fraca = extract_h( L_shl_o( Num, expa, &Overflow ) );
1491 : #endif
1492 0 : expa = sub( 30, add( expa, Q_num ) );
1493 :
1494 :
1495 0 : expb = norm_l( Den );
1496 : #ifdef ISSUE_1867_replace_overflow_libenc
1497 0 : fracb = round_fx_sat( L_shl( Den, expb ) );
1498 : #else
1499 : fracb = round_fx_o( L_shl_o( Den, expb, &Overflow ), &Overflow );
1500 : #endif
1501 0 : expb = sub( 30, add( expb, Q_den ) );
1502 :
1503 :
1504 0 : scale = shr( sub( fraca, fracb ), 15 );
1505 0 : fracb = shl_sat( fracb, scale );
1506 0 : expb = sub( expb, scale );
1507 :
1508 0 : tmp = div_s( fracb, fraca );
1509 0 : exp = sub( expb, expa );
1510 :
1511 0 : L_tmp = Isqrt_lc( L_deposit_h( tmp ), &exp ); /* Q(31-exp) */
1512 0 : IF( corr_fx > 0 )
1513 : {
1514 0 : Result = L_add( L_tmp, 0 );
1515 : }
1516 : ELSE
1517 : {
1518 0 : Result = L_negate( L_tmp );
1519 : }
1520 0 : *Qout = sub( 30, exp );
1521 0 : move16();
1522 : }
1523 0 : return Result;
1524 : }
1525 : /*===================================================================*/
1526 : /* FUNCTION : DTFS_alignment_extract_td_fx () */
1527 : /*-------------------------------------------------------------------*/
1528 : /* PURPOSE : search for alignment in time domain */
1529 : /*-------------------------------------------------------------------*/
1530 : /* INPUT ARGUMENTS : */
1531 : /* _ (Word16 *) x1: Q? */
1532 : /* _ (Word16 *) x2: Q? */
1533 : /*-------------------------------------------------------------------*/
1534 : /* OUTPUT ARGUMENTS : */
1535 : /* _ (Word16) lag : Q0 */
1536 : /*-------------------------------------------------------------------*/
1537 : /* INPUT/OUTPUT ARGUMENTS : */
1538 : /* _ None */
1539 : /*-------------------------------------------------------------------*/
1540 : /* RETURN ARGUMENTS : _ (Word16 *) idx: Q0 */
1541 : /*-------------------------------------------------------------------*/
1542 : /* CALLED FROM : TX */
1543 : /*===================================================================*/
1544 :
1545 0 : static Word16 DTFS_alignment_extract_td_fx( Word16 *x1, Word16 *x2, Word16 lag )
1546 : {
1547 : Word16 j, k, idx, Adiff_fx;
1548 : Word32 maxcorr, corr;
1549 : #ifndef ISSUE_1867_replace_overflow_libenc
1550 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1551 : Flag Overflow = 0;
1552 : move32();
1553 : #endif
1554 : #endif
1555 0 : maxcorr = L_add( MIN_32, 0 );
1556 0 : Adiff_fx = (Word16) ( s_max( 4, shr( lag, 3 ) ) );
1557 :
1558 0 : idx = 0;
1559 0 : move16();
1560 0 : FOR( j = negate( Adiff_fx ); j <= Adiff_fx; j++ )
1561 : {
1562 0 : corr = L_deposit_l( 0 );
1563 0 : FOR( k = 0; k < lag; k++ )
1564 : {
1565 : #ifdef ISSUE_1867_replace_overflow_libenc
1566 0 : corr = L_mac_sat( corr, x1[k], x2[( k - j + lag ) % lag] );
1567 : #else
1568 : corr = L_mac_o( corr, x1[k], x2[( k - j + lag ) % lag], &Overflow );
1569 : #endif
1570 : }
1571 0 : IF( GT_32( corr, maxcorr ) )
1572 : {
1573 0 : idx = j;
1574 0 : move16();
1575 0 : maxcorr = L_add( corr, 0 );
1576 : }
1577 : }
1578 0 : return idx;
1579 : }
1580 : /*=================================================================================*/
1581 : /* FUNCTION : DTFS_getEngy_band_fx (Word16 lband, Word16 hband) */
1582 : /*---------------------------------------------------------------------------------*/
1583 : /* PURPOSE : compute the energy of X1.a[k] and X2.b[k] */
1584 : /*---------------------------------------------------------------------------------*/
1585 : /* INPUT ARGUMENTS : */
1586 : /* _ (struct DTFS_STRUCTURE_FX) X_fx : a_fx/b_fx in X_fx.Q, lag in Q0 */
1587 : /* _ (Word16) lband: Q0 */
1588 : /* _ (Word16) hband: Q0 */
1589 : /*---------------------------------------------------------------------------------*/
1590 : /* OUTPUT ARGUMENTS : */
1591 : /* _ (Word40) en_fx : 2*X1.Q */
1592 : /*---------------------------------------------------------------------------------*/
1593 : /* INPUT/OUTPUT ARGUMENTS : */
1594 : /* _ None */
1595 : /*---------------------------------------------------------------------------------*/
1596 : /* RETURN ARGUMENTS : _ None. */
1597 : /*---------------------------------------------------------------------------------*/
1598 : /* CALLED FROM : TX */
1599 : /*=================================================================================*/
1600 :
1601 : /* PORTING: Handling the functions with variable no. of arguments */
1602 :
1603 0 : static Word32 DTFS_getEngy_band_fx(
1604 : DTFS_STRUCTURE X_fx,
1605 : const Word16 lband,
1606 : const Word16 hband )
1607 : {
1608 : Word16 k, lk, hk, HalfLag;
1609 : Word32 freq_fx, L_lband, L_hband;
1610 0 : Word32 en_fx = 0;
1611 0 : move32();
1612 : #ifndef ISSUE_1867_replace_overflow_libenc
1613 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1614 : Flag Overflow = 0;
1615 : move32();
1616 : #endif
1617 : #endif
1618 0 : L_lband = L_mult( lband, X_fx.lag_fx ); /* Q0 * Q0 -> Q1 */
1619 0 : L_hband = L_mult( hband, X_fx.lag_fx ); /* Q0 * Q0 -> Q1 */
1620 0 : HalfLag = s_min( shr( sub( X_fx.lag_fx, 1 ), 1 ), X_fx.nH_4kHz_fx );
1621 : /* get lband and hband */
1622 0 : FOR( k = 1; k <= HalfLag; k++ )
1623 : {
1624 0 : freq_fx = L_mult( k, 12800 );
1625 0 : if ( GE_32( freq_fx, L_lband ) )
1626 : {
1627 0 : BREAK;
1628 : }
1629 : }
1630 0 : lk = k;
1631 0 : move16();
1632 0 : FOR( k = 1; k <= HalfLag; k++ )
1633 : {
1634 0 : freq_fx = L_mult( k, 12800 );
1635 0 : if ( GE_32( freq_fx, L_hband ) )
1636 : {
1637 0 : BREAK;
1638 : }
1639 : }
1640 0 : hk = k;
1641 0 : move16();
1642 :
1643 0 : FOR( k = lk; k < hk; k++ )
1644 : {
1645 : #ifdef ISSUE_1867_replace_overflow_libenc
1646 0 : en_fx = L_mac0_sat( en_fx, X_fx.a_fx[k], X_fx.a_fx[k] ); /* 2*X1.Q+1 */
1647 0 : en_fx = L_mac0_sat( en_fx, X_fx.b_fx[k], X_fx.b_fx[k] );
1648 : #else
1649 : en_fx = L_mac0_o( en_fx, X_fx.a_fx[k], X_fx.a_fx[k], &Overflow ); /* 2*X1.Q+1 */
1650 : en_fx = L_mac0_o( en_fx, X_fx.b_fx[k], X_fx.b_fx[k], &Overflow );
1651 : #endif
1652 : }
1653 :
1654 0 : if ( lband == 0 )
1655 : {
1656 0 : en_fx = L_mac0( en_fx, X_fx.a_fx[0], X_fx.a_fx[0] ); /* 2*X1.Q+1 */
1657 : }
1658 :
1659 : /* IF ((X_fx.lag_fx%2 == 0) && (hband == X_fx.upper_cut_off_freq_fx)) */
1660 0 : test();
1661 0 : IF( ( s_and( X_fx.lag_fx, 1 ) == 0 ) && ( hband == X_fx.upper_cut_off_freq_fx ) )
1662 : {
1663 : #ifdef ISSUE_1867_replace_overflow_libenc
1664 0 : en_fx = L_mac0_sat( en_fx, X_fx.a_fx[k], X_fx.a_fx[k] );
1665 0 : en_fx = L_mac0_sat( en_fx, X_fx.b_fx[k], X_fx.b_fx[k] );
1666 : #else
1667 : en_fx = L_mac0_o( en_fx, X_fx.a_fx[k], X_fx.a_fx[k], &Overflow );
1668 : en_fx = L_mac0_o( en_fx, X_fx.b_fx[k], X_fx.b_fx[k], &Overflow );
1669 : #endif
1670 : }
1671 :
1672 0 : return en_fx; /* 2*X1.Q */
1673 : }
1674 : /*---------------------------------------------------------------------*
1675 : * sc_vbr_enc_init_fx()
1676 : *
1677 : * Initialize SC-VBR encoder
1678 : *---------------------------------------------------------------------*/
1679 :
1680 3 : void sc_vbr_enc_init_fx(
1681 : SC_VBR_ENC_HANDLE hSC_VBR /* i/o: SC-VBR encoder handle */
1682 : )
1683 : {
1684 3 : hSC_VBR->nelp_enc_seed = 0;
1685 3 : move16();
1686 3 : hSC_VBR->last_nelp_mode = 0;
1687 3 : move16();
1688 3 : hSC_VBR->pppcountE = 0;
1689 3 : move16();
1690 3 : hSC_VBR->last_ppp_mode = 0;
1691 3 : move16();
1692 3 : hSC_VBR->last_last_ppp_mode = 0;
1693 3 : move16();
1694 3 : hSC_VBR->firstTime_voicedenc = 1;
1695 3 : move16();
1696 3 : hSC_VBR->prev_ppp_gain_pit_fx = 0;
1697 3 : move16();
1698 3 : hSC_VBR->prev_tilt_code_fx = 0;
1699 3 : move16();
1700 :
1701 3 : hSC_VBR->ppp_mode = 0;
1702 3 : move16();
1703 3 : hSC_VBR->nelp_mode = 0;
1704 3 : move16();
1705 :
1706 :
1707 3 : hSC_VBR->pattern_m = 0;
1708 3 : move16();
1709 3 : hSC_VBR->Last_Resort = 0;
1710 3 : move16();
1711 3 : hSC_VBR->Q_to_F = 0;
1712 3 : move16();
1713 :
1714 3 : hSC_VBR->numactive = 0; /* keep the count of the frames inside current 600 frame bloack.*/
1715 3 : move16();
1716 3 : hSC_VBR->sum_of_rates_fx = 0; /* sum of the rates of past 600 active frames*/
1717 3 : move32();
1718 3 : hSC_VBR->global_avr_rate_fx = 0; /* global rate upto current time. recorded a (rate in kbps) *6000*/
1719 3 : move32();
1720 3 : hSC_VBR->global_frame_cnt = 0; /* 600 active frame block count. Used to update the global rate*/
1721 3 : move16();
1722 3 : hSC_VBR->rate_control = 0;
1723 3 : move16();
1724 3 : hSC_VBR->SNR_THLD_fx = SNR_THLD_FX_Q8;
1725 3 : move16();
1726 3 : hSC_VBR->mode_QQF = 1;
1727 3 : move16();
1728 :
1729 3 : hSC_VBR->vbr_generic_ho = 0;
1730 3 : move16();
1731 3 : hSC_VBR->Local_VAD = 0;
1732 3 : move16();
1733 3 : hSC_VBR->Last_Resort = 0;
1734 3 : move16();
1735 3 : hSC_VBR->set_ppp_generic = 0;
1736 3 : move16();
1737 3 : hSC_VBR->last_7k2_coder_type = GENERIC;
1738 3 : move16();
1739 :
1740 3 : set16_fx( hSC_VBR->shape1_filt_mem_fx, 0, 10 );
1741 3 : set16_fx( hSC_VBR->shape2_filt_mem_fx, 0, 10 );
1742 3 : set16_fx( hSC_VBR->shape3_filt_mem_fx, 0, 10 );
1743 3 : set16_fx( hSC_VBR->txlpf1_filt1_mem_fx, 0, 10 );
1744 3 : set16_fx( hSC_VBR->txlpf1_filt2_mem_fx, 0, 10 );
1745 3 : set16_fx( hSC_VBR->txhpf1_filt1_mem_fx, 0, 10 );
1746 3 : set16_fx( hSC_VBR->txhpf1_filt2_mem_fx, 0, 10 );
1747 3 : hSC_VBR->qprevIn_fx = 0;
1748 3 : move16();
1749 3 : hSC_VBR->qprevGain_fx = 0;
1750 3 : move16();
1751 :
1752 3 : return;
1753 : }
|