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 : #include "rom_com.h"
9 : #include "ivas_prot_fx.h"
10 :
11 :
12 : /*---------------------------------------------------------------------*
13 : * Local function prototypes
14 : *---------------------------------------------------------------------*/
15 : static Word16 FEC_phase_matching_fx( HQ_NBFEC_HANDLE st_fx, Word32 *ImdctOut_fx, Word16 *auOut_fx, Word16 *OldauOut_fx, Word16 OldauOut_pha_fx[2][N_LEAD_NB] );
16 : static void FEC_phase_matching_nextgood_fx( const Word32 *ImdctOut_fx, Word16 *auOut_fx, Word16 *OldauOut_fx, Word16 OldauOut_pha_fx[2][N_LEAD_NB], Word16 mean_en_high_fx );
17 : static void FEC_phase_matching_burst_fx( const Word32 *ImdctOut_fx, Word16 *auOut_fx, Word16 *OldauOut_fx, Word16 OldauOut_pha_fx[2][N_LEAD_NB], Word16 *prev_oldauOut_fx );
18 : static void Repetition_smoothing_nextgood_fx( const Word32 *ImdctOut_fx, Word16 *auOut_fx, Word32 *OldImdctOut_fx, Word16 *OldauOut_fx, Word16 cur_data_use_flag, Word16 overlap_time );
19 : static Word16 Repetition_smoothing_fx( const Word32 *ImdctOut_fx, Word16 *auOut_fx, Word32 *OldImdctOut_fx, Word16 *OldauOut_fx, const Word16 L, Word16 *prev_oldauOut_fx, Word16 overlap_time );
20 : static void Smoothing_vector_scaledown_NB_fx( const Word16 OldauOutnoWin_fx[], const Word16 ImdctOutWin_fx[], const Word16 SmoothingWin_fx[], Word16 auOut_fx[], const Word16 ol_size );
21 : static void Smoothing_vector_NB_fx( const Word16 OldauOutnoWin_fx[], const Word16 ImdctOutWin_fx[], const Word16 SmoothingWin_fx[], Word16 auOut_fx[], const Word16 ol_size );
22 : static void Windowing_1st_NB_fx( Word16 *ImdctOutWin_fx, const Word32 *ImdctOut_fx, const Word16 *win_fx, const Word16 *smoothingWin_fx, Word16 smoothing_flag );
23 : static void Windowing_2nd_NB_fx( Word16 *ImdctOutWin_fx, const Word32 *ImdctOut_fx, const Word16 *win_fx );
24 : static void Scaledown_fx( Word16 x[], Word16 y[], Word16 scale_v, const Word16 N );
25 : static void Next_good_after_burst_erasures_fx( const Word32 *ImdctOut_fx, Word16 *auOut_fx, Word16 *OldauOut_fx, const Word16 ol_size );
26 : static void common_overlapping_fx( Word16 *auOut_fx, Word16 *ImdctOutWin_fx, Word16 *OldauOut_fx, Word16 end1, Word16 offset1, Word16 start2, Word16 end2, Word16 offset_i2, Word16 offset2 );
27 :
28 : /*--------------------------------------------------------------------------*
29 : * Regression_Anal()
30 : *
31 : *
32 : *--------------------------------------------------------------------------*/
33 0 : static void Regression_Anal_fx(
34 : const Word32 *values_fx,
35 : /* i : Previous values */ // Q12
36 : Word32 *r_p_fx,
37 : /* o : Output r[a b] array : y=ax+b */ // Q5
38 : const Word16 num_pgf /* i : Number of previous good frame */
39 : )
40 : {
41 : Word16 i;
42 : Word16 tmp;
43 : Word32 L_tmp1, L_tmp2;
44 : Word16 aindex_fx[MAX_PGF + 1]; // Q0
45 : Word32 b_p_fx[MAX_PGF + 1]; // Q10
46 : #ifndef ISSUE_1866_replace_overflow_libdec
47 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
48 : Flag Overflow = 0;
49 : move32();
50 : #endif
51 : #endif
52 :
53 : /* Initialize */
54 0 : FOR( i = 0; i < add( num_pgf, 1 ); i++ )
55 : {
56 0 : aindex_fx[i] = 0;
57 0 : move16();
58 0 : b_p_fx[i] = 0;
59 0 : move16();
60 : }
61 :
62 : /* [aindex[0] aindex[1]][r[0]]=[b[0]]*/
63 : /* [aindex[1] aindex[2]][r[1]] [b[1]]*/
64 : /* r[0] is the y-intercept(initial value). r[1] is slope*/
65 :
66 : /* r[0] = (b[0]a[2]-a[1]b[1])/(a[0]a[2]-a[1]a[1])
67 : r[1] = (b[0]a[1]-a[0]b[1])/(a[1]a[1]-a[0]a[2]) */
68 : /*aindex[0]=num_pgf; */
69 0 : aindex_fx[0] = num_pgf;
70 0 : move16();
71 0 : FOR( i = 1; i < add( num_pgf, 1 ); i++ )
72 : {
73 0 : aindex_fx[1] = add( aindex_fx[1], i );
74 0 : move16();
75 0 : aindex_fx[2] = add( aindex_fx[2], i_mult( i, i ) );
76 0 : move16();
77 : }
78 : /* Calculate b[] */
79 0 : FOR( i = 0; i < num_pgf; i++ )
80 : {
81 0 : b_p_fx[0] = L_add( b_p_fx[0], L_shr( values_fx[i], 2 ) ); /*10 */
82 0 : move32();
83 : #ifdef ISSUE_1866_replace_overflow_libdec
84 0 : b_p_fx[1] = L_add( b_p_fx[1], Mult_32_16( values_fx[i], shl_sat( sub( num_pgf, i ), 13 ) ) ); /*10 */
85 : #else
86 : b_p_fx[1] = L_add( b_p_fx[1], Mult_32_16( values_fx[i], shl_o( sub( num_pgf, i ), 13, &Overflow ) ) ); /*10 */
87 : #endif
88 0 : move32();
89 : }
90 :
91 0 : tmp = sub( i_mult( aindex_fx[0], aindex_fx[2] ), i_mult( aindex_fx[1], aindex_fx[1] ) );
92 0 : tmp = inv_tbl_fx[tmp];
93 0 : move16(); /*15 */
94 0 : L_tmp1 = L_sub( Mult_32_16( b_p_fx[0], shl( aindex_fx[2], 10 ) ), Mult_32_16( b_p_fx[1], shl( aindex_fx[1], 10 ) ) ); /*5 */
95 0 : L_tmp2 = L_sub( Mult_32_16( b_p_fx[1], shl( aindex_fx[0], 10 ) ), Mult_32_16( b_p_fx[0], shl( aindex_fx[1], 10 ) ) ); /*5 */
96 0 : r_p_fx[0] = Mult_32_16( L_tmp1, tmp );
97 0 : move32();
98 0 : r_p_fx[1] = Mult_32_16( L_tmp2, tmp ); // Q15 + Q5 - Q15
99 0 : move32();
100 :
101 0 : return;
102 : }
103 :
104 0 : static void FEC_scaling_fx(
105 : Word32 *old_coeffs_fx,
106 : /* i/o : Pointer to old MDCT coeffs. */ // Q12
107 : Word32 *t_audio_q_fx,
108 : /* o : MDCT coeffs. (for synthesis) */ // Q12
109 : Word16 *Norm_gain_fx,
110 : /* i : Gain for Norm of each band */ // Q15
111 : Word16 *HQ_FEC_seed, /* i/o : Seed for Ransom number Generator */
112 : Word16 nb_sfm, /* i : Number of sub-band */
113 : const Word16 *start_band,
114 : const Word16 *end_band )
115 : {
116 : Word16 i, j;
117 :
118 0 : FOR( i = 0; i < RANDOM_START; i++ )
119 : {
120 0 : FOR( j = start_band[i]; j < end_band[i]; j++ )
121 : {
122 0 : t_audio_q_fx[j] = Mult_32_16( old_coeffs_fx[j], Norm_gain_fx[i] ); // Q12 + Q15 - Q15
123 0 : move32();
124 : }
125 : }
126 :
127 0 : FOR( i = RANDOM_START; i < nb_sfm; i++ )
128 : {
129 0 : FOR( j = start_band[i]; j < end_band[i]; j++ )
130 : {
131 0 : IF( Random( HQ_FEC_seed ) < 0 )
132 : {
133 0 : t_audio_q_fx[j] = Mult_32_16( L_negate( old_coeffs_fx[j] ), Norm_gain_fx[i] ); // Q12 + Q15 - Q15
134 0 : move32();
135 : }
136 : ELSE
137 : {
138 0 : t_audio_q_fx[j] = Mult_32_16( old_coeffs_fx[j], Norm_gain_fx[i] ); // Q12 + Q15 - Q15
139 0 : move32();
140 : }
141 : }
142 : }
143 0 : return;
144 : }
145 :
146 0 : void HQ_FEC_processing_fx(
147 : Decoder_State *st_fx, /* i/o: decoder state structure */
148 : Word32 *t_audio_q_fx, /* o : MDCT coeffs. (for synthesis) Q12 */
149 : Word16 is_transient, /* i : Old flag for transient */
150 : Word32 ynrm_values_fx[][MAX_PGF], /* i : Old average Norm values for each group of bands Q12 */
151 : Word32 r_p_values_fx[][MAX_ROW], /* i : Computed y-intercept and slope by Regression Q5 */
152 : Word16 num_Sb, /* i : Number of sub-band group */
153 : Word16 nb_sfm, /* i : Number of sub-band */
154 : Word16 *Num_bands_p, /* i : Number of coeffs. for each sub-band */
155 : Word16 output_frame, /* i : Frame size */
156 : const Word16 *sfm_start, /* i : Start of bands */
157 : const Word16 *sfm_end /* i : End of bands */
158 : )
159 : {
160 : Word16 i, j, k;
161 : Word16 mute_start, num_pgf;
162 : Word16 Num_sb_bwe;
163 : Word16 sfm;
164 :
165 : Word16 tmp_fx, exp1, exp2;
166 : Word32 norm_p_fx[MAX_SB_NB];
167 : Word32 *norm_values_fx /*Q12*/, *r_p_fx /*Q5*/;
168 : Word16 energy_diff_fx; // Q10
169 : HQ_NBFEC_HANDLE hHQ_nbfec;
170 : HQ_DEC_HANDLE hHQ_core;
171 : #ifndef ISSUE_1866_replace_overflow_libdec
172 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
173 : Flag Overflow = 0;
174 : move32();
175 : #endif
176 : #endif
177 0 : hHQ_nbfec = st_fx->hHQ_nbfec;
178 0 : hHQ_core = st_fx->hHQ_core;
179 :
180 :
181 : /* Decide the start frame number for adaptive muting */
182 : /* Normalized energy difference between the current frame and the moving average */
183 0 : tmp_fx = abs_s( sub( hHQ_nbfec->energy_MA_Curr_fx[1], hHQ_nbfec->energy_MA_Curr_fx[0] ) );
184 0 : exp1 = sub( norm_s( tmp_fx ), 1 );
185 0 : hHQ_nbfec->energy_MA_Curr_fx[0] = s_max( hHQ_nbfec->energy_MA_Curr_fx[0], 1 );
186 0 : move16();
187 0 : exp2 = norm_s( hHQ_nbfec->energy_MA_Curr_fx[0] );
188 0 : tmp_fx = div_s( shl( tmp_fx, exp1 ), shl( hHQ_nbfec->energy_MA_Curr_fx[0], exp2 ) ); /*15 + exp1 - exp2*/
189 0 : energy_diff_fx = shl( tmp_fx, sub( sub( exp2, exp1 ), 5 ) ); /*10*/
190 0 : test();
191 0 : IF( ( LT_16( energy_diff_fx, 1024 ) ) && ( is_transient == 0 ) ) /* First erasure frame */
192 : {
193 0 : mute_start = 5;
194 0 : move16();
195 : }
196 : ELSE
197 : {
198 0 : mute_start = 2;
199 0 : move16();
200 : }
201 0 : test();
202 0 : test();
203 0 : IF( EQ_16( st_fx->prev_old_bfi, 1 ) && EQ_16( st_fx->nbLostCmpt, 1 ) && EQ_16( output_frame, L_FRAME8k ) )
204 : {
205 0 : st_fx->nbLostCmpt = add( st_fx->nbLostCmpt, 1 );
206 0 : move32();
207 : }
208 :
209 : /* Frequency-domain FEC */
210 0 : IF( EQ_16( st_fx->nbLostCmpt, 1 ) ) /* First erasure frame */
211 : {
212 0 : IF( is_transient == 0 )
213 : {
214 0 : IF( LT_16( energy_diff_fx, 1024 ) )
215 : {
216 0 : FOR( i = 0; i < output_frame; i++ )
217 : {
218 0 : t_audio_q_fx[i] = hHQ_nbfec->old_coeffs_fx[i];
219 0 : move32();
220 : }
221 : }
222 : ELSE
223 : {
224 0 : FOR( i = 0; i < output_frame; i++ )
225 : {
226 0 : hHQ_nbfec->old_coeffs_fx[i] = Mult_32_16( hHQ_nbfec->old_coeffs_fx[i], 23170 ); /*23170, 3dB, Q15*/
227 0 : move32();
228 0 : t_audio_q_fx[i] = hHQ_nbfec->old_coeffs_fx[i];
229 0 : move32();
230 : }
231 : }
232 :
233 : /* Sign prediction in 4-dim bands up to 1.6 kHz*/
234 0 : IF( hHQ_core->old_is_transient[1] == 0 )
235 : {
236 0 : IF( hHQ_core->old_is_transient[2] == 0 )
237 : {
238 0 : FOR( sfm = 0; sfm < HQ_FEC_SIGN_SFM; sfm++ )
239 : {
240 0 : IF( GE_16( hHQ_nbfec->prev_sign_switch[sfm], HQ_FEC_SIGN_THRES ) )
241 : {
242 0 : FOR( i = 0; i < HQ_FEC_BAND_SIZE; i++ )
243 : {
244 0 : t_audio_q_fx[i + sfm * HQ_FEC_BAND_SIZE] = L_negate( t_audio_q_fx[i + sfm * HQ_FEC_BAND_SIZE] );
245 0 : move32();
246 : }
247 : }
248 : }
249 : }
250 : ELSE
251 : {
252 0 : FOR( sfm = 0; sfm < HQ_FEC_SIGN_SFM; sfm++ )
253 : {
254 0 : IF( GE_16( hHQ_nbfec->prev_sign_switch[sfm], HQ_FEC_SIGN_THRES_TRANS ) )
255 : {
256 0 : FOR( i = 0; i < HQ_FEC_BAND_SIZE; i++ )
257 : {
258 0 : t_audio_q_fx[i + sfm * HQ_FEC_BAND_SIZE] = L_negate( t_audio_q_fx[i + sfm * HQ_FEC_BAND_SIZE] );
259 0 : move32();
260 : }
261 : }
262 : }
263 : }
264 : }
265 : ELSE
266 : {
267 0 : FOR( i = RANDOM_START * 8; i < output_frame; i++ )
268 : {
269 0 : IF( Random( &hHQ_nbfec->HQ_FEC_seed ) < 0 )
270 : {
271 0 : t_audio_q_fx[i] = L_negate( t_audio_q_fx[i] );
272 0 : move32();
273 : }
274 : }
275 : }
276 : }
277 : ELSE
278 : {
279 0 : IF( hHQ_core->old_is_transient[1] ) /* hangover */
280 : {
281 0 : FOR( i = 0; i < output_frame; i++ )
282 : {
283 0 : hHQ_nbfec->old_coeffs_fx[i] = Mult_32_16( hHQ_nbfec->old_coeffs_fx[i], 23170 );
284 0 : move32();
285 0 : t_audio_q_fx[i] = hHQ_nbfec->old_coeffs_fx[i];
286 0 : move32();
287 : }
288 : }
289 : ELSE
290 : {
291 0 : FOR( i = 0; i < RANDOM_START * 8; i++ )
292 : {
293 0 : hHQ_nbfec->old_coeffs_fx[i] = Mult_32_16( hHQ_nbfec->old_coeffs_fx[i], 23170 );
294 0 : move32();
295 0 : t_audio_q_fx[i] = hHQ_nbfec->old_coeffs_fx[i];
296 0 : move32();
297 : }
298 :
299 0 : FOR( i = RANDOM_START * 8; i < output_frame; i++ )
300 : {
301 0 : hHQ_nbfec->old_coeffs_fx[i] = Mult_32_16( hHQ_nbfec->old_coeffs_fx[i], 23170 );
302 0 : move32();
303 0 : IF( Random( &hHQ_nbfec->HQ_FEC_seed ) < 0 )
304 : {
305 0 : t_audio_q_fx[i] = L_negate( hHQ_nbfec->old_coeffs_fx[i] );
306 0 : move32();
307 : }
308 : ELSE
309 : {
310 0 : t_audio_q_fx[i] = hHQ_nbfec->old_coeffs_fx[i];
311 0 : move32();
312 : }
313 : }
314 : }
315 : }
316 : }
317 : ELSE /* st_fx->nbLostCmpt > 1 */
318 : {
319 0 : test();
320 0 : IF( LT_16( energy_diff_fx, 1024 ) && is_transient == 0 )
321 : {
322 0 : num_pgf = 4;
323 0 : move16();
324 : }
325 : ELSE
326 : {
327 0 : num_pgf = 2;
328 0 : move16();
329 : }
330 :
331 0 : Num_sb_bwe = num_Sb;
332 0 : move16();
333 0 : IF( EQ_16( st_fx->nbLostCmpt, 2 ) )
334 : {
335 :
336 0 : FOR( i = 0; i < Num_sb_bwe; i++ )
337 : {
338 0 : norm_values_fx = &ynrm_values_fx[i][0]; /*Q12*/
339 0 : r_p_fx = &r_p_values_fx[i][0]; /*Q5*/
340 0 : Regression_Anal_fx( norm_values_fx, r_p_fx, num_pgf );
341 : }
342 : }
343 :
344 : /* Fade-out Norm by the result of Regression */
345 0 : IF( GE_16( st_fx->nbLostCmpt, mute_start ) )
346 : {
347 : /* Scaling */
348 0 : FOR( i = 0; i < output_frame; i++ )
349 : {
350 0 : hHQ_nbfec->old_coeffs_fx[i] = Mult_32_16( hHQ_nbfec->old_coeffs_fx[i], 23170 );
351 0 : move32();
352 : }
353 : }
354 :
355 0 : k = 0;
356 0 : move16();
357 0 : FOR( i = 0; i < Num_sb_bwe; i++ )
358 : {
359 0 : norm_values_fx = &ynrm_values_fx[i][0];
360 0 : r_p_fx = &r_p_values_fx[i][0];
361 :
362 : /* Predict the average energy of each sub-band using Regression */
363 : /* Linear Regression */
364 0 : IF( r_p_fx[1] > 0 )
365 : {
366 0 : r_p_fx[1] = L_deposit_l( 0 );
367 0 : move32();
368 0 : norm_p_fx[i] = L_shr( norm_values_fx[0], 7 ); /*5*/
369 0 : move32();
370 : }
371 : ELSE
372 : {
373 0 : norm_p_fx[i] = L_add( r_p_fx[0], L_mult0( extract_l( r_p_fx[1] ), sub( add( st_fx->nbLostCmpt, num_pgf ), 1 ) ) );
374 0 : move32();
375 : }
376 :
377 0 : test();
378 0 : IF( norm_values_fx[0] != 0 && norm_p_fx[i] > 0 ) /* Avoid negative value of the predicted energy */
379 : {
380 0 : exp1 = sub( norm_l( norm_p_fx[i] ), 1 );
381 0 : exp2 = norm_l( norm_values_fx[0] );
382 0 : tmp_fx = div_s( extract_h( L_shl( norm_p_fx[i], exp1 ) ),
383 0 : extract_h( L_shl( norm_values_fx[0], exp2 ) ) ); /*15 + (5 + exp1 - 16) - (12 + exp2 - 16)*/
384 0 : tmp_fx = shl_sat( tmp_fx, add( 6, sub( exp2, exp1 ) ) ); /*14*/
385 0 : if ( GT_16( tmp_fx, 16384 ) )
386 : {
387 0 : tmp_fx = 16384;
388 0 : move16();
389 : }
390 :
391 0 : FOR( j = 0; j < Num_bands_p[i]; j++ )
392 : {
393 : #ifdef ISSUE_1866_replace_overflow_libdec
394 0 : hHQ_nbfec->Norm_gain_fx[k] = shl_sat( tmp_fx, 1 );
395 : #else
396 : hHQ_nbfec->Norm_gain_fx[k] = shl_o( tmp_fx, 1, &Overflow );
397 : #endif
398 0 : move16();
399 0 : k = add( k, 1 );
400 : }
401 : }
402 : ELSE
403 : {
404 : /* Scale down the last gain with the fixed gain(-3dB) */
405 0 : FOR( j = 0; j < Num_bands_p[i]; j++ )
406 : {
407 0 : hHQ_nbfec->Norm_gain_fx[k] = mult_r( hHQ_nbfec->Norm_gain_fx[k], 23170 );
408 0 : move16();
409 0 : k = add( k, 1 );
410 : }
411 : }
412 : }
413 :
414 : /* Scaling for core band */
415 0 : FEC_scaling_fx( hHQ_nbfec->old_coeffs_fx, t_audio_q_fx, hHQ_nbfec->Norm_gain_fx, &hHQ_nbfec->HQ_FEC_seed, nb_sfm, sfm_start, sfm_end );
416 : }
417 :
418 :
419 0 : return;
420 : }
421 :
422 7432 : void ivas_HQ_FEC_Mem_update_fx(
423 : Decoder_State *st_fx, /* i/o: decoder state structure */
424 : Word32 *t_audio_q_fx, /*Q12*/
425 : Word32 *normq_fx, /*Q14*/
426 : Word16 *ynrm,
427 : Word16 *Num_bands_p,
428 : Word16 is_transient,
429 : Word16 hqswb_clas,
430 : Word16 c_switching_flag,
431 : Word16 nb_sfm,
432 : Word16 num_Sb,
433 : Word16 *mean_en_high_fx, /*Q5*/
434 : Word16 hq_core_type, /* i : normal or low-rate MDCT(HQ) core */
435 : Word16 output_frame )
436 : {
437 : Word16 Min_ind;
438 : Word32 Min_value;
439 : Word16 Max_ind;
440 : Word16 stat_mode_curr;
441 :
442 : Word16 i, j, k;
443 : Word16 offset;
444 : Word16 exp, exp1, exp2, tmp_fx;
445 : Word32 *norm_values_fx; // Q12
446 7432 : Word32 L_tmp, tmp_energy_fx = 0 /*Q8*/, Max_coeff_fx /*Q12*/;
447 : Word32 en_high_fx[MAX_SB_NB]; // Q12
448 : HQ_NBFEC_HANDLE hHQ_nbfec;
449 : HQ_DEC_HANDLE hHQ_core;
450 7432 : hHQ_nbfec = st_fx->hHQ_nbfec;
451 7432 : hHQ_core = st_fx->hHQ_core;
452 : #ifndef ISSUE_1866_replace_overflow_libdec
453 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
454 : Flag Overflow = 0;
455 : move32();
456 : #endif
457 : #endif
458 7432 : move32(); // for tmp_energy_fx
459 7432 : IF( EQ_16( output_frame, L_FRAME8k ) )
460 : {
461 :
462 0 : IF( is_transient )
463 : {
464 0 : set16_fx( hHQ_nbfec->prev_sign_switch_2, 0, HQ_FEC_SIGN_SFM );
465 0 : set16_fx( hHQ_nbfec->prev_sign_switch, 0, HQ_FEC_SIGN_SFM );
466 : }
467 : ELSE
468 : {
469 0 : FOR( j = 0; j < HQ_FEC_SIGN_SFM; j++ )
470 : {
471 0 : hHQ_nbfec->prev_sign_switch[j] = hHQ_nbfec->prev_sign_switch_2[j];
472 0 : move16();
473 0 : hHQ_nbfec->prev_sign_switch_2[j] = 0;
474 0 : move16();
475 :
476 0 : FOR( i = 0; i < HQ_FEC_BAND_SIZE; i++ )
477 : {
478 0 : test();
479 0 : test();
480 0 : test();
481 0 : IF( ( hHQ_nbfec->old_coeffs_fx[i + j * HQ_FEC_BAND_SIZE] > 0 && t_audio_q_fx[i + j * HQ_FEC_BAND_SIZE] < 0 ) || ( hHQ_nbfec->old_coeffs_fx[i + j * HQ_FEC_BAND_SIZE] < 0 && t_audio_q_fx[i + j * HQ_FEC_BAND_SIZE] > 0 ) )
482 : {
483 0 : hHQ_nbfec->prev_sign_switch[j] = add( hHQ_nbfec->prev_sign_switch[j], 1 );
484 0 : move16();
485 0 : hHQ_nbfec->prev_sign_switch_2[j] = add( hHQ_nbfec->prev_sign_switch_2[j], 1 );
486 0 : move16();
487 : }
488 : }
489 : }
490 : }
491 : /* if LR MDCT core is used, recalculate norms from decoded MDCT spectrum (using code from hq_hr_enc_fx()) */
492 0 : test();
493 0 : IF( ( EQ_16( hqswb_clas, HQ_HVQ ) ) || ( EQ_16( hq_core_type, LOW_RATE_HQ_CORE ) ) )
494 : {
495 : /* First group */
496 0 : logqnorm_fx( t_audio_q_fx, 12, ynrm, 32, WID_G1, (const Word16) EQ_16( hqswb_clas, HQ_HVQ ) );
497 0 : j = ynrm[0];
498 0 : move16();
499 0 : offset = WID_G1;
500 0 : move16();
501 :
502 0 : FOR( i = 1; i < SFM_G1; i++ )
503 : {
504 0 : logqnorm_fx( &t_audio_q_fx[offset], 12, &ynrm[i], 40, WID_G1, (const Word16) EQ_16( hqswb_clas, HQ_HVQ ) );
505 0 : offset = add( offset, WID_G1 );
506 : }
507 :
508 : /* Second group */
509 0 : FOR( i = SFM_G1; i < SFM_G1 + 2; i++ )
510 : {
511 0 : logqnorm_fx( &t_audio_q_fx[offset], 12, &ynrm[i], 40, WID_G2, (const Word16) EQ_16( hqswb_clas, HQ_HVQ ) );
512 0 : offset = add( offset, WID_G2 );
513 : }
514 : }
515 :
516 : /* Memory update for the LGF log2 Norm */
517 0 : FOR( i = 0; i < nb_sfm; i++ )
518 : {
519 0 : normq_fx[i] = dicn_fx[ynrm[i]];
520 0 : move32();
521 : }
522 0 : k = 0;
523 0 : move16();
524 0 : FOR( i = 0; i < num_Sb; i++ )
525 : {
526 0 : norm_values_fx = &hHQ_nbfec->ynrm_values_fx[i][0];
527 0 : Copy32( norm_values_fx, &norm_values_fx[1], MAX_PGF - 1 );
528 :
529 0 : L_tmp = L_deposit_l( 0 );
530 0 : FOR( j = 0; j < Num_bands_p[i]; j++ )
531 : {
532 0 : L_tmp = L_add( L_tmp, L_shr( normq_fx[k], 3 ) ); /*11*/
533 0 : k = add( k, 1 );
534 : }
535 : #ifdef ISSUE_1866_replace_overflow_libdec
536 0 : tmp_fx = shl_sat( inv_tbl_fx[Num_bands_p[i]], 1 ); /*16*/
537 : #else
538 : tmp_fx = shl_o( inv_tbl_fx[Num_bands_p[i]], 1, &Overflow ); /*16*/
539 : #endif
540 0 : norm_values_fx[0] = Mult_32_16( L_tmp, tmp_fx ); /*11 + 16 - 15*/
541 0 : move32();
542 0 : tmp_energy_fx = L_add( tmp_energy_fx, L_shr( L_tmp, 3 ) ); /*8*/
543 : }
544 0 : test();
545 0 : test();
546 0 : IF( ( c_switching_flag ) || ( ( st_fx->last_core == ACELP_CORE ) && ( EQ_16( st_fx->core, HQ_CORE ) ) ) )
547 : {
548 0 : FOR( i = 0; i < MAX_SB_NB; i++ )
549 : {
550 0 : FOR( j = 1; j < MAX_PGF; j++ )
551 : {
552 0 : hHQ_nbfec->ynrm_values_fx[i][j] = hHQ_nbfec->ynrm_values_fx[i][0];
553 0 : move32();
554 : }
555 : }
556 : }
557 0 : set16_fx( hHQ_nbfec->Norm_gain_fx, 32767, SFM_N_NB ); /*15*/
558 : /* st->energy_MA_Curr[1]=Energy of the current frame */
559 0 : tmp_fx = inv_tbl_fx[nb_sfm];
560 0 : move16(); /*15*/
561 0 : L_tmp = Mult_32_16( tmp_energy_fx, tmp_fx ); /*8 + 15 - 15*/
562 :
563 0 : hHQ_nbfec->energy_MA_Curr_fx[1] = extract_h( L_shl( L_tmp, 16 - 8 ) );
564 0 : move16();
565 : /* Moving Average */
566 0 : hHQ_nbfec->energy_MA_Curr_fx[0] = s_max( 1, add( mult_r( 26214, hHQ_nbfec->energy_MA_Curr_fx[0] ), mult_r( 6554, hHQ_nbfec->energy_MA_Curr_fx[1] ) ) );
567 0 : move16();
568 :
569 : /*st->diff_energy = (float)fabs((st->energy_MA_Curr[1] - st->energy_MA_Curr[0])/st->energy_MA_Curr[0]); */
570 0 : hHQ_nbfec->diff_energy_fx = abs_s( sub( hHQ_nbfec->energy_MA_Curr_fx[1], hHQ_nbfec->energy_MA_Curr_fx[0] ) );
571 0 : move16();
572 0 : exp1 = sub( norm_l( hHQ_nbfec->diff_energy_fx ), 1 );
573 0 : exp2 = norm_l( hHQ_nbfec->energy_MA_Curr_fx[0] );
574 0 : hHQ_nbfec->diff_energy_fx = div_s( extract_h( L_shl( hHQ_nbfec->diff_energy_fx, exp1 ) ), extract_h( L_shl( hHQ_nbfec->energy_MA_Curr_fx[0], exp2 ) ) );
575 0 : move16();
576 0 : exp = add( 15, sub( exp1, exp2 ) );
577 0 : hHQ_nbfec->diff_energy_fx = shl( hHQ_nbfec->diff_energy_fx, sub( 11, exp ) ); /*11*/
578 0 : move16();
579 :
580 : /* Classify the stationary mode : 12% */
581 0 : IF( LT_16( hHQ_nbfec->diff_energy_fx, ED_THRES_12P_fx ) )
582 : {
583 0 : stat_mode_curr = 1;
584 0 : move16();
585 : }
586 : ELSE
587 : {
588 0 : stat_mode_curr = 0;
589 0 : move16();
590 : }
591 :
592 : /* Apply Hysteresis to prevent frequent mode changing */
593 0 : if ( EQ_16( hHQ_nbfec->stat_mode_old, stat_mode_curr ) )
594 : {
595 0 : hHQ_nbfec->stat_mode_out = stat_mode_curr;
596 0 : move16();
597 : }
598 :
599 0 : hHQ_nbfec->stat_mode_old = stat_mode_curr;
600 0 : move16();
601 :
602 : /* Find max. band index (Minimum value means maximum energy) */
603 0 : Min_ind = 0;
604 0 : move16();
605 0 : Min_value = L_deposit_l( 100 );
606 0 : FOR( i = 0; i < num_Sb; i++ )
607 : {
608 0 : IF( GT_32( Min_value, ynrm[i] ) )
609 : {
610 0 : Min_value = ynrm[i];
611 0 : move16();
612 0 : Min_ind = i;
613 0 : move16();
614 : }
615 : }
616 :
617 : /* Find max. coeff in band 0 */
618 0 : Max_ind = 0;
619 0 : move16();
620 0 : IF( Min_ind == 0 )
621 : {
622 0 : Max_coeff_fx = L_deposit_l( 0 );
623 0 : FOR( i = 0; i < 8; i++ )
624 : {
625 0 : L_tmp = L_abs( t_audio_q_fx[i] ); // Q12
626 0 : IF( LT_32( Max_coeff_fx, L_tmp ) )
627 : {
628 0 : Max_coeff_fx = L_add( L_tmp, 0 );
629 0 : Max_ind = i;
630 0 : move16();
631 : }
632 : }
633 : }
634 :
635 : /* Find energy difference from band 16 */
636 0 : k = 1;
637 0 : move16();
638 :
639 0 : FOR( i = k; i < num_Sb; i++ )
640 : {
641 0 : en_high_fx[i] = L_deposit_l( 0 );
642 0 : FOR( j = 0; j < 2; j++ )
643 : {
644 : /*en_high[i] += 0.5f*st->ynrm_values[i][j+1];*/
645 0 : en_high_fx[i] = L_add( en_high_fx[i], L_shr( hHQ_nbfec->ynrm_values_fx[i][j + 1], 1 ) ); /*Q12*/
646 0 : move32();
647 : }
648 : }
649 :
650 0 : *mean_en_high_fx = 0;
651 0 : move16();
652 0 : FOR( i = k; i < num_Sb; i++ )
653 : {
654 : /* *mean_en_high += (float)(en_high[i]/st->ynrm_values[i][0]);*/
655 0 : exp1 = sub( norm_l( en_high_fx[i] ), 1 );
656 0 : exp2 = norm_l( hHQ_nbfec->ynrm_values_fx[i][0] );
657 0 : tmp_fx = div_s( extract_h( L_shl( en_high_fx[i], exp1 ) ), extract_h( L_shl( hHQ_nbfec->ynrm_values_fx[i][0], exp2 ) ) );
658 0 : exp = add( 15, sub( exp1, exp2 ) );
659 : #ifdef ISSUE_1866_replace_overflow_libdec
660 0 : *mean_en_high_fx = add_sat( *mean_en_high_fx, shr_sat( tmp_fx, sub( exp, 5 ) ) );
661 : #else
662 : *mean_en_high_fx = add_o( *mean_en_high_fx, shr_sat( tmp_fx, sub( exp, 5 ) ), &Overflow );
663 : #endif
664 0 : move16();
665 : }
666 0 : *mean_en_high_fx = mult( *mean_en_high_fx, inv_tbl_fx[sub( num_Sb, k )] );
667 0 : move16();
668 :
669 0 : test();
670 0 : test();
671 0 : test();
672 0 : test();
673 0 : test();
674 0 : test();
675 0 : test();
676 0 : test();
677 0 : test();
678 0 : IF( ( LT_16( Min_ind, 5 ) ) && ( LT_16( abs_s( sub( Min_ind, hHQ_nbfec->old_Min_ind ) ), 2 ) ) && ( LT_16( hHQ_nbfec->diff_energy_fx, ED_THRES_90P_fx ) ) && ( !st_fx->bfi ) && ( !st_fx->prev_bfi ) && ( !st_fx->prev_old_bfi ) && ( !is_transient ) && ( !hHQ_core->old_is_transient[1] ) && ( EQ_16( hHQ_nbfec->prev_last_core, HQ_CORE ) ) && ( EQ_16( st_fx->last_core, HQ_CORE ) ) )
679 : {
680 0 : hHQ_nbfec->phase_mat_flag = 1;
681 0 : move16();
682 0 : test();
683 0 : if ( ( Min_ind == 0 ) && ( LT_16( Max_ind, 3 ) ) )
684 : {
685 0 : hHQ_nbfec->phase_mat_flag = 0;
686 0 : move16();
687 : }
688 : }
689 : ELSE
690 : {
691 0 : hHQ_nbfec->phase_mat_flag = 0;
692 0 : move16();
693 : }
694 :
695 0 : hHQ_nbfec->old_Min_ind = Min_ind;
696 0 : move16();
697 :
698 0 : FOR( i = 0; i < L_FRAME8k; i++ )
699 : {
700 0 : hHQ_nbfec->old_coeffs_fx[i] = t_audio_q_fx[i];
701 0 : move32();
702 : }
703 : }
704 :
705 7432 : hHQ_core->old_is_transient[2] = hHQ_core->old_is_transient[1];
706 7432 : move16();
707 7432 : hHQ_core->old_is_transient[1] = hHQ_core->old_is_transient[0];
708 7432 : move16();
709 7432 : hHQ_core->old_is_transient[0] = is_transient;
710 7432 : move16();
711 :
712 7432 : return;
713 : }
714 :
715 440 : void HQ_FEC_Mem_update_fx(
716 : Decoder_State *st_fx, /* i/o: decoder state structure */
717 : Word32 *t_audio_q_fx, /*Q12*/
718 : Word32 *normq_fx, /*Q14*/
719 : Word16 *ynrm,
720 : Word16 *Num_bands_p,
721 : Word16 is_transient,
722 : Word16 hqswb_clas,
723 : Word16 c_switching_flag,
724 : Word16 nb_sfm,
725 : Word16 num_Sb,
726 : Word16 *mean_en_high_fx, /*Q5*/
727 : Word16 hq_core_type, /* i : normal or low-rate MDCT(HQ) core */
728 : Word16 output_frame )
729 : {
730 : Word16 Min_ind;
731 : Word32 Min_value;
732 : Word16 Max_ind;
733 : Word16 stat_mode_curr;
734 :
735 : Word16 i, j, k;
736 : Word16 offset;
737 : Word16 exp, exp1, exp2, tmp_fx;
738 : Word32 *norm_values_fx; // Q12
739 440 : Word32 L_tmp, tmp_energy_fx = 0 /*Q8*/, Max_coeff_fx /*Q12*/;
740 : Word32 en_high_fx[MAX_SB_NB]; // Q12
741 : HQ_NBFEC_HANDLE hHQ_nbfec;
742 : HQ_DEC_HANDLE hHQ_core;
743 440 : hHQ_nbfec = st_fx->hHQ_nbfec;
744 440 : hHQ_core = st_fx->hHQ_core;
745 : #ifndef ISSUE_1866_replace_overflow_libdec
746 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
747 : Flag Overflow = 0;
748 : move32();
749 : #endif
750 : #endif
751 440 : move32(); // tmp_energy_fx
752 :
753 440 : IF( EQ_16( output_frame, L_FRAME8k ) )
754 : {
755 :
756 0 : IF( is_transient )
757 : {
758 0 : set16_fx( hHQ_nbfec->prev_sign_switch_2, 0, HQ_FEC_SIGN_SFM );
759 0 : set16_fx( hHQ_nbfec->prev_sign_switch, 0, HQ_FEC_SIGN_SFM );
760 : }
761 : ELSE
762 : {
763 0 : FOR( j = 0; j < HQ_FEC_SIGN_SFM; j++ )
764 : {
765 0 : hHQ_nbfec->prev_sign_switch[j] = hHQ_nbfec->prev_sign_switch_2[j];
766 0 : move16();
767 0 : hHQ_nbfec->prev_sign_switch_2[j] = 0;
768 0 : move16();
769 :
770 0 : FOR( i = 0; i < HQ_FEC_BAND_SIZE; i++ )
771 : {
772 0 : test();
773 0 : test();
774 0 : test();
775 0 : IF( ( hHQ_nbfec->old_coeffs_fx[i + j * HQ_FEC_BAND_SIZE] > 0 && t_audio_q_fx[i + j * HQ_FEC_BAND_SIZE] < 0 ) || ( hHQ_nbfec->old_coeffs_fx[i + j * HQ_FEC_BAND_SIZE] < 0 && t_audio_q_fx[i + j * HQ_FEC_BAND_SIZE] > 0 ) )
776 : {
777 0 : hHQ_nbfec->prev_sign_switch[j] = add( hHQ_nbfec->prev_sign_switch[j], 1 );
778 0 : move16();
779 0 : hHQ_nbfec->prev_sign_switch_2[j] = add( hHQ_nbfec->prev_sign_switch_2[j], 1 );
780 0 : move16();
781 : }
782 : }
783 : }
784 : }
785 :
786 : /* if LR MDCT core is used, recalculate norms from decoded MDCT spectrum (using code from hq_hr_enc_fx()) */
787 0 : test();
788 0 : IF( ( EQ_16( hqswb_clas, HQ_HVQ ) ) || ( EQ_16( hq_core_type, LOW_RATE_HQ_CORE ) ) )
789 : {
790 : /* First group */
791 0 : logqnorm_fx( t_audio_q_fx, 12, ynrm, 32, WID_G1, (const Word16) EQ_16( hqswb_clas, HQ_HVQ ) );
792 0 : j = ynrm[0];
793 0 : move16();
794 0 : offset = WID_G1;
795 0 : move16();
796 :
797 0 : FOR( i = 1; i < SFM_G1; i++ )
798 : {
799 0 : logqnorm_fx( &t_audio_q_fx[offset], 12, &ynrm[i], 40, WID_G1, (const Word16) EQ_16( hqswb_clas, HQ_HVQ ) );
800 0 : offset = add( offset, WID_G1 );
801 : }
802 :
803 : /* Second group */
804 0 : FOR( i = SFM_G1; i < SFM_G1 + 2; i++ )
805 : {
806 0 : logqnorm_fx( &t_audio_q_fx[offset], 12, &ynrm[i], 40, WID_G2, (const Word16) EQ_16( hqswb_clas, HQ_HVQ ) );
807 0 : offset = add( offset, WID_G2 );
808 : }
809 : }
810 :
811 : /* Memory update for the LGF log2 Norm */
812 0 : FOR( i = 0; i < nb_sfm; i++ )
813 : {
814 0 : normq_fx[i] = dicn_fx[ynrm[i]];
815 0 : move32();
816 : }
817 0 : k = 0;
818 0 : move16();
819 0 : FOR( i = 0; i < num_Sb; i++ )
820 : {
821 0 : norm_values_fx = &hHQ_nbfec->ynrm_values_fx[i][0];
822 0 : Copy32( norm_values_fx, &norm_values_fx[1], MAX_PGF - 1 );
823 :
824 0 : L_tmp = L_deposit_l( 0 );
825 0 : FOR( j = 0; j < Num_bands_p[i]; j++ )
826 : {
827 0 : L_tmp = L_add( L_tmp, L_shr( normq_fx[k], 3 ) ); /*11*/
828 0 : k = add( k, 1 );
829 : }
830 : #ifdef ISSUE_1866_replace_overflow_libdec
831 0 : tmp_fx = shl_sat( inv_tbl_fx[Num_bands_p[i]], 1 ); /*16*/
832 : #else
833 : tmp_fx = shl_o( inv_tbl_fx[Num_bands_p[i]], 1, &Overflow ); /*16*/
834 : #endif
835 0 : norm_values_fx[0] = Mult_32_16( L_tmp, tmp_fx ); /*11 + 16 - 15*/
836 0 : move32();
837 0 : tmp_energy_fx = L_add( tmp_energy_fx, L_shr( L_tmp, 3 ) ); /*8*/
838 : }
839 0 : test();
840 0 : test();
841 0 : IF( ( c_switching_flag ) || ( ( st_fx->last_core == ACELP_CORE ) && ( EQ_16( st_fx->core, HQ_CORE ) ) ) )
842 : {
843 0 : FOR( i = 0; i < MAX_SB_NB; i++ )
844 : {
845 0 : FOR( j = 1; j < MAX_PGF; j++ )
846 : {
847 0 : hHQ_nbfec->ynrm_values_fx[i][j] = hHQ_nbfec->ynrm_values_fx[i][0];
848 0 : move32();
849 : }
850 : }
851 : }
852 0 : set16_fx( hHQ_nbfec->Norm_gain_fx, 32767, SFM_N_NB ); /*15*/
853 : /* st->energy_MA_Curr[1]=Energy of the current frame */
854 0 : tmp_fx = inv_tbl_fx[nb_sfm];
855 0 : move16(); /*15*/
856 0 : L_tmp = Mult_32_16( tmp_energy_fx, tmp_fx ); /*8 + 15 - 15*/
857 :
858 0 : hHQ_nbfec->energy_MA_Curr_fx[1] = extract_h( L_shl_sat( L_tmp, 16 - 8 ) );
859 0 : move16();
860 : /* Moving Average */
861 0 : hHQ_nbfec->energy_MA_Curr_fx[0] = s_max( 1, add( mult_r( 26214, hHQ_nbfec->energy_MA_Curr_fx[0] ), mult_r( 6554, hHQ_nbfec->energy_MA_Curr_fx[1] ) ) );
862 0 : move16();
863 :
864 : /*st->diff_energy = (float)fabs((st->energy_MA_Curr[1] - st->energy_MA_Curr[0])/st->energy_MA_Curr[0]); */
865 0 : hHQ_nbfec->diff_energy_fx = abs_s( sub( hHQ_nbfec->energy_MA_Curr_fx[1], hHQ_nbfec->energy_MA_Curr_fx[0] ) );
866 0 : move16();
867 0 : exp1 = sub( norm_l( hHQ_nbfec->diff_energy_fx ), 1 );
868 0 : exp2 = norm_l( hHQ_nbfec->energy_MA_Curr_fx[0] );
869 0 : hHQ_nbfec->diff_energy_fx = div_s( extract_h( L_shl( hHQ_nbfec->diff_energy_fx, exp1 ) ), extract_h( L_shl( hHQ_nbfec->energy_MA_Curr_fx[0], exp2 ) ) );
870 0 : move16();
871 0 : exp = add( 15, sub( exp1, exp2 ) );
872 0 : hHQ_nbfec->diff_energy_fx = shl( hHQ_nbfec->diff_energy_fx, sub( 11, exp ) ); /*11*/
873 0 : move16();
874 :
875 : /* Classify the stationary mode : 12% */
876 0 : IF( LT_16( hHQ_nbfec->diff_energy_fx, ED_THRES_12P_fx ) )
877 : {
878 0 : stat_mode_curr = 1;
879 0 : move16();
880 : }
881 : ELSE
882 : {
883 0 : stat_mode_curr = 0;
884 0 : move16();
885 : }
886 :
887 : /* Apply Hysteresis to prevent frequent mode changing */
888 0 : if ( EQ_16( hHQ_nbfec->stat_mode_old, stat_mode_curr ) )
889 : {
890 0 : hHQ_nbfec->stat_mode_out = stat_mode_curr;
891 0 : move16();
892 : }
893 :
894 0 : hHQ_nbfec->stat_mode_old = stat_mode_curr;
895 0 : move16();
896 :
897 : /* Find max. band index (Minimum value means maximum energy) */
898 0 : Min_ind = 0;
899 0 : move16();
900 0 : Min_value = L_deposit_l( 100 );
901 0 : FOR( i = 0; i < num_Sb; i++ )
902 : {
903 0 : IF( GT_32( Min_value, ynrm[i] ) )
904 : {
905 0 : Min_value = ynrm[i];
906 0 : move16();
907 0 : Min_ind = i;
908 0 : move16();
909 : }
910 : }
911 :
912 : /* Find max. coeff in band 0 */
913 0 : Max_ind = 0;
914 0 : move16();
915 0 : IF( Min_ind == 0 )
916 : {
917 0 : Max_coeff_fx = L_deposit_l( 0 );
918 0 : FOR( i = 0; i < 8; i++ )
919 : {
920 0 : L_tmp = L_abs( t_audio_q_fx[i] );
921 0 : IF( LT_32( Max_coeff_fx, L_tmp ) )
922 : {
923 0 : Max_coeff_fx = L_add( L_tmp, 0 );
924 0 : Max_ind = i;
925 0 : move16();
926 : }
927 : }
928 : }
929 :
930 : /* Find energy difference from band 16 */
931 0 : k = 1;
932 0 : move16();
933 :
934 0 : FOR( i = k; i < num_Sb; i++ )
935 : {
936 0 : en_high_fx[i] = L_deposit_l( 0 );
937 0 : move16();
938 0 : FOR( j = 0; j < 2; j++ )
939 : {
940 : /*en_high[i] += 0.5f*st->ynrm_values[i][j+1];*/
941 0 : en_high_fx[i] = L_add( en_high_fx[i], L_shr( hHQ_nbfec->ynrm_values_fx[i][j + 1], 1 ) ); /*Q12*/
942 0 : move32();
943 : }
944 : }
945 :
946 0 : *mean_en_high_fx = 0;
947 0 : move16();
948 0 : FOR( i = k; i < num_Sb; i++ )
949 : {
950 : /* *mean_en_high += (float)(en_high[i]/st->ynrm_values[i][0]);*/
951 0 : exp1 = sub( norm_l( en_high_fx[i] ), 1 );
952 0 : exp2 = norm_l( hHQ_nbfec->ynrm_values_fx[i][0] );
953 0 : tmp_fx = div_s( extract_h( L_shl( en_high_fx[i], exp1 ) ), extract_h( L_shl( hHQ_nbfec->ynrm_values_fx[i][0], exp2 ) ) );
954 0 : exp = add( 15, sub( exp1, exp2 ) );
955 : #ifdef ISSUE_1866_replace_overflow_libdec
956 0 : *mean_en_high_fx = add_sat( *mean_en_high_fx, shr_sat( tmp_fx, sub( exp, 5 ) ) );
957 : #else
958 : *mean_en_high_fx = add_o( *mean_en_high_fx, shr_sat( tmp_fx, sub( exp, 5 ) ), &Overflow );
959 : #endif
960 0 : move16();
961 : }
962 0 : *mean_en_high_fx = mult( *mean_en_high_fx, inv_tbl_fx[sub( num_Sb, k )] );
963 0 : move16();
964 :
965 0 : test();
966 0 : test();
967 0 : test();
968 0 : test();
969 0 : test();
970 0 : test();
971 0 : test();
972 0 : test();
973 0 : test();
974 0 : IF( ( LT_16( Min_ind, 5 ) ) && ( LT_16( abs_s( sub( Min_ind, hHQ_nbfec->old_Min_ind ) ), 2 ) ) && ( LT_16( hHQ_nbfec->diff_energy_fx, ED_THRES_90P_fx ) ) && ( !st_fx->bfi ) && ( !st_fx->prev_bfi ) && ( !st_fx->prev_old_bfi ) && ( !is_transient ) && ( !hHQ_core->old_is_transient[1] ) && EQ_16( hHQ_nbfec->prev_last_core, HQ_CORE ) && EQ_16( st_fx->last_core, HQ_CORE ) )
975 : {
976 0 : hHQ_nbfec->phase_mat_flag = 1;
977 0 : move16();
978 0 : test();
979 0 : if ( Min_ind == 0 && ( LT_16( Max_ind, 3 ) ) )
980 : {
981 0 : hHQ_nbfec->phase_mat_flag = 0;
982 0 : move16();
983 : }
984 : }
985 : ELSE
986 : {
987 0 : hHQ_nbfec->phase_mat_flag = 0;
988 0 : move16();
989 : }
990 :
991 0 : hHQ_nbfec->old_Min_ind = Min_ind;
992 0 : move16();
993 :
994 :
995 0 : FOR( i = 0; i < L_FRAME8k; i++ )
996 : {
997 0 : hHQ_nbfec->old_coeffs_fx[i] = t_audio_q_fx[i];
998 0 : move32();
999 : }
1000 : }
1001 :
1002 440 : hHQ_core->old_is_transient[2] = hHQ_core->old_is_transient[1];
1003 440 : move16();
1004 440 : hHQ_core->old_is_transient[1] = hHQ_core->old_is_transient[0];
1005 440 : move16();
1006 440 : hHQ_core->old_is_transient[0] = is_transient;
1007 440 : move16();
1008 :
1009 440 : return;
1010 : }
1011 :
1012 0 : static Word16 find_best_delay_fx(
1013 : Word16 *mu_o_fx, // Qx
1014 : Word16 *in_fx, // Qx
1015 : Word16 mind1,
1016 : Word16 maxd1,
1017 : Word16 lin,
1018 : Word16 delta,
1019 : Word16 *false_flag )
1020 : {
1021 : Word16 i, d1, k;
1022 0 : Word16 d1m = 0;
1023 :
1024 : Word16 tmp, exp1, exp2;
1025 : Word32 L_tmp1, L_tmp2;
1026 :
1027 : Word32 min_sq_cross_fx, min_corr_fx;
1028 : Word32 accA_fx, accB_fx;
1029 : Word32 Rxy_fx[MAXDELAY_FEC], Ryy_fx[MAXDELAY_FEC];
1030 : #ifndef ISSUE_1866_replace_overflow_libdec
1031 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1032 : Flag Overflow = 0;
1033 : move32();
1034 : #endif
1035 : #endif
1036 0 : move16(); // d1m
1037 :
1038 :
1039 0 : d1 = mind1;
1040 0 : move16();
1041 0 : FOR( k = 0; k < idiv1616( sub( maxd1, mind1 ), delta ); k++ )
1042 : {
1043 0 : accA_fx = L_deposit_l( 0 );
1044 0 : accB_fx = L_deposit_l( 0 );
1045 0 : FOR( i = 0; i < lin; i += delta )
1046 : {
1047 0 : accA_fx = L_add_sat( accA_fx, L_shr( L_mult_sat( mu_o_fx[d1 + i], mu_o_fx[d1 + i] ), 2 ) );
1048 0 : accB_fx = L_add_sat( accB_fx, L_shr( L_mult_sat( mu_o_fx[d1 + i], in_fx[i] ), 2 ) );
1049 : }
1050 :
1051 0 : Rxy_fx[k] = accB_fx;
1052 0 : move32();
1053 0 : Ryy_fx[k] = accA_fx;
1054 0 : move32();
1055 :
1056 0 : d1 = add( d1, delta );
1057 : }
1058 :
1059 : /* Obtain the best delay values */
1060 0 : min_sq_cross_fx = 0x80000000;
1061 0 : move32();
1062 0 : min_corr_fx = L_deposit_l( 0 );
1063 0 : exp2 = 0;
1064 0 : move16();
1065 0 : FOR( d1 = 0; d1 < ( maxd1 - mind1 ) / delta; d1++ )
1066 : {
1067 0 : IF( GT_32( L_abs( Rxy_fx[d1] ), L_abs( Ryy_fx[d1] ) ) )
1068 0 : exp1 = norm_l( Rxy_fx[d1] );
1069 : ELSE
1070 0 : exp1 = norm_l( Ryy_fx[d1] );
1071 :
1072 0 : L_tmp1 = Mult_32_32( L_shl( Rxy_fx[d1], exp1 ), L_shl( min_corr_fx, exp2 ) );
1073 0 : L_tmp2 = Mult_32_32( L_shl( Ryy_fx[d1], exp1 ), L_shl( min_sq_cross_fx, exp2 ) );
1074 0 : IF( GE_32( L_tmp1, L_tmp2 ) )
1075 : {
1076 0 : d1m = d1;
1077 0 : move16();
1078 0 : min_corr_fx = L_add( Ryy_fx[d1], 0 ); /*12 + 12 - 31 */
1079 0 : min_sq_cross_fx = L_add( Rxy_fx[d1], 0 ); /*12 + 12 - 31 */
1080 0 : exp2 = exp1;
1081 0 : move16();
1082 : }
1083 : }
1084 :
1085 0 : test();
1086 0 : IF( ( min_sq_cross_fx <= 0 ) || ( min_corr_fx <= 0 ) )
1087 : {
1088 0 : tmp = 0;
1089 0 : move16(); /* If cross correlation is negative, the division per the energy will always be negative --> tmp will be < 8192, no need to do the division per say */
1090 : }
1091 : ELSE
1092 : {
1093 : /*d1m *= delta; */
1094 0 : d1m = extract_l( L_mult0( d1m, delta ) );
1095 :
1096 0 : exp1 = sub( norm_l( min_sq_cross_fx ), 1 );
1097 0 : exp2 = norm_l( min_corr_fx );
1098 0 : L_tmp1 = L_shl( min_sq_cross_fx, exp1 );
1099 0 : L_tmp2 = L_shl( min_corr_fx, exp2 );
1100 0 : tmp = div_s( extract_h( L_tmp1 ), extract_h( L_tmp2 ) ); /*15 + exp1 - exp2 */
1101 : #ifdef ISSUE_1866_replace_overflow_libdec
1102 0 : tmp = shl_sat( tmp, sub( exp2, add( exp1, 1 ) ) ); /*14 */
1103 : #else
1104 : tmp = shl_o( tmp, sub( exp2, add( exp1, 1 ) ), &Overflow ); /*14 */
1105 : #endif
1106 : }
1107 :
1108 0 : *false_flag = 0;
1109 0 : move16();
1110 0 : test();
1111 0 : if ( LT_16( tmp, 8192 ) || GT_16( tmp, 24576 ) )
1112 : {
1113 0 : *false_flag = 1;
1114 0 : move16();
1115 : }
1116 :
1117 0 : return d1m;
1118 : }
1119 :
1120 0 : static Word16 Search_Max_Corr_fx(
1121 : Word16 *mu_o_fx,
1122 : /* i : *old_auOut_2fr, */ // Qx
1123 : Word16 old_Min_ind, /* i : *old_auOut_2fr, */
1124 : const Word16 L /* i : L/2 */
1125 : )
1126 : {
1127 : Word16 pos;
1128 : Word16 pos2, delta2;
1129 : Word16 lin, delta;
1130 : Word16 mind1, maxd1;
1131 : Word16 false_flag;
1132 : Word16 min_d1, max_d1;
1133 : Word16 tmp1, tmp2;
1134 : Word16 *in_fx; // Qx
1135 :
1136 0 : IF( old_Min_ind == 0 )
1137 : {
1138 : /*lin = 8*L/20; */ /* Basic size of the block for phase matching */
1139 0 : lin = mult_r( L, 13107 ); /* Basic size of the block for phase matching */
1140 : /*min_dist = -1e35f; */
1141 0 : mind1 = 0;
1142 0 : move16(); /* min value of delay d1 to search for */
1143 : /*maxd1 = 12*L/20; */ /* max value of delay d1 to search for */
1144 0 : maxd1 = mult_r( L, 19661 ); /* max value of delay d1 to search for */
1145 :
1146 : /*in = mu_o + 2*L -lin; */
1147 0 : in_fx = mu_o_fx + sub( shl( L, 1 ), lin );
1148 :
1149 : /* generate correlation */
1150 0 : delta = 2;
1151 0 : move16();
1152 0 : delta2 = 1;
1153 0 : move16();
1154 :
1155 0 : pos = find_best_delay_fx( mu_o_fx, in_fx, mind1, maxd1, lin, delta, &false_flag );
1156 :
1157 0 : if ( false_flag )
1158 : {
1159 0 : return 0;
1160 : }
1161 :
1162 0 : tmp1 = add( mind1, sub( add( pos, 1 ), delta ) );
1163 0 : tmp2 = add( mind1, add( pos, delta ) );
1164 0 : min_d1 = s_max( mind1, tmp1 );
1165 0 : max_d1 = s_min( maxd1, tmp2 );
1166 0 : pos2 = find_best_delay_fx( mu_o_fx, in_fx, min_d1, max_d1, lin, delta2, &false_flag );
1167 0 : IF( GT_16( mind1, tmp1 ) )
1168 : {
1169 0 : pos = pos2;
1170 0 : move16();
1171 : }
1172 : ELSE
1173 : {
1174 0 : pos = add( pos, add( sub( pos2, delta ), 1 ) );
1175 : }
1176 :
1177 0 : pos = add( pos, add( lin, mind1 ) );
1178 : }
1179 : ELSE
1180 : {
1181 0 : lin = mult_r( L, 9830 );
1182 0 : mind1 = mult_r( L, 14746 ); /* min value of delay d1 to search for */
1183 0 : maxd1 = mult_r( L, 22938 ); /* max value of delay d1 to search for */
1184 0 : in_fx = mu_o_fx + sub( shl( L, 1 ), lin );
1185 :
1186 : /* generate correlation */
1187 0 : delta = 2;
1188 0 : move16();
1189 0 : delta2 = 1;
1190 0 : move16();
1191 :
1192 0 : pos = find_best_delay_fx( mu_o_fx, in_fx, mind1, maxd1, lin, delta, &false_flag );
1193 :
1194 0 : if ( false_flag )
1195 : {
1196 0 : return 0;
1197 : }
1198 :
1199 0 : tmp1 = add( mind1, add( sub( pos, delta ), 1 ) );
1200 0 : tmp2 = add( mind1, add( pos, delta ) );
1201 0 : min_d1 = s_max( mind1, tmp1 );
1202 0 : max_d1 = s_min( maxd1, tmp2 );
1203 0 : pos2 = find_best_delay_fx( mu_o_fx, in_fx, min_d1, max_d1, lin, delta2, &false_flag );
1204 :
1205 0 : IF( GT_16( mind1, tmp1 ) )
1206 : {
1207 0 : pos = pos2;
1208 0 : move16();
1209 : }
1210 : ELSE
1211 : {
1212 0 : pos = add( pos, add( sub( pos2, delta ), 1 ) );
1213 : }
1214 0 : pos = add( pos, add( lin, mind1 ) );
1215 : }
1216 :
1217 0 : return pos;
1218 : }
1219 :
1220 0 : static Word16 FEC_phase_matching_fx(
1221 : HQ_NBFEC_HANDLE st_fx, /* i : Decoder State */
1222 : Word32 *ImdctOut_fx, /* i : input, Q6 */
1223 : Word16 *auOut_fx, /* o : output audio, Q0 */
1224 : Word16 *OldauOut_fx, // Q0
1225 : Word16 OldauOut_pha_fx[2][N_LEAD_NB] ) // Qx
1226 : {
1227 : Word16 i;
1228 : Word16 pos, remain;
1229 : Word16 ol_size;
1230 : Word16 L_overlap, L;
1231 : Word16 ImdctOutWin_fx[2 * L_FRAME8k];
1232 : Word16 OldauOutnoWin_fx[L_FRAME8k];
1233 : Word16 OldauOut2_fx[L_FRAME8k];
1234 : Word16 win_NB_fx[L_FRAME8k + 25]; // Q15
1235 : Word16 exp1, exp2, tmp;
1236 : Word32 pow1_fx, pow22_fx;
1237 : Word16 SmoothingWin_NB3_fx[24]; // Q15
1238 :
1239 0 : L = L_FRAME8k;
1240 0 : move16();
1241 0 : ol_size = idiv1616( shl( L, 1 ), 20 );
1242 0 : move16();
1243 0 : L_overlap = idiv1616( imult1616( 3, L ), 20 );
1244 0 : move16();
1245 :
1246 0 : FOR( i = 0; i < L_overlap; i++ )
1247 : {
1248 0 : SmoothingWin_NB3_fx[i] = SmoothingWin_NB875_fx[i * 3];
1249 0 : move16();
1250 : }
1251 :
1252 0 : FOR( i = 0; i < L + 25; i++ )
1253 : {
1254 0 : win_NB_fx[i] = window_48kHz_fx[i * 6 + 3]; // Q15
1255 0 : move16();
1256 : }
1257 0 : set16_fx( ImdctOutWin_fx, 0, shl( L, 1 ) );
1258 :
1259 0 : pos = Search_Max_Corr_fx( st_fx->old_auOut_2fr_fx, st_fx->old_Min_ind, L );
1260 :
1261 0 : if ( pos == 0 )
1262 : {
1263 0 : return 1;
1264 : }
1265 :
1266 : /* Repetition */
1267 0 : remain = sub( add( L, N_Z_L_NB ), sub( shl( L, 1 ), pos ) );
1268 0 : Copy( &st_fx->old_auOut_2fr_fx[pos], &ImdctOutWin_fx[N_ZERO_NB], sub( shl( L, 1 ), pos ) );
1269 :
1270 : /* OldauOut without windowing */
1271 0 : FOR( i = N_ZERO_NB; i < L / 2; i++ )
1272 : {
1273 0 : OldauOutnoWin_fx[i - N_ZERO_NB] = extract_l( L_shr( L_negate( st_fx->oldIMDCTout_fx[L / 2 - 1 - i] ), 6 ) ); // Q6 -> Q0
1274 0 : move16();
1275 : }
1276 0 : FOR( i = 0; i < L / 2; i++ )
1277 : {
1278 0 : OldauOutnoWin_fx[i + N_ZERO_O_NB] = extract_l( L_shr( L_negate( st_fx->oldIMDCTout_fx[i] ), 6 ) ); // Q6 -> Q0
1279 0 : move16();
1280 : }
1281 :
1282 0 : Copy( OldauOutnoWin_fx, &ImdctOutWin_fx[N_ZERO_NB + ( 2 * L ) - pos], remain );
1283 :
1284 0 : pow1_fx = L_deposit_l( 0 );
1285 0 : pow22_fx = L_deposit_l( 0 );
1286 0 : FOR( i = 0; i < L; i++ )
1287 : {
1288 0 : pow1_fx = L_add( pow1_fx, shr( abs_s( st_fx->old_auOut_2fr_fx[L + i] ), 1 ) );
1289 0 : pow22_fx = L_add( pow22_fx, shr( abs_s( ImdctOutWin_fx[N_ZERO_NB + i] ), 1 ) );
1290 : }
1291 0 : IF( pow22_fx != 0 )
1292 : {
1293 0 : exp1 = sub( norm_l( pow1_fx ), 1 );
1294 0 : exp2 = norm_l( pow22_fx );
1295 0 : tmp = div_s( extract_h( L_shl( pow1_fx, exp1 ) ), extract_h( L_shl( pow22_fx, exp2 ) ) ); /*15 + exp1 - exp2*/
1296 0 : tmp = shl( tmp, sub( sub( exp2, exp1 ), 1 ) ); /*14*/
1297 0 : FOR( i = N_ZERO_NB; i < L * 2; i++ )
1298 : {
1299 0 : ImdctOutWin_fx[i] = shl_sat( mult( ImdctOutWin_fx[i], tmp ), 1 );
1300 0 : move16();
1301 : }
1302 : }
1303 0 : Smoothing_vector_NB_fx( OldauOutnoWin_fx, &ImdctOutWin_fx[N_ZERO_NB], SmoothingWin_NB2_fx, auOut_fx, ol_size );
1304 :
1305 0 : FOR( i = 0; i < L / 2; i++ )
1306 : {
1307 : /*ImdctOutWin[3*L/2 + i] *= win_NB[L/2-i-1];*/
1308 0 : ImdctOutWin_fx[3 * L / 2 + i] = mult( ImdctOutWin_fx[3 * L / 2 + i], win_NB_fx[L / 2 - i - 1] );
1309 0 : move16();
1310 : }
1311 :
1312 0 : FOR( i = N_ZERO_NB; i < L / 2; i++ )
1313 : {
1314 : /*ImdctOutWin_fx[L + i] *= win_NB_fx[(L-1-i)];*/
1315 0 : ImdctOutWin_fx[L + i] = mult( ImdctOutWin_fx[L + i], win_NB_fx[( L - 1 - i )] );
1316 0 : move16();
1317 : }
1318 :
1319 0 : Copy( &ImdctOutWin_fx[N_Z_L_O_NB], &OldauOut_pha_fx[0][0], N_LEAD_NB );
1320 0 : Copy( &ImdctOutWin_fx[ol_size + N_ZERO_NB], &auOut_fx[ol_size], sub( N_Z_L_NB, ol_size ) );
1321 0 : Copy( &ImdctOutWin_fx[L], &auOut_fx[N_Z_L_NB], N_ZERO_NB );
1322 0 : Copy( &ImdctOutWin_fx[L], OldauOut_fx, L );
1323 :
1324 0 : FOR( i = 0; i < shr( L, 1 ); i++ )
1325 : {
1326 0 : OldauOut2_fx[i] = extract_l( L_shr( L_negate( ImdctOut_fx[L / 2 - 1 - i] ), 6 ) );
1327 0 : move16();
1328 0 : OldauOut2_fx[L / 2 + i] = extract_l( L_shr( L_negate( ImdctOut_fx[i] ), 6 ) );
1329 0 : move16();
1330 : }
1331 :
1332 0 : Smoothing_vector_NB_fx( &ImdctOutWin_fx[N_Z_L_O_NB], &OldauOut2_fx[N_ZERO_NB], SmoothingWin_NB3_fx, &OldauOut_pha_fx[1][0], L_overlap );
1333 :
1334 0 : FOR( i = L_overlap; i < N_LEAD_NB; i++ )
1335 : {
1336 0 : OldauOut_pha_fx[1][i] = OldauOut2_fx[i + N_ZERO_NB];
1337 0 : move32();
1338 : }
1339 :
1340 0 : return 0;
1341 : }
1342 :
1343 0 : static void FEC_phase_matching_nextgood_fx(
1344 : const Word32 *ImdctOut_fx, /* i : input Q6 */
1345 : Word16 *auOut_fx, /* o : output audio */
1346 : Word16 *OldauOut_fx, /* i/o: audio from previous frame Q0 */
1347 : Word16 OldauOut_pha_fx[2][N_LEAD_NB],
1348 : Word16 mean_en_high_fx /*Q5 */
1349 : )
1350 : {
1351 : Word16 i;
1352 : Word16 L_overlap, L;
1353 : Word16 oldout_pha_idx;
1354 : Word16 *OldOut_pha_fx; // Qx
1355 : Word16 ImdctOutWin_fx[2 * L_FRAME48k];
1356 : Word16 win_NB_fx[L_FRAME8k + 25];
1357 :
1358 0 : L = L_FRAME8k;
1359 0 : move16();
1360 0 : FOR( i = 0; i < L + 25; i++ )
1361 : {
1362 : /* win_NB[i] = window_48kHz[i*6+3]; */
1363 0 : win_NB_fx[i] = window_48kHz_fx[i * 6 + 3]; // Q15
1364 0 : move16();
1365 : }
1366 :
1367 0 : test();
1368 0 : IF( ( GT_16( mean_en_high_fx, 64 ) ) || ( LT_16( mean_en_high_fx, 16 ) ) )
1369 : {
1370 0 : oldout_pha_idx = 1;
1371 0 : move16();
1372 : }
1373 : ELSE
1374 : {
1375 0 : oldout_pha_idx = 0;
1376 0 : move16();
1377 : }
1378 :
1379 : /* Overlapping with next good frame : Overlapping to remove the discontinuity */
1380 0 : L_overlap = N_LEAD_NB;
1381 0 : move16();
1382 0 : OldOut_pha_fx = OldauOut_pha_fx[oldout_pha_idx];
1383 0 : FOR( i = 0; i < N_LEAD_NB; i++ )
1384 : {
1385 : /* OldOut_pha[i] *= SmoothingWin_NB875[L_overlap-i-1]; */
1386 0 : OldOut_pha_fx[i] = mult( OldOut_pha_fx[i], SmoothingWin_NB875_fx[L_overlap - i - 1] );
1387 0 : move16();
1388 : }
1389 :
1390 0 : IF( EQ_16( oldout_pha_idx, 1 ) )
1391 : {
1392 : /* Use phase matching and overlapping with the Oldauout*/
1393 : /* Windowing */
1394 : /*Windowing_1st_NB(ImdctOutWin, ImdctOut, win_NB, NULL, 0);*/
1395 : /*Windowing_2nd_NB(ImdctOutWin, ImdctOut, win_NB); */
1396 0 : Windowing_1st_NB_fx( ImdctOutWin_fx, ImdctOut_fx, win_NB_fx, NULL, 0 );
1397 0 : Windowing_2nd_NB_fx( ImdctOutWin_fx, ImdctOut_fx, win_NB_fx );
1398 : }
1399 : ELSE
1400 : {
1401 : /* Only use phase matching */
1402 : /* Windowing */
1403 0 : Windowing_1st_NB_fx( ImdctOutWin_fx, ImdctOut_fx, win_NB_fx, SmoothingWin_NB875_fx, 1 );
1404 0 : Windowing_2nd_NB_fx( ImdctOutWin_fx, ImdctOut_fx, win_NB_fx );
1405 : }
1406 : /* common_overlapping(auOut, ImdctOutWin, OldOut_pha, N_LEAD_NB, 0, N_LEAD_NB, L, N_ZERO_NB, 0, L);*/
1407 0 : common_overlapping_fx( auOut_fx, ImdctOutWin_fx, OldOut_pha_fx, N_LEAD_NB, 0, N_LEAD_NB, L, N_ZERO_NB, 0 );
1408 0 : Copy( &ImdctOutWin_fx[L], OldauOut_fx, L );
1409 :
1410 0 : return;
1411 : }
1412 :
1413 0 : static void FEC_phase_matching_burst_fx(
1414 : const Word32 *ImdctOut_fx, /* i : input Q6 */
1415 : Word16 *auOut_fx, /* o : output audio Q0 */
1416 : Word16 *OldauOut_fx, /* i/o: audio from previous frame Q0 */
1417 : Word16 OldauOut_pha_fx[2][N_LEAD_NB],
1418 : Word16 *prev_oldauOut_fx /* i : OldauOut from previous frame Q0 */
1419 : )
1420 : {
1421 : Word16 i;
1422 : Word16 L_overlap;
1423 : Word16 L;
1424 : Word16 OldauOut2_fx[L_FRAME8k];
1425 : Word16 ImdctOutWin_fx[2 * L_FRAME8k];
1426 : Word16 win_NB_fx[L_FRAME8k + 25];
1427 : Word16 SmoothingWin_NB3_fx[24];
1428 :
1429 0 : L = L_FRAME8k;
1430 0 : move16();
1431 0 : L_overlap = idiv1616( imult1616( 3, L ), 20 );
1432 0 : move16();
1433 :
1434 0 : FOR( i = 0; i < L_overlap; i++ )
1435 : {
1436 0 : SmoothingWin_NB3_fx[i] = SmoothingWin_NB875_fx[i * 3];
1437 0 : move16();
1438 : }
1439 :
1440 0 : FOR( i = 0; i < add( L, 25 ); i++ )
1441 : {
1442 0 : win_NB_fx[i] = window_48kHz_fx[i * 6 + 3]; // Q15
1443 0 : move16();
1444 : }
1445 :
1446 : /* Windowing */
1447 0 : Windowing_1st_NB_fx( ImdctOutWin_fx, ImdctOut_fx, win_NB_fx, NULL, 0 );
1448 0 : Windowing_2nd_NB_fx( ImdctOutWin_fx, ImdctOut_fx, win_NB_fx );
1449 :
1450 : /* Repetition with old frame to reserve energy */
1451 : /*common_overlapping(auOut, ImdctOutWin, prev_oldauOut, N_Z_L_NB, 0, N_Z_L_NB, L, N_ZERO_NB, 0, L);*/
1452 0 : common_overlapping_fx( auOut_fx, ImdctOutWin_fx, prev_oldauOut_fx, N_Z_L_NB, 0, N_Z_L_NB, L, N_ZERO_NB, 0 );
1453 :
1454 : /* data transition from OldauOut to auOut using smoothing win*/
1455 0 : Smoothing_vector_NB_fx( OldauOut_pha_fx[0], auOut_fx, SmoothingWin_NB875_fx, auOut_fx, N_LEAD_NB );
1456 :
1457 : /* Update the OldauOut array for next overlapping */
1458 0 : Copy( &ImdctOutWin_fx[N_Z_L_O_NB], &OldauOut_pha_fx[0][0], N_LEAD_NB );
1459 0 : Copy( &ImdctOutWin_fx[L], OldauOut_fx, L );
1460 0 : Scaledown_fx( prev_oldauOut_fx, prev_oldauOut_fx, 23170, L );
1461 :
1462 0 : FOR( i = 0; i < L / 2; i++ )
1463 : {
1464 : /* OldauOut2[i] = -ImdctOut[L/2 - 1 - i];*/
1465 : /* OldauOut2[L/2+i] = -ImdctOut[i];*/
1466 0 : OldauOut2_fx[i] = extract_l( L_shr( L_negate( ImdctOut_fx[L / 2 - 1 - i] ), 6 ) ); // Q6 -> Q0
1467 0 : move16();
1468 0 : OldauOut2_fx[L / 2 + i] = extract_l( L_shr( L_negate( ImdctOut_fx[i] ), 6 ) ); // Q6 -> Q0
1469 0 : move16();
1470 : }
1471 :
1472 0 : Smoothing_vector_NB_fx( &ImdctOutWin_fx[N_Z_L_O_NB], &OldauOut2_fx[N_ZERO_NB], SmoothingWin_NB3_fx, &OldauOut_pha_fx[1][0], L_overlap );
1473 :
1474 0 : FOR( i = L_overlap; i < N_LEAD_NB; i++ )
1475 : {
1476 : /* OldauOut_pha[1][i] = OldauOut2[i+N_ZERO_NB]; */
1477 0 : OldauOut_pha_fx[1][i] = OldauOut2_fx[i + N_ZERO_NB];
1478 0 : move16();
1479 : }
1480 :
1481 0 : return;
1482 : }
1483 :
1484 0 : static void Repetition_smoothing_nextgood_fx(
1485 : const Word32 *ImdctOut_fx, /* i : input Q6 */
1486 : Word16 *auOut_fx, /* o : output audio Q0 */
1487 : Word32 *OldImdctOut_fx, /* i : input Q6 */
1488 : Word16 *OldauOut_fx, /* i/o: audio from previous frame Q0 */
1489 : Word16 cur_data_use_flag, /* i : current imdct data use flag */
1490 : Word16 overlap_time )
1491 : {
1492 : Word16 i;
1493 : Word16 L_overlap;
1494 : Word16 ol_size;
1495 : Word16 L;
1496 : Word16 ImdctOutWin_fx[2 * L_FRAME8k]; // Q0
1497 : Word16 win_NB_fx[L_FRAME8k + 25];
1498 :
1499 0 : L = L_FRAME8k;
1500 0 : move16();
1501 :
1502 0 : FOR( i = 0; i < L_FRAME8k + 25; i++ )
1503 : {
1504 : /*win_NB[i] = window_48kHz[i*6+3];*/
1505 0 : win_NB_fx[i] = window_48kHz_fx[i * 6 + 3]; // Q15
1506 0 : move16();
1507 : }
1508 :
1509 0 : FOR( i = N_ZERO_NB; i < L / 2; i++ )
1510 : {
1511 : /*OldauOut[i-N_ZERO_NB] = -OldImdctOut[L/2 - 1 - i];*/
1512 0 : OldauOut_fx[i - N_ZERO_NB] = extract_l( L_shr( L_negate( OldImdctOut_fx[L / 2 - 1 - i] ), 6 ) ); /* Q6 -> Q0 */
1513 0 : move16();
1514 : }
1515 0 : FOR( i = 0; i < L / 4; i++ )
1516 : {
1517 : /*OldauOut[i+N_ZERO_O_NB] = -OldImdctOut[i];*/
1518 0 : OldauOut_fx[i + N_ZERO_O_NB] = extract_l( L_shr( L_negate( OldImdctOut_fx[i] ), 6 ) ); /* Q6 -> Q0 */
1519 0 : move16();
1520 : }
1521 :
1522 : /* Overlapping with next good frame : Overlapping to remove the discontinuity */
1523 0 : IF( cur_data_use_flag )
1524 : {
1525 0 : ol_size = N_LEAD_NB;
1526 0 : move16();
1527 :
1528 0 : FOR( i = N_ZERO_NB; i < L / 2; i++ )
1529 : {
1530 : /* ImdctOutWin[i+L] = -ImdctOut[L/2 - 1 - i]; */
1531 0 : ImdctOutWin_fx[add( i, L )] = extract_l( L_shr( L_negate( ImdctOut_fx[L / 2 - 1 - i] ), 6 ) ); /* Q6 -> Q0 */
1532 0 : move16();
1533 : }
1534 0 : FOR( i = 0; i < L / 2; i++ )
1535 : {
1536 0 : ImdctOutWin_fx[i + 3 * L / 2] = extract_l( L_shr( L_negate( ImdctOut_fx[i] ), 6 ) ); /* Q6 -> Q0 */
1537 0 : move16();
1538 : }
1539 :
1540 : /*a = (float)(1./(float)(ol_size)); y = ax */
1541 0 : Smoothing_vector_scaledown_NB_fx( OldauOut_fx, &ImdctOutWin_fx[N_Z_L_O_NB], SmoothingWin_NB875_fx, OldauOut_fx, ol_size );
1542 :
1543 : /* Scale down the overlapped signal */
1544 0 : Scaledown_fx( &ImdctOutWin_fx[ol_size + N_Z_L_O_NB], &OldauOut_fx[ol_size], 23170, sub( N_Z_L_NB, ol_size ) ); // SCALE_DOWN_3dB.Q15 = 23170
1545 : }
1546 :
1547 0 : L_overlap = overlap_time;
1548 0 : move16();
1549 0 : FOR( i = 0; i < L_overlap; i++ )
1550 : {
1551 : /*OldauOut[i] *= SmoothingWin_NB875[L_overlap-i-1];*/
1552 0 : OldauOut_fx[i] = mult( OldauOut_fx[i], SmoothingWin_NB875_fx[L_overlap - i - 1] );
1553 0 : move16();
1554 : }
1555 0 : FOR( i = L_overlap; i < L; i++ )
1556 : {
1557 0 : OldauOut_fx[i] = 0;
1558 0 : move16();
1559 : }
1560 :
1561 : /* Windowing */
1562 : /*Windowing_1st_NB(ImdctOutWin, ImdctOut, win_NB, SmoothingWin_NB875, 1);*/
1563 : /*Windowing_2nd_NB(ImdctOutWin, ImdctOut, win_NB);*/
1564 0 : Windowing_1st_NB_fx( ImdctOutWin_fx, ImdctOut_fx, win_NB_fx, SmoothingWin_NB875_fx, 1 );
1565 0 : Windowing_2nd_NB_fx( ImdctOutWin_fx, ImdctOut_fx, win_NB_fx );
1566 :
1567 : /*v_add(&ImdctOutWin[N_ZERO_NB], OldauOut, auOut, L);*/
1568 : /*mvr2r(&ImdctOutWin[L], OldauOut, L);*/
1569 0 : FOR( i = 0; i < L; i++ )
1570 : {
1571 0 : auOut_fx[i] = add_sat( ImdctOutWin_fx[N_ZERO_NB + i], OldauOut_fx[i] ); // Q0
1572 0 : move16();
1573 : }
1574 0 : Copy( &ImdctOutWin_fx[L], OldauOut_fx, L );
1575 :
1576 0 : return;
1577 : }
1578 :
1579 0 : static Word16 Repetition_smoothing_fx(
1580 : const Word32 *ImdctOut_fx, /* i : input Q6 */
1581 : Word16 *auOut_fx, /* o : output audio Q0 */
1582 : Word32 *OldImdctOut_fx, /* i : input Q6 */
1583 : Word16 *OldauOut_fx, /* i/o: audio from previous frame Q0 */
1584 : const Word16 L, /* i : length */
1585 : Word16 *prev_oldauOut_fx, /* i : OldauOut from previous frame Q0 */
1586 : Word16 overlap_time /* i : overlap time */
1587 : )
1588 : {
1589 : Word16 i;
1590 : Word32 pow1_fx;
1591 : Word32 pow22_fx;
1592 : Word16 ImdctOutWin_fx[2 * L_FRAME8k]; // Q0
1593 : Word16 OldauOutnoWin_fx[L_FRAME8k]; // Q0
1594 : Word16 win_NB_fx[L_FRAME8k + 25];
1595 :
1596 0 : FOR( i = 0; i < L_FRAME8k + 25; i++ )
1597 : {
1598 : /*win_NB[i] = window_48kHz[i*6+3];*/
1599 0 : win_NB_fx[i] = window_48kHz_fx[i * 6 + 3]; // Q15
1600 0 : move16();
1601 : }
1602 :
1603 : /* Windowing */
1604 0 : Windowing_1st_NB_fx( ImdctOutWin_fx, ImdctOut_fx, win_NB_fx, NULL, 0 );
1605 0 : Windowing_2nd_NB_fx( ImdctOutWin_fx, ImdctOut_fx, win_NB_fx );
1606 :
1607 : /* Repetition with old frame to reserve energy */
1608 0 : common_overlapping_fx( auOut_fx, ImdctOutWin_fx, prev_oldauOut_fx, N_Z_L_NB, 0, N_Z_L_NB, L, N_ZERO_NB, 0 );
1609 :
1610 : /* OldauOut without windowing */
1611 0 : FOR( i = N_ZERO_NB; i < L / 2; i++ )
1612 : {
1613 0 : OldauOutnoWin_fx[i - N_ZERO_NB] = extract_l( L_shr( L_negate( OldImdctOut_fx[L / 2 - 1 - i] ), 6 ) ); /* Q6 -> Q0 */
1614 0 : move16();
1615 : }
1616 0 : FOR( i = 0; i < L / 2; i++ )
1617 : {
1618 0 : OldauOutnoWin_fx[i + N_ZERO_O_NB] = extract_l( L_shr( L_negate( OldImdctOut_fx[i] ), 6 ) ); /* Q6 -> Q0 */
1619 0 : move16();
1620 : }
1621 :
1622 : /* data transition from OldauOut to auOut using smoothing win*/
1623 0 : Smoothing_vector_NB_fx( OldauOutnoWin_fx, auOut_fx, SmoothingWin_NB875_fx, auOut_fx, overlap_time );
1624 :
1625 0 : pow1_fx = L_deposit_l( 0 );
1626 0 : pow22_fx = L_deposit_l( 0 );
1627 0 : FOR( i = 0; i < ( 4 * L ) / 20; i++ )
1628 : {
1629 0 : pow1_fx = L_add( pow1_fx, Mult_32_32( L_shl( (Word32) auOut_fx[( L / 20 ) + i], 6 ), L_shl( (Word32) auOut_fx[( L / 20 ) + i], 6 ) ) );
1630 0 : pow22_fx = L_add( pow22_fx, Mult_32_32( L_shl( (Word32) auOut_fx[N_LEAD_NB + i], 6 ), L_shl( (Word32) auOut_fx[N_LEAD_NB + i], 6 ) ) );
1631 : }
1632 :
1633 :
1634 0 : if ( GT_32( pow22_fx, L_add( pow1_fx, L_shl( pow1_fx, 1 ) ) ) )
1635 : {
1636 0 : return 1;
1637 : }
1638 :
1639 : /* Update the OldauOut array for next overlapping */
1640 0 : Copy( &ImdctOutWin_fx[L], OldauOut_fx, L );
1641 0 : Scaledown_fx( prev_oldauOut_fx, prev_oldauOut_fx, 23170, L );
1642 :
1643 0 : return 0;
1644 : }
1645 :
1646 0 : static void common_overlapping_fx(
1647 : Word16 *auOut_fx, /* i : Input Q0 */
1648 : Word16 *ImdctOutWin_fx, /* o : Output Q0 */
1649 : Word16 *OldauOut_fx, /* i : Window Q0 */
1650 : Word16 end1, /* i : Decay */
1651 : Word16 offset1,
1652 : Word16 start2,
1653 : Word16 end2,
1654 : Word16 offset_i2,
1655 : Word16 offset2 )
1656 : {
1657 : Word16 i;
1658 :
1659 : /* Common Overlapping */
1660 0 : FOR( i = 0; i < end1; i++ )
1661 : {
1662 : /*auOut_fx[i] = L_add(ImdctOutWin_fx[i+7*L/20], OldauOut_fx[i+offset1]);*/
1663 0 : auOut_fx[i] = add_sat( ImdctOutWin_fx[i + N_ZERO_NB], OldauOut_fx[i + offset1] );
1664 0 : move16();
1665 : }
1666 0 : FOR( i = start2; i < end2; i++ )
1667 : {
1668 : /*auOut_fx[i+offset2] = ImdctOutWin_fx[i+offset_i2]; move32();*/
1669 0 : auOut_fx[i + offset2] = ImdctOutWin_fx[i + offset_i2];
1670 0 : move16();
1671 : }
1672 :
1673 0 : return;
1674 : }
1675 :
1676 :
1677 0 : static void Smoothing_vector_NB_fx(
1678 : const Word16 OldauOutnoWin_fx[], /* i : Input vector 1 Qx */
1679 : const Word16 ImdctOutWin_fx[], /* i : Input vector 2 Qx */
1680 : const Word16 SmoothingWin_fx[], /* i : Smoothing window Q15 */
1681 : Word16 auOut_fx[], /* o : Output vector that contains vector 1 .* vector 2 Qx*/
1682 : const Word16 ol_size /* i : Overlap size */
1683 : )
1684 : {
1685 : Word16 i;
1686 : Word16 weight_fx; // Q15
1687 :
1688 0 : FOR( i = 0; i < ol_size; i++ )
1689 : {
1690 0 : weight_fx = SmoothingWin_fx[i];
1691 0 : move16();
1692 0 : auOut_fx[i] = add( mult( OldauOutnoWin_fx[i], sub( 32767, weight_fx ) ), mult( ImdctOutWin_fx[i], weight_fx ) );
1693 0 : move16();
1694 : }
1695 :
1696 0 : return;
1697 : }
1698 :
1699 :
1700 0 : static void Windowing_1st_NB_fx(
1701 : Word16 *ImdctOutWin_fx, /* o : Output Q0 */
1702 : const Word32 *ImdctOut_fx, /* i : Input Q6 */
1703 : const Word16 *win_fx, /* i : Window Q15 */
1704 : const Word16 *smoothingWin_fx, /* i : Smoothing Window Q15 */
1705 : Word16 smoothing_flag /* i : 1=Smoothing window, 0=Original window */
1706 : )
1707 : {
1708 : Word16 i;
1709 : Word16 L;
1710 :
1711 0 : L = L_FRAME8k;
1712 0 : move16();
1713 0 : IF( smoothing_flag == 0 )
1714 : {
1715 0 : FOR( i = N_ZERO_NB; i < L / 2; i++ )
1716 : {
1717 : /*ImdctOutWin[i] = ImdctOut[L/2 + i] * win[(2*L-1-i)-N_LEAD_O_NB];*/
1718 0 : ImdctOutWin_fx[i] = extract_l( L_shr( Mult_32_16( ImdctOut_fx[L / 2 + i], win_fx[( 2 * L - 1 - i ) - N_LEAD_O_NB] ), 6 ) ); // Q6 -> Q0
1719 0 : move16();
1720 : }
1721 :
1722 0 : FOR( i = 0; i < N_ZERO_O_NB; i++ )
1723 : {
1724 : /*ImdctOutWin[L/2 + i] = -ImdctOut[L - 1 - i] * win[(3*L/2-1-i)-N_LEAD_O_NB];*/
1725 : /*ImdctOutWin[3*L/2 + i] = -ImdctOut[i] * win[(L/2-i-1)];*/
1726 0 : ImdctOutWin_fx[L / 2 + i] = extract_l( L_shr( Mult_32_16( L_negate( ImdctOut_fx[L - 1 - i] ), win_fx[( 3 * L / 2 - 1 - i ) - N_LEAD_O_NB] ), 6 ) ); // Q6 -> Q0
1727 0 : move16();
1728 0 : ImdctOutWin_fx[3 * L / 2 + i] = extract_l( L_shr( Mult_32_16( L_negate( ImdctOut_fx[i] ), win_fx[( L / 2 - i - 1 )] ), 6 ) ); // Q6 -> Q0
1729 0 : move16();
1730 : }
1731 : }
1732 : ELSE
1733 : {
1734 0 : FOR( i = N_ZERO_NB; i < L / 2; i++ )
1735 : {
1736 : /*ImdctOutWin[i] = ImdctOut[L/2 + i] * smoothingWin[(i-N_ZERO_NB)];*/ /*win[(2*L-i)*decimate-1-decay-14*L_FRAME48k/20];*/
1737 0 : ImdctOutWin_fx[i] = extract_l( L_shr( Mult_32_16( ImdctOut_fx[L / 2 + i], smoothingWin_fx[( i - N_ZERO_NB )] ), 6 ) ); /*win[(2*L-i)*decimate-1-decay-14*L_FRAME48k/20];*/
1738 0 : move16();
1739 : }
1740 :
1741 0 : FOR( i = 0; i < N_ZERO_O_NB; i++ )
1742 : {
1743 : /*ImdctOutWin[L/2 + i] = -ImdctOut[L - 1 - i] * smoothingWin[(i+N_ZERO_O_NB)];*/ /*win[(3*L/2-1-i)*decimate+decay-L_FRAME48k*14/20];*/
1744 : /*ImdctOutWin[3*L/2 + i] = -ImdctOut[i] * win[(L/2-i-1)];*/
1745 0 : ImdctOutWin_fx[L / 2 + i] = extract_l( L_shr( Mult_32_16( L_negate( ImdctOut_fx[L - 1 - i] ), smoothingWin_fx[( i + N_ZERO_O_NB )] ), 6 ) ); /*win[(3*L/2-1-i)*decimate+decay-L_FRAME48k*14/20];*/ // Q6 -> Q0
1746 0 : move16();
1747 0 : ImdctOutWin_fx[3 * L / 2 + i] = extract_l( L_shr( Mult_32_16( L_negate( ImdctOut_fx[i] ), win_fx[( L / 2 - i - 1 )] ), 6 ) ); // Q6 -> Q0
1748 0 : move16();
1749 : }
1750 : }
1751 :
1752 0 : return;
1753 : }
1754 0 : static void Windowing_2nd_NB_fx(
1755 : Word16 *ImdctOutWin_fx, /* o : Output Q0 */
1756 : const Word32 *ImdctOut_fx, /* i : Input Q6 */
1757 : const Word16 *win_fx /* i : Window Q15 */
1758 : )
1759 : {
1760 : Word16 i;
1761 : Word16 L;
1762 :
1763 0 : L = L_FRAME8k;
1764 0 : move16();
1765 0 : FOR( i = N_ZERO_O_NB; i < L / 2; i++ )
1766 : {
1767 : /*ImdctOutWin[L/2 + i] = -ImdctOut[L - 1 - i];*/
1768 : /*ImdctOutWin[3*L/2 + i] = -ImdctOut[i] * win[L/2-i-1];*/
1769 0 : ImdctOutWin_fx[L / 2 + i] = extract_l( L_shr( L_negate( ImdctOut_fx[L - 1 - i] ), 6 ) );
1770 0 : move16();
1771 0 : ImdctOutWin_fx[3 * L / 2 + i] = extract_l( L_shr( Mult_32_16( L_negate( ImdctOut_fx[i] ), win_fx[L / 2 - i - 1] ), 6 ) );
1772 0 : move16();
1773 : }
1774 :
1775 0 : FOR( i = 0; i < N_ZERO_NB; i++ )
1776 : {
1777 : /*ImdctOutWin[L + i] = -ImdctOut[L/2 - 1 - i];*/
1778 0 : ImdctOutWin_fx[L + i] = extract_l( L_shr( L_negate( ImdctOut_fx[L / 2 - 1 - i] ), 6 ) );
1779 0 : move16();
1780 : }
1781 :
1782 0 : FOR( i = N_ZERO_NB; i < L / 2; i++ )
1783 : {
1784 : /*ImdctOutWin[L + i] = -ImdctOut[L/2 - 1 - i] * win[L - 1 - i];*/
1785 0 : ImdctOutWin_fx[L + i] = extract_l( L_shr( Mult_32_16( L_negate( ImdctOut_fx[L / 2 - 1 - i] ), win_fx[L - 1 - i] ), 6 ) );
1786 0 : move16();
1787 : }
1788 :
1789 0 : return;
1790 : }
1791 :
1792 0 : static void Smoothing_vector_scaledown_NB_fx(
1793 : const Word16 OldauOutnoWin_fx[], /* i : Input vector 1 Q0 */
1794 : const Word16 ImdctOutWin_fx[], /* i : Input vector 2 Q0 */
1795 : const Word16 SmoothingWin_fx[], /* i : Smoothing window Q15 */
1796 : Word16 auOut_fx[], /* o : Output vector that contains vector 1 .* vector 2 Q0 */
1797 : const Word16 ol_size /* i : Overlap size */
1798 :
1799 : )
1800 : {
1801 : Word16 i;
1802 : Word16 weight_fx; // Q15
1803 :
1804 0 : FOR( i = 0; i < ol_size; i++ )
1805 : {
1806 0 : weight_fx = SmoothingWin_fx[i];
1807 0 : move16();
1808 0 : auOut_fx[i] = add( mult( OldauOutnoWin_fx[i], sub( 32767, weight_fx ) ),
1809 0 : mult( ImdctOutWin_fx[i], mult_r( 23170, weight_fx ) ) );
1810 0 : move16();
1811 : }
1812 :
1813 0 : return;
1814 : }
1815 :
1816 :
1817 0 : static void Scaledown_fx(
1818 : Word16 x[], /* i : Input vector */
1819 : Word16 y[], /* o : Output vector that contains vector 1 .* vector 2 */
1820 : Word16 scale_v, /*Q15 */
1821 : const Word16 N /* i : Overlap size */
1822 : )
1823 : {
1824 : Word16 i;
1825 :
1826 0 : FOR( i = 0; i < N; i++ )
1827 : {
1828 0 : y[i] = mult( x[i], scale_v );
1829 0 : move16();
1830 : }
1831 :
1832 0 : return;
1833 : }
1834 :
1835 0 : void time_domain_FEC_HQ_fx(
1836 : Decoder_State *st_fx, /* i : Decoder State */
1837 : Word32 *wtda_audio_fx, /* i : input Q6 */
1838 : Word16 *out_fx, /* o : output audio Q0 */
1839 : Word16 mean_en_high_fx, /* i : transient flag */
1840 : const Word16 output_frame,
1841 : Word16 *Q_synth )
1842 : {
1843 : HQ_NBFEC_HANDLE hHQ_nbfec;
1844 : HQ_DEC_HANDLE hHQ_core;
1845 0 : hHQ_nbfec = st_fx->hHQ_nbfec;
1846 0 : hHQ_core = st_fx->hHQ_core;
1847 :
1848 0 : IF( hHQ_core->Q_old_wtda != 0 )
1849 : {
1850 0 : Scale_sig( hHQ_core->old_out_fx, output_frame, negate( hHQ_core->Q_old_wtda ) );
1851 0 : hHQ_core->Q_old_wtda = 0;
1852 0 : move16();
1853 : }
1854 :
1855 0 : test();
1856 0 : test();
1857 0 : test();
1858 0 : test();
1859 0 : test();
1860 0 : test();
1861 0 : IF( ( EQ_16( st_fx->nbLostCmpt, 1 ) ) && ( EQ_16( hHQ_nbfec->phase_mat_flag, 1 ) ) && ( hHQ_nbfec->phase_mat_next == 0 ) )
1862 : {
1863 0 : IF( FEC_phase_matching_fx( hHQ_nbfec, wtda_audio_fx, out_fx, hHQ_core->old_out_fx, hHQ_nbfec->old_out_pha_fx ) )
1864 : {
1865 : /* window_ola( wtda_audio, out, st->old_out, output_frame, 0, 0, 0 ); */
1866 0 : window_ola_fx( wtda_audio_fx, out_fx, Q_synth, hHQ_core->old_out_fx, &hHQ_core->Q_old_wtda, output_frame, ALDO_WINDOW, ALDO_WINDOW, 0, 0, 0 );
1867 0 : hHQ_nbfec->phase_mat_next = 0;
1868 0 : move16();
1869 : }
1870 : ELSE
1871 : {
1872 0 : hHQ_nbfec->phase_mat_next = 1;
1873 0 : move16();
1874 0 : *Q_synth = 0;
1875 0 : move16();
1876 : }
1877 : }
1878 0 : ELSE IF( ( EQ_16( st_fx->prev_bfi, 1 ) ) && ( st_fx->bfi == 0 ) && ( EQ_16( hHQ_nbfec->phase_mat_next, 1 ) ) )
1879 : {
1880 0 : FEC_phase_matching_nextgood_fx( wtda_audio_fx, out_fx, hHQ_core->old_out_fx, hHQ_nbfec->old_out_pha_fx, mean_en_high_fx );
1881 :
1882 0 : hHQ_nbfec->phase_mat_next = 0;
1883 0 : move16();
1884 0 : *Q_synth = 0;
1885 0 : move16();
1886 : }
1887 0 : ELSE IF( ( EQ_16( st_fx->prev_bfi, 1 ) ) && ( EQ_16( st_fx->bfi, 1 ) ) && ( EQ_16( hHQ_nbfec->phase_mat_next, 1 ) ) )
1888 : {
1889 0 : FEC_phase_matching_burst_fx( wtda_audio_fx, out_fx, hHQ_core->old_out_fx, hHQ_nbfec->old_out_pha_fx, hHQ_nbfec->prev_oldauOut_fx );
1890 0 : hHQ_nbfec->phase_mat_next = 1;
1891 0 : move16();
1892 0 : *Q_synth = 0;
1893 0 : move16();
1894 : }
1895 : ELSE
1896 : {
1897 : /*n4 = (short)(N_LEAD_MDCT*(float)(output_frame/20));*/
1898 0 : test();
1899 0 : IF( st_fx->bfi == 0 && EQ_16( st_fx->prev_bfi, 1 ) )
1900 : {
1901 0 : test();
1902 0 : IF( ( EQ_16( hHQ_nbfec->stat_mode_out, 1 ) ) || ( LT_16( hHQ_nbfec->diff_energy_fx, ED_THRES_50P_fx ) ) ) /* Q11 */
1903 0 : {
1904 : Word16 tmp;
1905 :
1906 0 : tmp = 0;
1907 0 : move16();
1908 0 : if ( GT_16( st_fx->old_bfi_cnt, 1 ) )
1909 : {
1910 0 : tmp = 1;
1911 0 : move16();
1912 : }
1913 0 : Repetition_smoothing_nextgood_fx( wtda_audio_fx, out_fx, hHQ_nbfec->oldIMDCTout_fx, hHQ_core->old_out_fx, tmp, N_LEAD_NB );
1914 0 : *Q_synth = 0;
1915 0 : move16();
1916 : }
1917 0 : ELSE IF( GT_16( st_fx->old_bfi_cnt, 1 ) )
1918 : {
1919 0 : Next_good_after_burst_erasures_fx( wtda_audio_fx, out_fx, hHQ_core->old_out_fx, N_LEAD_NB );
1920 0 : *Q_synth = 0;
1921 0 : move16();
1922 : }
1923 : ELSE
1924 : {
1925 : /*window_ola( wtda_audio, out, st->old_out, output_frame, 0, 0, 0); */
1926 0 : window_ola_fx( wtda_audio_fx, out_fx, Q_synth, hHQ_core->old_out_fx, &hHQ_core->Q_old_wtda, output_frame,
1927 0 : st_fx->hTcxCfg->tcx_last_overlap_mode, st_fx->hTcxCfg->tcx_curr_overlap_mode, st_fx->prev_bfi, hHQ_core->oldHqVoicing, hHQ_core->oldgapsynth_fx );
1928 : }
1929 : }
1930 : ELSE /* if(st->bfi == 1) */
1931 : {
1932 0 : test();
1933 0 : IF( ( EQ_16( hHQ_nbfec->stat_mode_out, 1 ) ) || ( LT_16( hHQ_nbfec->diff_energy_fx, ED_THRES_50P_fx ) ) )
1934 : {
1935 : /* if( window_ola_bfi( wtda_audio, out, st->oldIMDCTout, st->old_out, output_frame, st->prev_oldauOut, N_LEAD_NB) ) */
1936 0 : IF( Repetition_smoothing_fx( wtda_audio_fx, out_fx, hHQ_nbfec->oldIMDCTout_fx, hHQ_core->old_out_fx, output_frame, hHQ_nbfec->prev_oldauOut_fx, N_LEAD_NB ) )
1937 : {
1938 : /*window_ola( wtda_audio, out, st->old_out, output_frame, 0, 0, 0);*/
1939 0 : window_ola_fx( wtda_audio_fx, out_fx, Q_synth, hHQ_core->old_out_fx, &hHQ_core->Q_old_wtda, output_frame,
1940 0 : st_fx->hTcxCfg->tcx_last_overlap_mode, st_fx->hTcxCfg->tcx_curr_overlap_mode, st_fx->prev_bfi, hHQ_core->oldHqVoicing, hHQ_core->oldgapsynth_fx );
1941 : }
1942 : ELSE
1943 : {
1944 0 : *Q_synth = 0;
1945 0 : move16();
1946 : }
1947 : }
1948 : ELSE
1949 : {
1950 : /*window_ola( wtda_audio, out, st->old_out, output_frame, 0, 0, 0 );*/
1951 0 : window_ola_fx( wtda_audio_fx, out_fx, Q_synth, hHQ_core->old_out_fx, &hHQ_core->Q_old_wtda, output_frame,
1952 0 : st_fx->hTcxCfg->tcx_last_overlap_mode, st_fx->hTcxCfg->tcx_curr_overlap_mode, st_fx->prev_bfi, hHQ_core->oldHqVoicing, hHQ_core->oldgapsynth_fx );
1953 : }
1954 : }
1955 0 : hHQ_nbfec->phase_mat_next = 0;
1956 0 : move16();
1957 : }
1958 :
1959 0 : return;
1960 : }
1961 :
1962 0 : static void Next_good_after_burst_erasures_fx(
1963 : const Word32 *ImdctOut_fx, // Q6
1964 : Word16 *auOut_fx, // Q0
1965 : Word16 *OldauOut_fx, // Q0
1966 : const Word16 ol_size )
1967 : {
1968 : Word16 i, L;
1969 : Word16 ImdctOutWin_fx[2 * L_FRAME48k]; // Q0
1970 : Word16 win_NB_fx[L_FRAME8k + 25];
1971 :
1972 0 : L = L_FRAME8k;
1973 0 : move16();
1974 0 : FOR( i = 0; i < add( L, 25 ); i++ )
1975 : {
1976 0 : win_NB_fx[i] = window_48kHz_fx[i * 6 + 3]; // Q15
1977 0 : move16();
1978 : }
1979 :
1980 : /* Windowing */
1981 0 : Windowing_1st_NB_fx( ImdctOutWin_fx, ImdctOut_fx, win_NB_fx, NULL, 0 );
1982 0 : Windowing_2nd_NB_fx( ImdctOutWin_fx, ImdctOut_fx, win_NB_fx );
1983 :
1984 : /* Overlapping with next good frame : Overlapping to remove the discontinuity */
1985 0 : Smoothing_vector_scaledown_NB_fx( &OldauOut_fx[N_ZERO_NB], &ImdctOutWin_fx[N_Z_L_O_NB], SmoothingWin_NB875_fx, &OldauOut_fx[N_ZERO_NB], ol_size );
1986 :
1987 : /* Scale down the overlapped signal */
1988 0 : Scaledown_fx( &ImdctOutWin_fx[ol_size + N_Z_L_O_NB], &OldauOut_fx[ol_size + N_ZERO_NB], 23170, sub( N_Z_L_NB, ol_size ) );
1989 :
1990 : /* Common Overlapping */
1991 0 : common_overlapping_fx( auOut_fx, ImdctOutWin_fx, OldauOut_fx, N_Z_L_NB, N_ZERO_NB, 0, N_ZERO_NB, L, N_Z_L_NB );
1992 0 : Copy( &ImdctOutWin_fx[L], OldauOut_fx, L );
1993 :
1994 0 : return;
1995 : }
1996 :
1997 : /*--------------------------------------------------------------------------
1998 : * save_synthesis_hq_fec_fx()
1999 : *
2000 : * Save synthesis for HQ FEC
2001 : *-------------------------------------------------------------------------*/
2002 :
2003 1082231 : void save_synthesis_hq_fec_fx(
2004 : Decoder_State *st, /* i/o: decoder state structure */
2005 : const Word16 synth_fx[], /* i : decoded synthesis (EVS) */
2006 : const Word32 output_fx[], /* i : decoded synthesis */
2007 : const Word16 output_frame, /* i : decoded synthesis */
2008 : const Word16 Qpostd, /* i : Q value of delayed signal */
2009 : CPE_DEC_HANDLE hCPE /* i : CPE decoder structure */
2010 : )
2011 : {
2012 : Word16 post_hq_delay;
2013 :
2014 1082231 : SWITCH( st->element_mode )
2015 : {
2016 3100 : case EVS_MONO:
2017 3100 : post_hq_delay = NS2SA_FX2( st->output_Fs, POST_HQ_DELAY_NS );
2018 3100 : BREAK;
2019 317379 : case IVAS_SCE:
2020 317379 : post_hq_delay = NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS );
2021 317379 : BREAK;
2022 59692 : case IVAS_CPE_DFT:
2023 59692 : test();
2024 59692 : IF( EQ_16( hCPE->nchan_out, 1 ) && hCPE->hStereoDft->hConfig->res_cod_mode == STEREO_DFT_RES_COD_OFF )
2025 : {
2026 17050 : post_hq_delay = NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS );
2027 : }
2028 : ELSE
2029 : {
2030 42642 : post_hq_delay = 0;
2031 42642 : move16();
2032 : }
2033 59692 : BREAK;
2034 702060 : default:
2035 702060 : post_hq_delay = 0;
2036 702060 : move16();
2037 702060 : BREAK;
2038 : }
2039 :
2040 1082231 : test();
2041 1082231 : test();
2042 1082231 : test();
2043 1082231 : test();
2044 1082231 : test();
2045 1082231 : IF( ( EQ_16( st->codec_mode, MODE1 ) && st->hTcxDec != NULL ) && ( ( ( st->core == ACELP_CORE ) && !( EQ_16( st->bfi, 1 ) && EQ_16( st->con_tcx, 1 ) ) ) || EQ_16( st->core, HQ_CORE ) ) )
2046 : {
2047 173708 : IF( st->element_mode == EVS_MONO )
2048 : {
2049 1850 : Copy( st->hTcxDec->synth_history_fx + output_frame, st->hTcxDec->synth_history_fx, add( sub( output_frame, post_hq_delay ), NS2SA_FX2( st->output_Fs, PH_ECU_MEM_NS ) ) ); /*hTcxDec->q_synth_history_fx*/
2050 1850 : Copy_Scale_sig( synth_fx, st->hTcxDec->old_synthFB_fx + sub( output_frame, post_hq_delay ), output_frame, negate( Qpostd ) ); /* output_sp not initialized yet */
2051 : /* reset the remaining buffer, which is read in TCX concealment the necessary samples to fill
2052 : this buffer are not available for all cases, the impact on the output is limited */
2053 1850 : set16_fx( st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), post_hq_delay ), 0, post_hq_delay );
2054 :
2055 1850 : IF( GE_16( output_frame, L_FRAME16k ) )
2056 : {
2057 1850 : Copy_Scale_sig( st->prev_synth_buffer_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS ) ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), negate( st->Qprev_synth_buffer_fx ) ); /*Q0*/
2058 : }
2059 : /* IVAS Floating point code has the commented-out else branch below, but it does not appear to be necessary. To be verified
2060 : else
2061 : {
2062 : mvr2r( st->hHQ_core->old_out + NS2SA( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB + 2 * output_frame, NS2SA( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) );
2063 : }
2064 : */
2065 :
2066 1850 : IF( st->core != ACELP_CORE )
2067 : {
2068 440 : IF( GE_16( output_frame, L_FRAME16k ) )
2069 : {
2070 440 : Copy_Scale_sig( st->delay_buf_out_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ) ), NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ), negate( Qpostd ) ); /*Q0*/
2071 440 : Copy_Scale_sig( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ), negate( st->hHQ_core->Q_old_wtda ) ); /*Q0*/
2072 : }
2073 : ELSE
2074 : {
2075 :
2076 0 : Copy_Scale_sig( st->delay_buf_out_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS ) ), NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ), negate( Qpostd ) ); /*Q0*/
2077 0 : Copy_Scale_sig( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ), negate( st->hHQ_core->Q_old_wtda ) ); /*Q0*/
2078 : }
2079 : }
2080 : }
2081 : ELSE
2082 : {
2083 171858 : Copy( st->hTcxDec->synth_history_fx + output_frame, st->hTcxDec->synth_history_fx, add( sub( output_frame, post_hq_delay ), NS2SA_FX2( st->output_Fs, PH_ECU_MEM_NS ) ) );
2084 139833298 : FOR( Word16 i = 0; i < output_frame; i++ )
2085 : {
2086 139661440 : st->hTcxDec->old_synthFB_fx[( ( i + output_frame ) - post_hq_delay )] = extract_h( L_shl_sat( output_fx[i], 16 ) ); // Q16
2087 139661440 : move16();
2088 : }
2089 :
2090 171858 : IF( st->core != ACELP_CORE )
2091 : {
2092 7497 : Copy( st->delay_buf_out_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), post_hq_delay ), post_hq_delay );
2093 7497 : Copy( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) );
2094 : }
2095 : }
2096 : }
2097 1082231 : return;
2098 : }
|