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 "prot_fx.h" /* Function prototypes */
7 : #include "rom_com.h" /* Static table prototypes */
8 : #include "rom_dec.h" /* Static table prototypes */
9 : #include "cnst.h" /* Static table prototypes */
10 :
11 : #define Q_GUARD 1
12 : #define Q_32_BITS 14 /* scaling of 't_audio32' */
13 : #define MAKE_PSEUDO_FLT( v, e ) ( ( ( (Word32) ( v ) ) << 16 ) + ( e ) )
14 : /*-----------------------------------------------------------*
15 : * Gain_Dequant_HR()
16 : *
17 : * Returns decoded gain quantized between the specified
18 : * range using the specified number of levels.
19 : *-----------------------------------------------------------*/
20 : /* It would be more efficient (PROM wise) to combine
21 : with gain_dequant_fx(). But for now the 'max' param has
22 : a larger allowed range here (Q13) than in gain_dequant_fx()
23 : where is is in Q15. This applies for the 'min' param too.
24 : Here it is Q6 in gain_dequant_fx() it is Q0. But merging the
25 : two functions would be less efficient (Performance Wise)
26 : since the function here doesn't use 'Log2_norm_lc' at all
27 : versus gain_dequant_fx() which does. */
28 1453 : static Word16 Gain_Dequant_HR( /* o: decoded gain (Q13) */
29 : Word16 index, /* i: quantization index */
30 : const Word16 min, /* i: value of lower limit (Q13) */
31 : const Word16 bits, /* i: number of bits to dequantize */
32 : Word16 *exp /* o: exponent of Decoded Gain */
33 : )
34 : {
35 : Word32 L_mini, L_fact;
36 : Word16 gain;
37 : Word32 L_temp;
38 : Word16 exp1, exp2, p2_frac, p2_int;
39 :
40 1453 : L_mini = 0; /* no complexity counted, just to remove warning */
41 1453 : L_fact = 0; /* no complexity counted, just to remove warning */
42 1453 : move32();
43 1453 : move32();
44 :
45 1453 : IF( EQ_16( min, G_AVQ_MIN_FX ) )
46 : {
47 0 : L_mini = MAKE_PSEUDO_FLT( 26214, 15 ); /* 0.8 in Q15 */
48 0 : move32();
49 0 : L_fact = MAKE_PSEUDO_FLT( 14145, 11 ); /* Log2(96) - Log2(0.8) in Q11 */
50 0 : move32();
51 : }
52 1453 : ELSE IF( EQ_16( min, G_AVQ_MIN_DIV10_FX ) )
53 : {
54 0 : L_mini = MAKE_PSEUDO_FLT( 20972, 18 ); /* 0.8*0.1 in Q18 */
55 0 : move32();
56 0 : L_fact = MAKE_PSEUDO_FLT( 20949, 11 ); /* Log2(96) - Log2(0.8*0.1) in Q11 */
57 0 : move32();
58 : }
59 1453 : ELSE IF( EQ_16( min, G_CODE_MIN_FX ) )
60 : {
61 0 : L_mini = MAKE_PSEUDO_FLT( 20972, 20 ); /* 0.02 in Q20 */
62 0 : move32();
63 0 : L_fact = MAKE_PSEUDO_FLT( 32628, 12 ); /* Log2(5) - Log2(0.02) in Q12 */
64 0 : move32();
65 : }
66 1453 : ELSE IF( EQ_16( min, G_CODE_MIN_TC192_FX ) )
67 : {
68 0 : L_mini = MAKE_PSEUDO_FLT( 19661, 15 ); /* 0.6 in Q15 */
69 0 : move32();
70 0 : L_fact = MAKE_PSEUDO_FLT( 24963, 12 ); /* Log2(41) - Log2(0.6) in Q12 */
71 0 : move32();
72 : }
73 1453 : ELSE IF( EQ_16( min, MIN_GLOB_GAIN_BWE_HR_FX ) )
74 : {
75 1453 : L_mini = MAKE_PSEUDO_FLT( 24576, 13 ); /* 3.0 in Q13 */
76 1453 : move32();
77 1453 : L_fact = MAKE_PSEUDO_FLT( 30232, 12 ); /* Log2(500) - Log2(3) in Q12 */
78 1453 : move32();
79 : }
80 : /* levels = 1<<bits;*/
81 : /* c_min = (float)log10(min);*/
82 : /* c_mult = (float) ((levels-1)/(log10(max)-c_min));*/
83 : /* gain = (float)pow( 10.0, (((float)index)/c_mult) + c_min );*/
84 :
85 1453 : L_temp = L_mult0( extract_h( L_fact ), inv_tbl_2n_minus1[bits] ); // Q12 + Qx
86 1453 : exp1 = norm_s( index );
87 1453 : index = shl( index, exp1 );
88 : /* inv_tbl has variable Q, with Q0 being at [2]*/
89 : /* So 'exp1 = sub(sub(15, extract_l(L_fact)), exp1) - (bits-2)' is written as:*/
90 1453 : exp1 = sub( sub( sub( 15 + 2, extract_l( L_fact ) ), exp1 ), bits );
91 1453 : exp2 = norm_l( L_temp );
92 1453 : L_temp = L_shl( L_temp, exp2 );
93 1453 : exp2 = sub( exp2, exp1 );
94 1453 : L_temp = Mult_32_16( L_temp, index );
95 1453 : L_temp = L_shr( L_temp, exp2 );
96 :
97 1453 : p2_frac = L_Extract_lc( L_temp, &p2_int );
98 1453 : L_temp = Pow2( 30, p2_frac ); /* 30 to get the most bits */
99 1453 : exp1 = sub( 30 - 16 - 15, p2_int );
100 1453 : exp1 = add( exp1, extract_l( L_mini ) );
101 :
102 1453 : gain = round_fx( L_temp ); // exp1
103 :
104 1453 : L_temp = L_mult( gain, extract_h( L_mini ) );
105 1453 : exp2 = norm_l( L_temp );
106 1453 : L_temp = L_shl( L_temp, exp2 );
107 :
108 1453 : gain = round_fx( L_temp );
109 1453 : exp1 = add( exp1, exp2 );
110 :
111 1453 : *exp = exp1; // gain_e
112 1453 : move16();
113 :
114 1453 : return gain;
115 : }
116 :
117 : /*-------------------------------------------------------------------*
118 : * TD_Postprocess()
119 : *
120 : * post processing in time domain for td/fd switching
121 : *-------------------------------------------------------------------*/
122 :
123 10 : static Word16 TD_Postprocess( /* o : gain in Q15 */
124 : Word16 hb_synth_fx[], /* i/o: high-band synthesis Q(15 - hb_synth_fx_exp) */
125 : const Word16 hb_synth_fx_exp, /* i : Q of high-band synthesis */
126 : const Word16 input_frame, /* i : frame length */
127 : const Word16 last_extl /* i : last extension layer */
128 : )
129 : {
130 : Word16 i;
131 : Word16 pos, ind1, ind2;
132 : Word16 max_samp, temp, temp1, temp2, temp3;
133 : Word32 L_Energy, L_Energy2;
134 :
135 10 : max_samp = abs_s( hb_synth_fx[0] );
136 10 : pos = 0;
137 10 : move16();
138 9600 : FOR( i = 1; i < input_frame; i++ )
139 : {
140 9590 : temp = abs_s( hb_synth_fx[i] );
141 9590 : if ( GT_16( temp, max_samp ) )
142 : {
143 306 : pos = i;
144 306 : move16();
145 : }
146 9590 : max_samp = s_max( temp, max_samp );
147 : }
148 :
149 10 : IF( LT_16( pos, 160 ) )
150 : {
151 0 : L_Energy = Calc_Energy_Autoscaled( hb_synth_fx + sub( input_frame, 80 ), hb_synth_fx_exp, 80, &temp1 );
152 : }
153 : ELSE
154 : {
155 10 : L_Energy = Calc_Energy_Autoscaled( hb_synth_fx, hb_synth_fx_exp, 80, &temp1 );
156 : }
157 :
158 10 : ind1 = s_max( 0, sub( pos, 40 ) );
159 10 : ind2 = s_min( input_frame, add( pos, 40 ) );
160 10 : temp3 = sub( ind2, ind1 );
161 :
162 10 : L_Energy2 = Calc_Energy_Autoscaled( hb_synth_fx + ind1, hb_synth_fx_exp, temp3, &temp2 );
163 :
164 : /* Float Code: "gain_flt = min( 1.0f, 1.0f/sqrt( 80*tmpF/(gain_flt*temp) ) )"
165 : * Multiply by 80 (eq to Mult by 1.25 and 64)
166 : * So Div by 2 to avoid overflow
167 : * Add 1/8
168 : * Adjust Exponent (-1 for Dib by2, -6 for Missing Mult by 64
169 : */
170 10 : L_Energy2 = L_add( L_shr( L_Energy2, 1 ), L_shr( L_Energy2, 3 ) );
171 10 : temp2 = sub( temp2, 1 + 6 );
172 :
173 : /* Normalize 'temp3' */
174 10 : temp = norm_s( temp3 );
175 10 : temp3 = shl( temp3, temp );
176 : /* Adjust Exponent of Energy #1 */
177 10 : temp1 = add( temp1, temp );
178 : /* Mult by 'temp3' */
179 10 : L_Energy = Mult_32_16( L_Energy, temp3 );
180 10 : L_Energy = L_max( L_Energy, 1 );
181 :
182 10 : temp1 = sub( temp1, 15 ); /* because of Mpy_32_16_1 */
183 :
184 10 : L_Energy = Sqrt_Ratio32( L_Energy, temp1, L_Energy2, temp2, &temp );
185 :
186 : /* Put Back to Q31 (Let it saturate to 0.99999 in fx because we wanted to limit the gain to 1.0 anyways) */
187 10 : L_Energy = L_shl_sat( L_Energy, temp );
188 10 : temp = round_fx_sat( L_Energy );
189 :
190 10 : test();
191 10 : IF( EQ_16( last_extl, SWB_BWE ) || EQ_16( last_extl, FB_BWE ) )
192 : {
193 0 : FOR( i = ind1; i < input_frame; i++ )
194 : {
195 0 : hb_synth_fx[i] = mult_r( temp, hb_synth_fx[i] );
196 0 : move16();
197 : }
198 : }
199 : ELSE
200 : {
201 810 : FOR( i = ind1; i < ind2; i++ )
202 : {
203 800 : hb_synth_fx[i] = mult_r( temp, hb_synth_fx[i] );
204 800 : move16();
205 : }
206 :
207 10 : IF( NE_16( ind2, input_frame ) )
208 : {
209 : /* alpha_flt = (gain_flt > 0.5f) ? 1.0f : 0.5f;*/
210 : /* beta_flt = (alpha_flt - gain_flt)/sub(input_frame, ind2);*/
211 10 : temp2 = sub( 16384, temp );
212 10 : if ( temp2 < 0 )
213 0 : temp2 = add( temp2, 16384 );
214 10 : temp3 = sub( input_frame, ind2 );
215 : /* Inverse 'temp3' */
216 10 : temp1 = norm_s( temp3 );
217 10 : temp3 = shl( temp3, temp1 );
218 10 : temp3 = div_s( 16384, temp3 );
219 10 : L_Energy2 = L_mult0( temp2, temp3 );
220 10 : temp1 = add( temp1, 1 ); /* because we used 0.5 (16384) to inverse and not 1.0 (32768) */
221 : /* Back to Q31 */
222 10 : L_Energy2 = L_shr( L_Energy2, temp1 );
223 :
224 3380 : FOR( i = ind2; i < input_frame; i++ )
225 : {
226 3370 : hb_synth_fx[i] = mult_r_sat( round_fx_sat( L_Energy ), hb_synth_fx[i] );
227 3370 : move16();
228 3370 : L_Energy = L_add_sat( L_Energy, L_Energy2 );
229 : }
230 : }
231 : }
232 :
233 10 : return temp; /* in Q15 */
234 : }
235 :
236 : /*-------------------------------------------------------------------*
237 : * swb_bwe_dec_hr_fx()
238 : *
239 : * HR SWB BWE decoder
240 : *-------------------------------------------------------------------*/
241 :
242 669 : Word16 swb_bwe_dec_hr_fx( /* o : Exponent of SHB synthesis */
243 : Decoder_State *st_fx, /* i/o: decoder state structure */
244 : const Word16 *syn_12k8_16k_fx, /* i : ACELP core synthesis @16kHz : Q(15 - exp) */
245 : const Word16 exp, /* i : Exponent of core synthesis */
246 : Word16 *hb_synth_fx, /* o : SHB synthesis : Q(15 - hb_synth_fx_exp)*/
247 : const Word16 output_frame, /* i : frame length */
248 : const Word16 unbits, /* i : number of core unused bits */
249 : const Word16 pitch_buf[] /* i : pitch buffer : Q6 */
250 : )
251 : {
252 : Word16 i, j, k, nBits, nBits_total, nBits_block, Nsv, Nsv2, width_noncoded;
253 : Word16 is_transient, tmpS, incr, IsTransient, pos;
254 : Word16 x_norm[NSV_MAX * ( WIDTH_BAND + 1 )], x_norm1[NSV_MAX * ( WIDTH_BAND + 1 )];
255 : Word32 t_audio32_tmp[L_FRAME48k];
256 : Word32 t_audio32[L_FRAME48k];
257 : Word16 t_audio_exp;
258 : Word16 en_band[N_BANDS_BWE_HR];
259 : Word16 ind1, ind2;
260 : Word32 L_EnergyLT, L_Energy;
261 : Word16 nq[NSV_MAX], nq2[NSV_MAX], nq_tmp[NSV_MAX];
262 : Word16 alpha;
263 : Word16 temp, temp2, temp3, temp4;
264 : Word16 en_noncoded, min_env, max_env;
265 669 : Word16 gain_fx = 0, gain2_fx, exp1, exp2;
266 669 : move16();
267 : Word16 len;
268 : Word16 pitch;
269 : Word32 L_temp, L_temp2;
270 : Word32 L_tilt_wb;
271 : Word16 hb_synth_fx_exp;
272 : Word16 *ptr16;
273 : Word32 *ptr32;
274 : Word32 L_ener_all, L_ener_saved;
275 : Word16 ener_all_exp, ener_saved_exp;
276 : Word16 *t_audio, *t_audio_tmp;
277 669 : Word16 env = 0;
278 669 : move16();
279 : Word16 exp_L, inv_L, frac;
280 : FD_BWE_DEC_HANDLE hBWE_FD;
281 : HR_BWE_DEC_HANDLE hBWE_FD_HR;
282 :
283 669 : hBWE_FD = st_fx->hBWE_FD;
284 669 : hBWE_FD_HR = st_fx->hBWE_FD_HR;
285 :
286 : /* Use 't_audio32_tmp' Word32 Buffer as two Word16 Buffers to save local Stack. */
287 : /* There is no possible overlap so it is ok */
288 669 : t_audio = (Word16 *) &t_audio32_tmp[0];
289 669 : t_audio_tmp = (Word16 *) &t_audio32_tmp[L_FRAME48k / 2];
290 :
291 669 : hBWE_FD_HR->bwe_highrate_seed_fx = extract_l( L_mult0( pitch_buf[0], pitch_buf[3] ) );
292 669 : move16();
293 :
294 :
295 : /*---------------------------------------------------------------------*
296 : * initializations
297 : *---------------------------------------------------------------------*/
298 :
299 669 : set16_fx( t_audio, 0, output_frame );
300 669 : set32_fx( t_audio32, 0, output_frame );
301 669 : exp2 = 0;
302 669 : move16();
303 669 : Nsv2 = 0;
304 669 : move16();
305 : /* only to suppress warnings (no complexity counted) */
306 669 : gain2_fx = 0;
307 669 : move16();
308 669 : ind2 = 0;
309 669 : move16();
310 669 : L_ener_saved = 0;
311 669 : move32();
312 669 : ener_saved_exp = 0;
313 669 : move16();
314 :
315 : /* reset memories in case that last frame was a different technology */
316 669 : test();
317 669 : IF( EQ_16( st_fx->last_core, HQ_CORE ) || NE_16( st_fx->last_extl, st_fx->extl ) )
318 : {
319 11 : set16_fx( hBWE_FD->L_old_wtda_swb_fx, 0, L_FRAME48k );
320 11 : st_fx->hHQ_core->Q_old_wtda = 14;
321 11 : move16();
322 : }
323 :
324 : /* calculate SWB BWE bit-budget */
325 : /* nBits = st->extl_brate/50 + unbits */
326 669 : nBits = add( 320, unbits ); /* st->extl_brate_fx is always 16kbps */
327 669 : nBits_total = nBits;
328 669 : move16();
329 :
330 : /*---------------------------------------------------------------------*
331 : * calculate tilt of the core synthesis
332 : *---------------------------------------------------------------------*/
333 669 : L_tilt_wb = calc_tilt_bwe_fx( syn_12k8_16k_fx, exp, L_FRAME16k );
334 669 : L_temp = L_mac( 1, 8192, pitch_buf[0] );
335 2676 : FOR( i = 1; i < NB_SUBFR16k - 1; i++ )
336 : {
337 2007 : L_temp = L_mac( L_temp, 8192, pitch_buf[i] );
338 : }
339 669 : pitch = mac_r( L_temp, 8192, pitch_buf[i] );
340 : /* pitch now in Q4 (Q6 div by 4) */
341 :
342 : /*---------------------------------------------------------------------*
343 : * FEC, or good frame decoding
344 : *---------------------------------------------------------------------*/
345 :
346 669 : IF( st_fx->bfi )
347 : {
348 0 : is_transient = hBWE_FD_HR->old_is_transient_hr_bwe_fx;
349 0 : move16();
350 :
351 : /* Replication of the last spectrum, with an attenuation */
352 0 : test();
353 0 : test();
354 0 : IF( ( EQ_16( st_fx->clas_dec, VOICED_CLAS ) || EQ_16( st_fx->clas_dec, INACTIVE_CLAS ) ) && LE_16( st_fx->nbLostCmpt, 3 ) )
355 : {
356 0 : alpha = 26214; /* 0.80 */
357 0 : move16();
358 0 : t_audio_exp = 0;
359 0 : move16();
360 : }
361 0 : ELSE IF( is_transient )
362 : {
363 0 : alpha = 19661 /* 0.15 */;
364 0 : move16();
365 0 : t_audio_exp = 2;
366 0 : move16();
367 : }
368 : ELSE
369 : {
370 0 : alpha = 19661 /* 0.30 */;
371 0 : move16();
372 0 : t_audio_exp = 1;
373 0 : move16();
374 : }
375 :
376 0 : IF( is_transient )
377 : {
378 : /* output_frame == L_FRAME48k */
379 0 : tmpS = ( 2 * END_FREQ_BWE_FULL_FB / 50 ) / NUM_TIME_SWITCHING_BLOCKS - NUM_TRANS_START_FREQ_COEF;
380 0 : move16();
381 : /* set BWE spectrum length */
382 0 : if ( EQ_16( output_frame, L_FRAME32k ) )
383 : {
384 0 : tmpS = L_FRAME32k / NUM_TIME_SWITCHING_BLOCKS - NUM_TRANS_START_FREQ_COEF;
385 0 : move16();
386 : }
387 :
388 0 : temp = shr( output_frame, 2 );
389 0 : pos = NUM_TRANS_START_FREQ_COEF;
390 0 : move16();
391 0 : ind1 = 0;
392 0 : move16();
393 : /* reconstruct */
394 0 : len = 0;
395 0 : move16();
396 : /* Here t_audio was initialy filled with zeros */
397 : /* So, after the loop, the Q will be 'Q_32_Bits' */
398 0 : FOR( k = 0; k < NUM_TIME_SWITCHING_BLOCKS; k++ )
399 : {
400 0 : temp4 = sub( hBWE_FD_HR->t_audio_prev_fx_exp[k], Q_32_BITS );
401 0 : temp4 = add( temp4, t_audio_exp );
402 0 : FOR( i = 0; i < tmpS; i++ )
403 : {
404 0 : L_temp = L_mult( alpha, hBWE_FD_HR->t_audio_prev_fx[i + ind1] );
405 0 : L_temp = L_shr( L_temp, temp4 );
406 0 : t_audio32[pos + i] = L_temp;
407 0 : move32();
408 : }
409 0 : ind1 = add( ind1, tmpS );
410 0 : pos = add( pos, temp );
411 : }
412 : /* Save transform coefficients for the next frame (needed in case of frame erasures) */
413 0 : FOR( k = 0; k < NUM_TIME_SWITCHING_BLOCKS; k++ )
414 : {
415 0 : temp = add( NUM_TRANS_START_FREQ_COEF, len );
416 0 : temp4 = Find_Max_Norm32( t_audio32 + temp, tmpS );
417 0 : Copy_Scale_sig32_16( t_audio32 + temp, hBWE_FD_HR->t_audio_prev_fx + i_mult2( k, tmpS ), tmpS, temp4 );
418 0 : hBWE_FD_HR->t_audio_prev_fx_exp[k] = add( Q_32_BITS, temp4 );
419 0 : move16();
420 0 : len = add( len, shr( output_frame, 2 ) );
421 : }
422 : }
423 : ELSE
424 : {
425 : /* output_frame == L_FRAME48k */
426 0 : tmpS = 2 * END_FREQ_BWE_FULL_FB / 50 - NUM_NONTRANS_START_FREQ_COEF;
427 0 : move16();
428 : /* set BWE spectrum length */
429 0 : if ( EQ_16( output_frame, L_FRAME32k ) )
430 : {
431 0 : tmpS = L_FRAME32k - NUM_NONTRANS_START_FREQ_COEF;
432 0 : move16();
433 : }
434 :
435 : /* reconstruct */
436 : /* Here t_audio was initialy filled with zeros */
437 : /* So, after the loop, the Q will be 'Q_32_Bits' */
438 0 : temp4 = sub( hBWE_FD_HR->t_audio_prev_fx_exp[0], Q_32_BITS );
439 0 : temp4 = add( temp4, t_audio_exp );
440 0 : ptr32 = &t_audio32[NUM_NONTRANS_START_FREQ_COEF];
441 0 : FOR( i = 0; i < tmpS; i++ )
442 : {
443 0 : L_temp = L_mult( alpha, hBWE_FD_HR->t_audio_prev_fx[i] );
444 0 : L_temp = L_shr( L_temp, temp4 );
445 0 : *ptr32++ = L_temp;
446 0 : move32();
447 : }
448 : /* Save transform coefficients for the next frame (needed in case of frame erasures) */
449 0 : temp = NUM_NONTRANS_START_FREQ_COEF;
450 0 : move16(); /* not necessary but improves readability and allows a larger common code path */
451 0 : temp4 = Find_Max_Norm32( t_audio32 + temp, tmpS );
452 0 : Copy_Scale_sig32_16( t_audio32 + temp, hBWE_FD_HR->t_audio_prev_fx, tmpS, temp4 );
453 0 : hBWE_FD_HR->t_audio_prev_fx_exp[0] = add( Q_32_BITS, temp4 );
454 0 : move16();
455 : }
456 :
457 0 : hBWE_FD_HR->L_mem_EnergyLT_fx = Mul_flt32_Q15( hBWE_FD_HR->L_mem_EnergyLT_fx, &hBWE_FD_HR->mem_EnergyLT_fx_exp, alpha );
458 0 : move32();
459 0 : hBWE_FD_HR->mem_EnergyLT_fx_exp = add( hBWE_FD_HR->mem_EnergyLT_fx_exp, t_audio_exp );
460 0 : move16();
461 :
462 : /* Set Exponent */
463 0 : t_audio_exp = Q_32_BITS;
464 0 : move16();
465 0 : exp_L = norm_s( output_frame );
466 0 : inv_L = div_s( shl( 1, sub( 14, exp_L ) ), output_frame ); /*Q(29-exp_L)*/
467 :
468 : /*Q(st_fx->mem_EnergyLT_fx_exp+29-exp_L-15) -> Q(st_fx->mem_EnergyLT_fx_exp-exp_L+14)*/
469 0 : hBWE_FD_HR->L_mem_EnergyLT_fx = Mul_flt32_Q15( hBWE_FD_HR->L_mem_EnergyLT_fx, &hBWE_FD_HR->mem_EnergyLT_fx_exp, inv_L );
470 0 : move32();
471 0 : IF( hBWE_FD_HR->L_mem_EnergyLT_fx != 0 )
472 : {
473 0 : exp1 = norm_l( hBWE_FD_HR->L_mem_EnergyLT_fx );
474 0 : frac = extract_h( L_shl( hBWE_FD_HR->L_mem_EnergyLT_fx, exp1 ) );
475 0 : exp1 = sub( exp1, sub( 16, sub( hBWE_FD_HR->mem_EnergyLT_fx_exp, exp_L ) ) );
476 :
477 0 : temp = div_s( 16384, frac );
478 0 : L_temp = L_deposit_h( temp );
479 0 : L_temp = Isqrt_lc( L_temp, &exp1 );
480 0 : gain_fx = extract_l( L_shl_sat( L_temp, sub( exp1, 2 ) ) ); /*Q(31-exp + (exp-3)) -> Q13*/
481 : }
482 :
483 0 : env = 512;
484 0 : move16();
485 : }
486 : ELSE
487 : {
488 : /*---------------------------------------------------------------------*
489 : * get transient frame flag
490 : *---------------------------------------------------------------------*/
491 :
492 669 : is_transient = (Word16) get_next_indice_fx( st_fx, 1 );
493 :
494 669 : IF( is_transient )
495 : {
496 64 : nBits = -1;
497 64 : move16(); /* is_transient flag */
498 64 : nBits_block = shr( nBits_total, 2 );
499 64 : nBits = add( nBits, s_and( nBits_total, 3 ) );
500 :
501 : /* set width of noncoded (blind estimated) spectrum */
502 64 : test();
503 64 : IF( EQ_16( st_fx->extl, SWB_BWE_HIGHRATE ) || EQ_16( output_frame, L_FRAME32k ) )
504 : {
505 64 : width_noncoded = L_FRAME32k / NUM_TIME_SWITCHING_BLOCKS - NUM_TRANS_END_FREQ_COEF;
506 64 : move16();
507 64 : tmpS = L_FRAME32k / NUM_TIME_SWITCHING_BLOCKS - NUM_TRANS_END_FREQ_COEF_EFF;
508 64 : move16();
509 : }
510 : ELSE /* st->extl == FB_BWE_HIGHRATE */
511 : {
512 0 : width_noncoded = ( 2 * END_FREQ_BWE_FULL_FB / 50 ) / NUM_TIME_SWITCHING_BLOCKS - NUM_TRANS_END_FREQ_COEF;
513 0 : move16();
514 0 : tmpS = ( 2 * END_FREQ_BWE_FULL_FB / 50 ) / NUM_TIME_SWITCHING_BLOCKS - NUM_TRANS_END_FREQ_COEF_EFF;
515 0 : move16();
516 : }
517 :
518 : /*---------------------------------------------------------------------*
519 : * transient frames: processing in blocks (subframes)
520 : *---------------------------------------------------------------------*/
521 64 : len = 0;
522 64 : move16();
523 320 : FOR( k = 0; k < NUM_TIME_SWITCHING_BLOCKS; k++ )
524 : {
525 256 : nBits = add( nBits, nBits_block );
526 :
527 : /*---------------------------------------------------------------------*
528 : * global gain and envelope decoding
529 : *---------------------------------------------------------------------*/
530 :
531 : /* get global gain */
532 256 : ind1 = (Word16) get_next_indice_fx( st_fx, NBITS_GLOB_GAIN_BWE_HR );
533 256 : gain_fx = Gain_Dequant_HR( ind1, MIN_GLOB_GAIN_BWE_HR_FX, NBITS_GLOB_GAIN_BWE_HR, &exp1 );
534 256 : nBits = sub( nBits, NBITS_GLOB_GAIN_BWE_HR );
535 :
536 : /* get energy per band */
537 256 : IF( k == 0 )
538 : {
539 64 : ind1 = (Word16) get_next_indice_fx( st_fx, NBITS_ENVELOPE_BWE_HR_TR );
540 64 : ind2 = ind1;
541 64 : move16();
542 64 : nBits = sub( nBits, NBITS_ENVELOPE_BWE_HR_TR );
543 : }
544 : ELSE
545 : {
546 192 : ind1 = (Word16) get_next_indice_fx( st_fx, NBITS_ENVELOPE_BWE_HR_TR - 1 );
547 192 : if ( GE_16( ind2, 8 ) )
548 : {
549 150 : ind1 = add( ind1, NUM_ENVLOPE_CODE_HR_TR2 );
550 : }
551 192 : nBits = sub( nBits, NBITS_ENVELOPE_BWE_HR_TR - 1 );
552 : }
553 :
554 256 : temp = shl( ind1, 1 );
555 256 : en_band[0] = swb_hr_env_code3_fx[temp];
556 256 : move16();
557 256 : en_band[1] = swb_hr_env_code3_fx[temp + 1];
558 256 : move16();
559 :
560 : /*env = add(shr(en_band[0], 1), shr(en_band[1], 1));*/
561 256 : env = mac_r( L_mult( en_band[0], 16384 ), en_band[1], 16384 );
562 :
563 : /*---------------------------------------------------------------------*
564 : * estimate energy of noncoded spectrum (14.4-20kHz)
565 : *---------------------------------------------------------------------*/
566 :
567 256 : en_noncoded = en_band[N_BANDS_TRANS_BWE_HR - 1];
568 256 : move16();
569 :
570 256 : IF( EQ_16( st_fx->extl, FB_BWE_HIGHRATE ) )
571 : {
572 0 : ind1 = (Word16) get_next_indice_fx( st_fx, NBITS_HF_GAIN_BWE_HR );
573 0 : nBits = sub( nBits, NBITS_HF_GAIN_BWE_HR );
574 :
575 0 : IF( EQ_16( ind1, 1 ) )
576 : {
577 0 : en_noncoded = round_fx( L_mult0( en_noncoded, BWE_HR_TRANS_EN_LIMIT1_FX_Q16 ) ); // Q9
578 : }
579 :
580 0 : IF( EQ_16( ind1, 2 ) )
581 : {
582 0 : en_noncoded = round_fx( L_mult0( en_noncoded, BWE_HR_TRANS_EN_LIMIT2_FX_Q16 ) ); // Q9
583 : }
584 :
585 0 : IF( EQ_16( ind1, 3 ) )
586 : {
587 0 : en_noncoded = round_fx( L_mult0( en_noncoded, BWE_HR_TRANS_EN_LIMIT3_FX_Q16 ) ); // Q9
588 : }
589 : }
590 :
591 : /*---------------------------------------------------------------------*
592 : * AVQ decoding (dequantize normalized spectrum)
593 : *---------------------------------------------------------------------*/
594 :
595 256 : Nsv = ( NUM_TRANS_END_FREQ_COEF - NUM_TRANS_START_FREQ_COEF ) / WIDTH_BAND;
596 256 : move16();
597 256 : AVQ_demuxdec_fx( st_fx, x_norm, &nBits, Nsv, nq, 0, sub( Nsv, 1 ) );
598 256 : temp = add( len, NUM_TRANS_START_FREQ_COEF );
599 : /* 't_audio' in Q8 */
600 256 : t_audio_exp = 8;
601 256 : move16();
602 16640 : FOR( i = 0; i < i_mult( Nsv, WIDTH_BAND ); i++ )
603 : {
604 16384 : t_audio[temp + i] = shl( x_norm[i], t_audio_exp );
605 16384 : move16();
606 : }
607 :
608 : /* apply noise-fill */
609 256 : swb_hr_noise_fill_fx( is_transient, NUM_TRANS_START_FREQ_COEF, NUM_TRANS_END_FREQ_COEF, round_fx_sat( L_shl_sat( L_tilt_wb, 3 ) ), /* Q(24+3-16) -> Q11 */
610 256 : pitch, nq, Nsv, &hBWE_FD_HR->bwe_highrate_seed_fx, t_audio + temp, t_audio_exp );
611 : /* Go from Q't_audio_exp' on 16 Bits to 'Q_32_BITS' on 32 bits */
612 256 : temp2 = i_mult2( WIDTH_BAND, Nsv );
613 256 : ptr16 = &t_audio[temp];
614 256 : ptr32 = &t_audio32[temp];
615 256 : j = shl( 1, sub( Q_32_BITS, t_audio_exp ) );
616 16640 : FOR( i = 0; i < temp2; i++ )
617 : {
618 : /* put in 'Q_32_BITS' in a 32 Bits */
619 16384 : L_temp = L_mult0( *ptr16++, j );
620 16384 : *ptr32++ = L_temp;
621 16384 : move32();
622 : }
623 :
624 : /*---------------------------------------------------------------------*
625 : * reconstruction
626 : *---------------------------------------------------------------------*/
627 :
628 256 : temp = add( temp, NUM_TRANS_END_FREQ_COEF_EFF - NUM_TRANS_START_FREQ_COEF );
629 256 : pos = sub( temp, tmpS );
630 256 : ptr32 = &t_audio32[temp];
631 : /* reconstruct 14-16(20) kHz spectrum */
632 5376 : FOR( j = 0; j < tmpS; j++ )
633 : {
634 5120 : *ptr32++ = L_shr( t_audio32[pos + j], 1 );
635 5120 : move32();
636 : }
637 :
638 256 : temp = i_mult2( shr( output_frame, 2 ), k );
639 :
640 256 : temp2 = add( NUM_TRANS_START_FREQ_COEF, temp );
641 256 : ptr32 = &t_audio32[temp2];
642 : /* envelope denormalization */
643 768 : FOR( i = 0; i < N_BANDS_TRANS_BWE_HR; i++ )
644 : {
645 17920 : FOR( j = 0; j < WIDTH_TRANS_FREQ_COEF; j++ )
646 : {
647 17408 : L_temp = Mult_32_16( *ptr32, en_band[i] );
648 17408 : L_temp = L_shl( L_temp, 6 ); /* by 6 because 'en_band' is in Q9 */
649 17408 : *ptr32++ = L_temp;
650 17408 : move32();
651 : }
652 : }
653 :
654 256 : temp2 = add( NUM_TRANS_END_FREQ_COEF_EFF, temp );
655 256 : j = sub( tmpS, width_noncoded );
656 256 : ptr16 = &t_audio[temp2 + j];
657 256 : ptr32 = &t_audio32[temp2 + j];
658 : /* envelope denormalization of 14.4-16(20) kHz spectrum */
659 4352 : FOR( ; j < tmpS; j++ )
660 : {
661 4096 : L_temp = Mult_32_16( *ptr32, en_noncoded );
662 4096 : L_temp = L_shl( L_temp, 6 ); /* by 6 because 'en_noncoded' is in Q9 */
663 4096 : *ptr32++ = L_temp;
664 4096 : move32();
665 : }
666 :
667 256 : temp2 = add( NUM_TRANS_START_FREQ_COEF, temp );
668 256 : ptr16 = &t_audio[temp2];
669 256 : ptr32 = &t_audio32[temp2];
670 256 : temp4 = NSV_OVERLAP * ( WIDTH_BAND >> 2 );
671 : /* overlap region */
672 256 : IF( EQ_16( output_frame, L_FRAME48k ) )
673 : {
674 1280 : FOR( i = 0; i < temp4; i++ )
675 : {
676 1024 : L_temp = Mult_32_16( *ptr32, overlap_coefs_48kHz_fx[i * 4] ); /* overlap_coefs_fx in Q15 */
677 1024 : *ptr32++ = L_temp;
678 1024 : move32();
679 : }
680 : }
681 : ELSE
682 : {
683 0 : FOR( i = 0; i < temp4; i++ )
684 : {
685 0 : L_temp = Mult_32_16( *ptr32, overlap_coefs_fx[i * 4] ); /* overlap_coefs_fx in Q15 */
686 0 : *ptr32++ = L_temp;
687 0 : move32();
688 : }
689 : }
690 :
691 256 : temp2 = add( NUM_TRANS_START_FREQ_COEF, temp );
692 256 : ptr16 = &t_audio[temp2];
693 256 : ptr32 = &t_audio32[temp2];
694 256 : temp4 = add( WIDTH_TRANS_FREQ_COEF * N_BANDS_TRANS_BWE_HR, width_noncoded );
695 256 : temp3 = sub( 15, exp1 );
696 : /* apply global gain */
697 21760 : FOR( i = 0; i < temp4; i++ )
698 : {
699 21504 : L_temp = Mult_32_16( *ptr32, gain_fx );
700 21504 : L_temp = L_shl( L_temp, temp3 );
701 21504 : *ptr32++ = L_temp;
702 21504 : move32();
703 : }
704 :
705 : /* save transform coefficients for the next frame (needed in case of frame erasures) */
706 256 : temp = add( NUM_TRANS_START_FREQ_COEF, len );
707 256 : IF( EQ_16( output_frame, L_FRAME32k ) )
708 : {
709 0 : pos = L_FRAME32k / NUM_TIME_SWITCHING_BLOCKS - NUM_TRANS_START_FREQ_COEF;
710 0 : move16();
711 : }
712 : ELSE /* output_frame == L_FRAME48k */
713 : {
714 256 : pos = ( 2 * END_FREQ_BWE_FULL_FB / 50 ) / NUM_TIME_SWITCHING_BLOCKS - NUM_TRANS_START_FREQ_COEF;
715 256 : move16();
716 : }
717 256 : temp4 = Find_Max_Norm32( t_audio32 + temp, pos );
718 256 : Copy_Scale_sig32_16( t_audio32 + temp, hBWE_FD_HR->t_audio_prev_fx + i_mult2( k, pos ), pos, temp4 );
719 256 : hBWE_FD_HR->t_audio_prev_fx_exp[k] = add( Q_32_BITS, temp4 );
720 256 : move16();
721 256 : len = add( len, shr( output_frame, 2 ) );
722 :
723 : /* attenuate HFs in case of band-width switching */
724 256 : IF( st_fx->bws_cnt1 > 0 )
725 : {
726 0 : temp = shr( output_frame, 2 );
727 0 : temp = i_mult( k, temp );
728 0 : temp = add( NUM_TRANS_START_FREQ_COEF, temp );
729 0 : temp2 = i_mult( st_fx->bws_cnt1, 1638 ); /*Q15*/
730 :
731 0 : j = ( 2 * END_FREQ_BWE_FULL_FB / 50 ) / NUM_TIME_SWITCHING_BLOCKS - NUM_TRANS_START_FREQ_COEF;
732 0 : move16();
733 0 : if ( EQ_16( output_frame, L_FRAME32k ) )
734 : {
735 0 : j = L_FRAME32k / NUM_TIME_SWITCHING_BLOCKS - NUM_TRANS_START_FREQ_COEF;
736 0 : move16();
737 : }
738 :
739 0 : FOR( i = 0; i < j; i++ )
740 : {
741 0 : t_audio[temp + i] = mult_r( t_audio[temp + i], temp2 );
742 0 : move16();
743 : }
744 : }
745 : }
746 : }
747 : ELSE /* !is_transient */
748 : {
749 : /* subtract one bit for is_transient flag */
750 605 : nBits = sub( nBits, 1 );
751 :
752 : /*---------------------------------------------------------------------*
753 : * global gain and envelope decoding
754 : *---------------------------------------------------------------------*/
755 :
756 : /* get global gain */
757 605 : ind1 = (Word16) get_next_indice_fx( st_fx, NBITS_GLOB_GAIN_BWE_HR );
758 605 : gain_fx = Gain_Dequant_HR( ind1, MIN_GLOB_GAIN_BWE_HR_FX, NBITS_GLOB_GAIN_BWE_HR, &exp1 );
759 :
760 : /* get energy per band */
761 605 : ind1 = (Word16) get_next_indice_fx( st_fx, NBITS_ENVELOPE_BWE_HR1 );
762 605 : ind2 = (Word16) get_next_indice_fx( st_fx, NBITS_ENVELOPE_BWE_HR2 );
763 :
764 605 : temp = shl( ind1, 1 );
765 605 : en_band[0] = swb_hr_env_code1_fx[temp]; // Q9
766 605 : move16();
767 605 : en_band[1] = swb_hr_env_code1_fx[temp + 1]; // Q9
768 605 : move16();
769 605 : temp = shl( ind2, 1 );
770 605 : en_band[2] = swb_hr_env_code2_fx[temp]; // Q9
771 605 : move16();
772 605 : en_band[3] = swb_hr_env_code2_fx[temp + 1]; // Q9
773 605 : move16();
774 :
775 : /*env = add(add(shr(en_band[0], 2), shr(en_band[1], 2)), add(shr(en_band[2], 2), shr(en_band[3], 2)));*/
776 605 : env = mac_r( L_mac( L_mac( L_mult( en_band[0] /*Q9*/, 8192 /*0.25 in Q15*/ ) /*Q23*/, en_band[1], 8192 ), en_band[2], 8192 ), en_band[3], 8192 ); // Q23
777 :
778 : /*---------------------------------------------------------------------*
779 : * choose sub-bands to be dequantized
780 : *---------------------------------------------------------------------*/
781 :
782 : /* find the subband with the min envelope */
783 605 : pos = 0;
784 605 : move16();
785 605 : min_env = en_band[0];
786 605 : move16();
787 605 : max_env = en_band[0];
788 605 : move16();
789 2420 : FOR( j = 1; j < N_BANDS_BWE_HR; j++ )
790 : {
791 1815 : if ( LT_16( en_band[j], min_env ) )
792 : {
793 1385 : pos = j;
794 1385 : move16();
795 : }
796 1815 : min_env = s_min( min_env, en_band[j] );
797 1815 : max_env = s_max( max_env, en_band[j] );
798 : }
799 :
800 : /* decide the spectrum to be dequantized */
801 605 : i = NUM_NONTRANS_END_FREQ_COEF - NUM_NONTRANS_START_FREQ_COEF;
802 605 : move16();
803 605 : IF( LE_16( nBits_total, NBITS_THRESH_BWE_HR ) )
804 : {
805 605 : i = sub( NUM_NONTRANS_END_FREQ_COEF - NUM_NONTRANS_START_FREQ_COEF - 64, shl( s_and( pos, 1 ), 3 ) );
806 : }
807 :
808 605 : nBits = sub( nBits, NBITS_GLOB_GAIN_BWE_HR + NBITS_ENVELOPE_BWE_HR1 + NBITS_ENVELOPE_BWE_HR2 );
809 :
810 : /*---------------------------------------------------------------------*
811 : * estimate energy of noncoded spectrum (14.4-20kHz)
812 : *---------------------------------------------------------------------*/
813 :
814 605 : en_noncoded = mult_r( min_env, 16384 );
815 :
816 605 : IF( EQ_16( st_fx->extl, FB_BWE_HIGHRATE ) )
817 : {
818 0 : ind1 = (Word16) get_next_indice_fx( st_fx, NBITS_HF_GAIN_BWE_HR );
819 0 : nBits = sub( nBits, NBITS_HF_GAIN_BWE_HR );
820 :
821 0 : if ( EQ_16( ind1, 1 ) )
822 : {
823 : /* en_noncoded = BWE_HR_NONTRANS_EN_LIMIT1*(0.5*min_env) ==> 0.25*min_env */
824 0 : en_noncoded = mult_r( min_env, BWE_HR_NONTRANS_EN_LIMIT2_FX_Q15 / 2 ); // Q9
825 : }
826 :
827 0 : IF( EQ_16( ind1, 2 ) )
828 : {
829 : /* en_noncoded = 2.0*BWE_HR_NONTRANS_EN_LIMIT2*(0.5*min_env) ==> 1.2*min_env */
830 0 : en_noncoded = round_fx( L_shl( L_mult( BWE_HR_NONTRANS_EN_LIMIT2_FX_Q14, min_env ), 1 ) ); // Q9
831 : }
832 :
833 0 : if ( EQ_16( ind1, 3 ) )
834 : {
835 : /* en_noncoded = 2.0*BWE_HR_NONTRANS_EN_LIMIT3*(0.5*min_env) ==> 0.8*min_env */
836 0 : en_noncoded = mult_r( BWE_HR_NONTRANS_EN_LIMIT3_FX_Q15, min_env ); // Q9
837 : }
838 : }
839 :
840 : /*---------------------------------------------------------------------*
841 : * AVQ decoding (dequantize normalized spectrum)
842 : *---------------------------------------------------------------------*/
843 :
844 : /* Nsv = i / WIDTH_BAND */
845 605 : Nsv = shr( i, 3 );
846 605 : AVQ_demuxdec_fx( st_fx, x_norm, &nBits, Nsv, nq, 0, sub( Nsv, 1 ) );
847 : /*---------------------------------------------------------------------*
848 : * second stage decoding
849 : *---------------------------------------------------------------------*/
850 :
851 605 : test();
852 605 : IF( GE_16( nBits, 9 + NBITS_GLOB_GAIN_BWE_HR ) && sum16_fx( nq, Nsv ) > 0 )
853 : {
854 592 : ind1 = (Word16) get_next_indice_fx( st_fx, NBITS_GLOB_GAIN_BWE_HR );
855 592 : gain2_fx = Gain_Dequant_HR( ind1, MIN_GLOB_GAIN_BWE_HR_FX, NBITS_GLOB_GAIN_BWE_HR, &exp2 );
856 : /* gain2_flt *= 0.0625f */
857 592 : exp2 = add( exp2, 4 );
858 :
859 : /* calculate the number of subbands according to the rest bits */
860 592 : IF( GT_16( nBits, 396 ) )
861 : {
862 0 : Nsv2 = 33;
863 0 : move16();
864 : }
865 : ELSE
866 : {
867 : /* Here what is acheived is an integer divide by 12 with truncation. */
868 : /* nBits/12 */
869 592 : Nsv2 = mult( nBits, 2731 );
870 : /* But, we have imprecision of the fraction so correction is necessary. */
871 : /* We crosscheck if 'Nsv2' is either too high or too low. */
872 : /* Finally, the result must satisfy: */
873 : /* Nsv2 * 12 <= nBits (Nsv2 is not too high) AND */
874 : /* nBits - Nsv2 * 12 < 12 (Nsv2 is the highest divisor) */
875 592 : L_temp = L_msu0( L_deposit_l( nBits ), 12, Nsv2 );
876 592 : if ( GE_32( L_temp, 12 ) )
877 0 : Nsv2 = add( Nsv2, 1 );
878 592 : if ( L_temp < 0 )
879 0 : Nsv2 = sub( Nsv2, 1 );
880 : }
881 :
882 592 : nBits = sub( nBits, NBITS_GLOB_GAIN_BWE_HR );
883 592 : AVQ_demuxdec_fx( st_fx, x_norm1, &nBits, Nsv2, nq2, 0, sub( Nsv2, 1 ) );
884 : }
885 :
886 : /*---------------------------------------------------------------------*
887 : * dequantization
888 : *---------------------------------------------------------------------*/
889 :
890 : /* set 't_audio' exp */
891 605 : t_audio_exp = 10;
892 605 : move16();
893 122197 : FOR( i = 0; i < i_mult( Nsv, WIDTH_BAND ); i++ )
894 : {
895 121592 : t_audio_tmp[i] = shl_sat( x_norm[i], t_audio_exp );
896 121592 : move16();
897 : }
898 :
899 605 : Copy( nq, nq_tmp, Nsv );
900 605 : IF( GT_16( Nsv2, Nsv ) )
901 : {
902 : /* Safety check, happens rarely */
903 0 : set16_fx( nq_tmp + Nsv, 0, sub( Nsv2, Nsv ) );
904 : }
905 :
906 605 : incr = 0;
907 605 : move16();
908 605 : ptr16 = x_norm1;
909 605 : temp2 = sub( sub( exp2, 15 ), t_audio_exp ); /* go to Q't_audio' */
910 15804 : FOR( i = 0; i < Nsv; i++ )
911 : {
912 15199 : test();
913 15199 : IF( nq[i] == 0 && LT_16( incr, Nsv2 ) )
914 : {
915 2395 : temp = shl( i, 3 );
916 21555 : FOR( j = 0; j < WIDTH_BAND; j++ )
917 : {
918 19160 : L_temp = L_mult( gain2_fx, *ptr16++ );
919 19160 : L_temp = L_shr( L_temp, temp2 ); /* go to Q't_audio' */
920 19160 : t_audio_tmp[temp + j] = round_fx( L_temp );
921 : }
922 : /* 'nq[i] = add(nq[i], nq2[incr])' replaced by 'nq[i] = nq2[incr]' because 'nq[i] == 0' */
923 2395 : nq[i] = nq2[incr];
924 2395 : move16();
925 2395 : incr = add( incr, 1 );
926 : }
927 : }
928 :
929 605 : temp3 = shl( -32768, temp2 );
930 855 : FOR( i = 0; incr < Nsv2; i++ )
931 : {
932 : /* safety check, happens rarely */
933 250 : IF( GE_16( i, Nsv2 ) )
934 : {
935 0 : BREAK;
936 : }
937 :
938 250 : IF( nq_tmp[i] != 0 )
939 : {
940 234 : temp = shl( i, 3 );
941 2106 : FOR( j = 0; j < WIDTH_BAND; j++ )
942 : {
943 1872 : L_temp = L_mult( gain2_fx, *ptr16++ );
944 1872 : L_temp = L_msu( L_temp, t_audio_tmp[temp + j], temp3 ); /* go to -Q't_audio' */
945 1872 : L_temp = L_shr( L_temp, temp2 ); /* go to Q't_audio' */
946 1872 : t_audio_tmp[temp + j] = round_fx( L_temp );
947 : }
948 234 : nq[i] = add( nq[i], nq2[incr] );
949 234 : move16();
950 234 : incr = add( incr, 1 );
951 : }
952 : }
953 :
954 : /*---------------------------------------------------------------------*
955 : * reorder the decoded spectrum
956 : *---------------------------------------------------------------------*/
957 :
958 605 : ptr16 = t_audio + NUM_NONTRANS_START_FREQ_COEF;
959 :
960 605 : IF( GT_16( nBits_total, NBITS_THRESH_BWE_HR ) )
961 : {
962 0 : Copy( t_audio_tmp, ptr16, NUM_NONTRANS_END_FREQ_COEF - NUM_NONTRANS_START_FREQ_COEF );
963 : /* Update Maximum Written Location (from t_audio + NUM_NONTRANS_START_FREQ_COEF) */
964 0 : temp4 = NUM_NONTRANS_END_FREQ_COEF - NUM_NONTRANS_START_FREQ_COEF;
965 0 : move16();
966 : }
967 : ELSE
968 : {
969 605 : ind1 = add( shl( pos, 6 ), i_mult2( shr( pos, 1 ), WIDTH_BAND ) );
970 605 : Copy( t_audio_tmp, ptr16, ind1 );
971 :
972 : /* Update Maximum Written Location (from t_audio + NUM_NONTRANS_START_FREQ_COEF) */
973 605 : temp4 = ind1;
974 605 : move16();
975 :
976 605 : temp = add( pos, 1 );
977 605 : ind2 = add( shl( temp, 6 ), i_mult2( shr( temp, 1 ), WIDTH_BAND ) );
978 605 : Copy( t_audio_tmp + ind1, ptr16 + ind2, sub( NUM_NONTRANS_END_FREQ_COEF - NUM_NONTRANS_START_FREQ_COEF, ind2 ) );
979 : /* Update Maximum Written Location (from t_audio + NUM_NONTRANS_START_FREQ_COEF) */
980 605 : temp4 = s_max( temp4, NUM_NONTRANS_END_FREQ_COEF - NUM_NONTRANS_START_FREQ_COEF );
981 605 : move16();
982 :
983 : /* reconstruct non-encoded subband */
984 605 : IF( EQ_16( pos, 3 ) )
985 : {
986 476 : Copy( t_audio + NUM_NONTRANS_START_FREQ_COEF + 128, ptr16 + 200, 72 );
987 : /* Update Maximum Written Location (from t_audio + NUM_NONTRANS_START_FREQ_COEF) */
988 476 : temp4 = s_max( temp4, 200 + 72 );
989 :
990 476 : Copy( nq + 16, nq + 25, 9 );
991 : }
992 : ELSE
993 : {
994 129 : pos = s_and( pos, 1 );
995 129 : temp3 = add( 64, shl( pos, 3 ) );
996 129 : Copy( ptr16 + ind2, ptr16 + ind1, temp3 );
997 : /* Update Maximum Written Location (from t_audio + NUM_NONTRANS_START_FREQ_COEF) */
998 129 : temp4 = s_max( temp4, add( ind1, temp3 ) );
999 :
1000 129 : ind1 = shr( ind1, 3 );
1001 129 : ind2 = shr( ind2, 3 );
1002 :
1003 129 : j = 33;
1004 129 : move16();
1005 1866 : FOR( i = sub( Nsv, 1 ); i >= ind1; i-- )
1006 : {
1007 1737 : nq[j] = nq[i];
1008 1737 : move16();
1009 1737 : j = sub( j, 1 );
1010 : }
1011 :
1012 129 : Copy( nq + ind2, nq + ind1, add( WIDTH_BAND, pos ) );
1013 : }
1014 : }
1015 :
1016 : /* apply noise-fill */
1017 605 : IF( LT_16( nBits, 200 ) )
1018 : {
1019 605 : swb_hr_noise_fill_fx( is_transient, NUM_NONTRANS_START_FREQ_COEF, NUM_NONTRANS_END_FREQ_COEF,
1020 605 : round_fx_sat( L_shl_sat( L_tilt_wb, 3 ) ), /* Q(24+3-16) -> Q11 */
1021 : pitch, nq, Nsv, &hBWE_FD_HR->bwe_highrate_seed_fx, t_audio + NUM_NONTRANS_START_FREQ_COEF, t_audio_exp );
1022 : }
1023 :
1024 : /* Go from Q't_audio_exp' on 16 Bits to Q16 on 32 bits */
1025 605 : ptr32 = &t_audio32[NUM_NONTRANS_START_FREQ_COEF];
1026 605 : j = shl( 1, sub( Q_32_BITS, t_audio_exp ) );
1027 165165 : FOR( i = 0; i < temp4; i++ )
1028 : {
1029 : /* put in 'Q_32_BITS' in a 32 Bits */
1030 164560 : L_temp = L_mult0( *ptr16++, j );
1031 164560 : *ptr32++ = L_temp;
1032 164560 : move32();
1033 : }
1034 :
1035 : /*---------------------------------------------------------------------*
1036 : * reconstruction
1037 : *---------------------------------------------------------------------*/
1038 :
1039 : /* smoothing 12.6-12.8kHz */
1040 605 : test();
1041 605 : IF( EQ_16( pos, 3 ) && LE_16( nBits_total, 400 ) )
1042 : {
1043 476 : ptr16 = &t_audio[NUM_NONTRANS_START_FREQ_COEF + 200 - WIDTH_BAND];
1044 476 : L_temp = L_mac0( 1 /* EPSILON */, *ptr16, *ptr16 );
1045 3808 : FOR( i = 1; i < WIDTH_BAND; i++ )
1046 : {
1047 3332 : ptr16++;
1048 3332 : L_temp = L_mac0( L_temp, *ptr16, *ptr16 );
1049 : }
1050 476 : ptr16++;
1051 476 : L_temp2 = L_mac0( 1 /* EPSILON */, *ptr16, *ptr16 );
1052 3808 : FOR( i = 1; i < WIDTH_BAND; i++ )
1053 : {
1054 3332 : ptr16++;
1055 3332 : L_temp2 = L_mac0( L_temp2, *ptr16, *ptr16 );
1056 : }
1057 476 : L_temp = Sqrt_Ratio32( L_temp, 0, L_temp2, 0, &temp );
1058 :
1059 : /* if 'temp' is < 0 then it is req to shift right before substracting 1.0 */
1060 476 : temp2 = s_min( 0, temp );
1061 476 : L_temp = L_shl( L_temp, temp2 );
1062 : /* Energy_flt - i*(Energy_flt-1.0)/8.0 */
1063 476 : L_temp2 = L_add( L_temp, L_shr( -2147483647 - 1, s_max( 0, temp ) ) ); /* 1.0 in same Q as Sqrt minus the Guard */
1064 : /* / 8.0 */
1065 476 : L_temp2 = L_shr( L_temp2, 3 + Q_GUARD );
1066 : /* Add Guard */
1067 476 : L_temp = L_shr( L_temp, Q_GUARD );
1068 : /* Set Index */
1069 476 : ptr16 = &t_audio[NUM_NONTRANS_START_FREQ_COEF + 200];
1070 476 : ptr32 = &t_audio32[NUM_NONTRANS_START_FREQ_COEF + 200];
1071 : /* Set Exponent (relative to t_audio_exp (from 16 bits vector) */
1072 476 : temp2 = add( sub( temp, temp2 ), sub( Q_GUARD - ( 16 - Q_32_BITS ), t_audio_exp ) );
1073 :
1074 4284 : FOR( i = 0; i < WIDTH_BAND; i++ )
1075 : {
1076 3808 : *ptr32++ = L_shl( Mult_32_16( L_temp, *ptr16++ ), temp2 );
1077 3808 : move32();
1078 :
1079 3808 : L_temp = L_sub( L_temp, L_temp2 );
1080 : }
1081 : }
1082 :
1083 : /* reconstruct 14.4-16(20) kHz spectrum */
1084 605 : width_noncoded = 2 * END_FREQ_BWE_FULL_FB / 50 - NUM_NONTRANS_END_FREQ_COEF;
1085 605 : move16(); /* st->extl == FB_BWE_HIGHRATE */
1086 605 : test();
1087 605 : IF( EQ_16( st_fx->extl, SWB_BWE_HIGHRATE ) || EQ_16( output_frame, L_FRAME32k ) )
1088 : {
1089 605 : width_noncoded = L_FRAME32k - NUM_NONTRANS_END_FREQ_COEF;
1090 605 : move16();
1091 : }
1092 :
1093 605 : ptr16 = &t_audio[NUM_NONTRANS_END_FREQ_COEF - WIDTH_BAND];
1094 605 : L_temp = L_mac0( 1 /* EPSILON */, *ptr16, *ptr16 );
1095 4840 : FOR( i = 1; i < WIDTH_BAND; i++ )
1096 : {
1097 4235 : ptr16++;
1098 4235 : L_temp = L_mac0( L_temp, *ptr16, *ptr16 );
1099 : }
1100 :
1101 605 : ptr16 = &t_audio[NUM_NONTRANS_END_FREQ_COEF - width_noncoded];
1102 605 : L_temp2 = L_mac0( 1 /* EPSILON */, *ptr16, *ptr16 );
1103 4840 : FOR( i = 1; i < WIDTH_BAND; i++ )
1104 : {
1105 4235 : ptr16++;
1106 4235 : L_temp2 = L_mac0( L_temp2, *ptr16, *ptr16 );
1107 : }
1108 605 : L_temp = Sqrt_Ratio32( L_temp, 0, L_temp2, 0, &temp );
1109 :
1110 : /* So part of the copy can be skipped because the loop that follows */
1111 : /* will take the values from t_audio (16 bits) */
1112 : /* Since 'width_noncoded' is always > WIDTH_BAND, we can substract it from the length */
1113 : /* and adjust the offset accordingly */
1114 605 : Copy32( t_audio32 + sub( NUM_NONTRANS_END_FREQ_COEF + WIDTH_BAND, width_noncoded ),
1115 605 : t_audio32 + NUM_NONTRANS_END_FREQ_COEF + WIDTH_BAND, sub( width_noncoded, WIDTH_BAND ) );
1116 :
1117 : /* smoothing 14.4-14.8kHz */
1118 605 : ptr16 = &t_audio[NUM_NONTRANS_END_FREQ_COEF - width_noncoded];
1119 605 : ptr32 = &t_audio32[NUM_NONTRANS_END_FREQ_COEF];
1120 605 : temp = sub( temp, add( t_audio_exp, 16 - Q_32_BITS ) );
1121 5445 : FOR( i = 0; i < WIDTH_BAND; i++ )
1122 : {
1123 4840 : L_temp2 = Mult_32_16( L_temp, *ptr16++ );
1124 4840 : L_temp2 = L_shl( L_temp2, temp );
1125 4840 : *ptr32++ = L_temp2;
1126 4840 : move32();
1127 : }
1128 :
1129 : /* envelope denormalization */
1130 605 : ptr32 = &t_audio32[NUM_NONTRANS_START_FREQ_COEF];
1131 3025 : FOR( i = 0; i < N_BANDS_BWE_HR; i++ )
1132 : {
1133 166980 : FOR( j = 0; j < WIDTH_NONTRANS_FREQ_COEF; j++ )
1134 : {
1135 164560 : L_temp = Mult_32_16( *ptr32, en_band[i] );
1136 164560 : L_temp = L_shl( L_temp, 6 ); /* Because 'en_band' is in Q9 */
1137 164560 : *ptr32++ = L_temp;
1138 164560 : move32();
1139 : }
1140 2420 : temp = add( temp, WIDTH_NONTRANS_FREQ_COEF );
1141 : }
1142 :
1143 : /* equalize 14.4-16(20) kHz spectrum */
1144 : /* tmpF = max_env / min_env; */
1145 605 : temp = BASOP_Util_Divide1616_Scale( max_env, min_env, &temp2 );
1146 605 : test();
1147 605 : IF( EQ_16( st_fx->extl, SWB_BWE_HIGHRATE ) || LT_16( temp, shl_sat( 18022, sub( 15 - 13, temp2 ) ) ) ) /* 2.2 in Q13 == 18022 */
1148 : {
1149 :
1150 : /* (en_band_flt[3] - j*(en_band_flt[3]/WIDTH_BAND - en_noncoded_flt/WIDTH_BAND)) */
1151 605 : L_temp = L_deposit_h( en_band[3] );
1152 605 : L_temp2 = L_mult( sub( en_band[3], en_noncoded ), 32768 / WIDTH_BAND );
1153 605 : ptr32 = &t_audio32[NUM_NONTRANS_END_FREQ_COEF];
1154 : /* in L_temp/L_temp2, value in Q16+9 */
1155 5445 : FOR( j = 0; j < WIDTH_BAND; j++ )
1156 : {
1157 4840 : *ptr32 = L_shl( Mult_32_16( *ptr32, round_fx( L_temp ) ), ( 15 - 9 ) );
1158 4840 : move32();
1159 4840 : ptr32++;
1160 4840 : L_temp = L_sub( L_temp, L_temp2 );
1161 : }
1162 :
1163 605 : ptr32 = &t_audio32[NUM_NONTRANS_END_FREQ_COEF + WIDTH_BAND];
1164 34485 : FOR( j = WIDTH_BAND; j < width_noncoded; j++ )
1165 : {
1166 33880 : L_temp = Mult_32_16( *ptr32, en_noncoded );
1167 33880 : L_temp = L_shl( L_temp, 6 ); /* Because 'en_noncoded' is in Q9 */
1168 33880 : *ptr32++ = L_temp;
1169 33880 : move32();
1170 : }
1171 : }
1172 : ELSE
1173 : {
1174 0 : tmpS = L_FRAME32k - NUM_NONTRANS_END_FREQ_COEF;
1175 0 : move16();
1176 0 : if ( EQ_16( output_frame, L_FRAME48k ) )
1177 : {
1178 0 : tmpS = sub( width_noncoded, 2 * WIDTH_NONTRANS_FREQ_COEF );
1179 : }
1180 :
1181 0 : ptr32 = &t_audio32[NUM_NONTRANS_END_FREQ_COEF];
1182 0 : L_temp = L_mult( 18022 /* 2.2 in Q13*/, en_noncoded ); /* Q13 * Q9 -> Q23 */
1183 0 : L_temp2 = Mult_32_16( L_temp, 32768 / 160 ); /* step */
1184 0 : FOR( j = 0; j < tmpS; j++ )
1185 : {
1186 : /* t_audio[NUM_NONTRANS_END_FREQ_COEF + j] *= 2.2f * en_noncoded * (1-(float)k/(float)160); */
1187 0 : *ptr32 = L_shl( Mult_32_16( *ptr32, round_fx( L_temp ) ), ( 31 - 23 ) );
1188 0 : move32();
1189 0 : ptr32++;
1190 0 : L_temp = L_sub( L_temp, L_temp2 );
1191 : }
1192 :
1193 0 : L_temp = L_mult( 21299 /* 0.65 in Q15*/, en_noncoded ); /* Q15 * Q9 -> Q25 */
1194 0 : L_temp2 = Mult_32_16( L_temp, 32768 / 320 ); /* step */
1195 0 : FOR( ; j < width_noncoded; j++ )
1196 : {
1197 : /* t_audio[NUM_NONTRANS_END_FREQ_COEF + j] *= 0.65f * en_noncoded * (1-(float)k/(float)320); */
1198 0 : *ptr32 = L_shl( Mult_32_16( *ptr32, round_fx( L_temp ) ), ( 31 - 25 ) );
1199 0 : move32();
1200 0 : ptr32++;
1201 0 : L_temp = L_sub( L_temp, L_temp2 );
1202 : }
1203 : }
1204 :
1205 : /* Overlap region */
1206 605 : ptr32 = &t_audio32[NUM_NONTRANS_START_FREQ_COEF];
1207 605 : IF( EQ_16( output_frame, L_FRAME48k ) )
1208 : {
1209 10285 : FOR( i = 0; i < NSV_OVERLAP * WIDTH_BAND; i++ )
1210 : {
1211 9680 : L_temp = Mult_32_16( *ptr32, overlap_coefs_48kHz_fx[i] );
1212 9680 : *ptr32++ = L_temp;
1213 9680 : move32();
1214 : }
1215 : }
1216 : ELSE
1217 : {
1218 0 : FOR( i = 0; i < NSV_OVERLAP * WIDTH_BAND; i++ )
1219 : {
1220 0 : L_temp = Mult_32_16( *ptr32, overlap_coefs_fx[i] );
1221 0 : *ptr32++ = L_temp;
1222 0 : move32();
1223 : }
1224 : }
1225 :
1226 : /* Apply global gain */
1227 605 : if ( LE_16( nBits_total, NBITS_THRESH_BWE_HR ) )
1228 : {
1229 605 : gain_fx = mult_r( 27853, gain_fx ); /* 0.85 in exp_0 */
1230 : // gain_e
1231 : }
1232 :
1233 605 : ptr32 = &t_audio32[NUM_NONTRANS_START_FREQ_COEF];
1234 605 : temp = sub( 15, exp1 ); /* From Exponent of 'gain_fx' in Q'exp1' to Q15 */
1235 605 : temp2 = add( WIDTH_NONTRANS_FREQ_COEF * N_BANDS_BWE_HR, width_noncoded );
1236 203885 : FOR( i = 0; i < temp2; i++ )
1237 : {
1238 203280 : L_temp = Mult_32_16( *ptr32, gain_fx );
1239 203280 : L_temp = L_shl_sat( L_temp, temp );
1240 203280 : *ptr32++ = L_temp;
1241 203280 : move32();
1242 : }
1243 :
1244 : /* Save transform coefficients for the next frame (needed in case of frame erasures) */
1245 605 : temp = NUM_NONTRANS_START_FREQ_COEF;
1246 605 : move16(); /* not necessary but improves readability and allows a larger common code path */
1247 605 : IF( EQ_16( output_frame, L_FRAME32k ) )
1248 : {
1249 0 : pos = L_FRAME32k - NUM_NONTRANS_START_FREQ_COEF;
1250 0 : move16();
1251 : }
1252 : ELSE /* output_frame == L_FRAME48k */
1253 : {
1254 605 : pos = 2 * END_FREQ_BWE_FULL_FB / 50 - NUM_NONTRANS_START_FREQ_COEF;
1255 605 : move16();
1256 : }
1257 605 : temp4 = Find_Max_Norm32( t_audio32 + temp, pos );
1258 605 : Copy_Scale_sig32_16( t_audio32 + temp, hBWE_FD_HR->t_audio_prev_fx, pos, temp4 );
1259 605 : hBWE_FD_HR->t_audio_prev_fx_exp[0] = add( Q_32_BITS, temp4 );
1260 605 : move16();
1261 :
1262 : /* attenuate HFs in case of band-width switching */
1263 605 : IF( st_fx->bws_cnt1 > 0 )
1264 : {
1265 0 : temp = i_mult( st_fx->bws_cnt1, 1638 ); /*Q15*/
1266 :
1267 0 : j = 2 * END_FREQ_BWE_FULL_FB / 50 - NUM_NONTRANS_START_FREQ_COEF;
1268 0 : move16();
1269 0 : if ( EQ_16( output_frame, L_FRAME32k ) )
1270 : {
1271 0 : j = L_FRAME32k - NUM_NONTRANS_START_FREQ_COEF;
1272 0 : move16();
1273 : }
1274 :
1275 0 : FOR( i = 0; i < j; i++ )
1276 : {
1277 0 : t_audio[NUM_NONTRANS_START_FREQ_COEF + i] = mult_r( t_audio[NUM_NONTRANS_START_FREQ_COEF + i], temp );
1278 0 : move16();
1279 : }
1280 : }
1281 : }
1282 : }
1283 :
1284 669 : IF( gain_fx < 0 )
1285 : {
1286 0 : st_fx->prev_ener_shb_fx = extract_h( L_shr( L_mult0( 32767, env ), 7 ) );
1287 0 : move16();
1288 : }
1289 : ELSE
1290 : {
1291 669 : st_fx->prev_ener_shb_fx = extract_h( L_shr( L_mult0( gain_fx, env ) /*gain_e + (31 - Q23)*/, 7 ) ); /*gain_e + 15*/
1292 669 : move16();
1293 : }
1294 10035 : FOR( i = 0; i < SWB_FENV; i++ )
1295 : {
1296 9366 : st_fx->hBWE_FD->prev_SWB_fenv_fx[i] = st_fx->prev_ener_shb_fx; /*gain_e + 15*/
1297 9366 : move16();
1298 : }
1299 :
1300 : /*---------------------------------------------------------------------*
1301 : * iOLA and iMDCT
1302 : *---------------------------------------------------------------------*/
1303 :
1304 669 : t_audio_exp = Q_32_BITS;
1305 669 : move16();
1306 :
1307 669 : Inverse_Transform( t_audio32, &t_audio_exp, t_audio32_tmp, is_transient, output_frame, output_frame, st_fx->element_mode );
1308 669 : window_ola_fx( t_audio32_tmp, hb_synth_fx, &t_audio_exp, hBWE_FD->L_old_wtda_swb_fx, &st_fx->hHQ_core->Q_old_wtda, output_frame, ALDO_WINDOW, ALDO_WINDOW, 0, 0, 0 );
1309 669 : hb_synth_fx_exp = t_audio_exp;
1310 669 : move16();
1311 :
1312 : /*---------------------------------------------------------------------*
1313 : * final adjustments
1314 : *---------------------------------------------------------------------*/
1315 :
1316 669 : IF( !st_fx->bfi )
1317 : {
1318 669 : IsTransient = 0;
1319 669 : move16();
1320 669 : L_EnergyLT = L_add( hBWE_FD_HR->L_mem_EnergyLT_fx, 0 );
1321 669 : temp4 = hBWE_FD_HR->mem_EnergyLT_fx_exp;
1322 669 : move16();
1323 669 : pos = 0;
1324 669 : move16();
1325 :
1326 669 : ptr16 = hb_synth_fx;
1327 :
1328 669 : len = shr( output_frame, 2 ); /* Divide Frame Len by 4, all (160, 320, 640, 960) are divisible by 4 */
1329 669 : L_ener_all = L_deposit_l( 0 );
1330 669 : ener_all_exp = 40;
1331 669 : move16(); /* set to a high exponent */
1332 :
1333 3345 : FOR( j = 0; j < 4; j++ )
1334 : {
1335 2676 : L_Energy = Calc_Energy_Autoscaled( ptr16, hb_synth_fx_exp, len, &temp2 );
1336 2676 : ptr16 += len;
1337 : /* Normalize Energy */
1338 2676 : temp = norm_l( L_Energy );
1339 2676 : L_Energy = L_shl( L_Energy, temp );
1340 : /* Update Exponent of 'L_Energy' */
1341 2676 : temp2 = add( temp2, temp );
1342 :
1343 : /* Normalize Long Term Energy */
1344 2676 : temp = norm_l( L_EnergyLT );
1345 2676 : L_EnergyLT = L_shl( L_EnergyLT, temp );
1346 : /* Calculate Exponent of Long Term Energy */
1347 2676 : temp = add( temp, temp4 );
1348 :
1349 : /* Divide by 12.5 */
1350 2676 : L_temp = Mult_32_16( L_Energy, 20972 ); /* 20972 = 1/12.5*32768*8 (*8 to boost precision) */
1351 2676 : temp3 = norm_l( L_temp );
1352 2676 : L_temp = L_shl( L_temp, temp3 );
1353 2676 : temp3 = add( add( temp2, temp3 ), 3 );
1354 : /* Energies are Strictly Positive Values and Normalized
1355 : (compare exponent and value only if exponent is same) */
1356 : /* Replaces: 'if (Energy_flt > 12.5f * EnergyLT_flt )' */
1357 2676 : temp3 = sub( temp3, temp );
1358 2676 : test();
1359 2676 : test();
1360 2676 : IF( temp3 < 0 || ( GT_32( L_temp, L_EnergyLT ) && temp3 == 0 ) )
1361 : {
1362 28 : IsTransient = 1;
1363 28 : move16();
1364 28 : pos = j;
1365 28 : move16();
1366 28 : L_ener_saved = L_add( L_ener_all, 0 );
1367 28 : ener_saved_exp = ener_all_exp;
1368 28 : move16();
1369 : }
1370 :
1371 2676 : L_ener_all = Add_flt32_flt32( L_Energy, temp2, L_ener_all, ener_all_exp, &ener_all_exp );
1372 : /* 0.25f*Energy_flt */
1373 2676 : temp2 = add( temp2, 2 );
1374 : /* 0.75f*EnergyLT_flt */
1375 2676 : L_EnergyLT = L_sub( L_EnergyLT, L_shr( L_EnergyLT, 2 ) );
1376 : /* Exponent of 'L_EnergyLT' is 'temp' */
1377 : /* Exponent of 'L_Energy' is 'temp2' */
1378 : /* EnergyLT = 0.75f*EnergyLT + 0.25f*Energy */
1379 2676 : L_EnergyLT = Add_flt32_flt32( L_Energy, temp2, L_EnergyLT, temp, &temp4 );
1380 : }
1381 :
1382 669 : test();
1383 669 : test();
1384 669 : test();
1385 669 : IF( IsTransient != 0 && pos > 0 && LT_32( L_tilt_wb, 50331648 /* (16777216L * 3) */ /*tilt_wb in Q24*/ ) && GT_16( pitch, ( 500 * 16 ) /*Q4*/ ) )
1386 : {
1387 3 : Nsv = i_mult2( pos, shr( output_frame, 2 ) );
1388 :
1389 3 : gain_fx = 16384; /* sqrt(1.0) in Q14 */
1390 3 : move16();
1391 : /* pos is 1,2 or 3 */
1392 3 : temp3 = sub( pos, 2 );
1393 3 : if ( temp3 == 0 )
1394 : {
1395 0 : gain_fx = 23170;
1396 0 : move16(); /* sqrt(2.0) in Q14 */
1397 : }
1398 :
1399 3 : if ( temp3 > 0 )
1400 : {
1401 0 : gain_fx = 28378;
1402 0 : move16(); /* sqrt(3.0) in Q14 */
1403 : }
1404 3 : exp1 = 14;
1405 3 : move16();
1406 :
1407 3 : IF( EQ_16( st_fx->last_extl, st_fx->extl ) )
1408 : {
1409 2 : L_temp = Div_flt32_flt32( L_ener_saved, ener_saved_exp, hBWE_FD_HR->L_mem_EnergyLT_fx, hBWE_FD_HR->mem_EnergyLT_fx_exp, &temp2 );
1410 2 : temp3 = sub( temp2, 1 );
1411 2 : L_temp2 = Isqrt_lc( L_temp, &temp3 );
1412 2 : temp3 = sub( sub( 30 + 31 - 15 + 1, temp2 ), temp3 );
1413 :
1414 2 : L_temp = Mult_32_16( L_temp2, gain_fx );
1415 2 : temp = norm_l( L_temp );
1416 2 : L_temp2 = L_shl( L_temp, temp );
1417 2 : gain_fx = round_fx( L_temp2 );
1418 2 : exp1 = sub( add( temp3, temp ), sub( 31, exp1 ) ); /* gain_fx is in Q14 */
1419 : }
1420 :
1421 3 : L_temp = L_mult0( 26214, gain_fx );
1422 : /* +16: Because 26214 is 0.2 in Q16
1423 : * -16: Because of round_fx
1424 : * -15: To get exponent with ref to Q15
1425 : * +1: Because of L_mult'0'
1426 : * and the normalization
1427 : */
1428 3 : exp2 = add( exp1, 16 - 16 - 15 + 1 );
1429 3 : temp = norm_l( L_temp );
1430 3 : L_temp = L_shl( L_temp, temp );
1431 3 : exp2 = add( exp2, temp );
1432 3 : temp = round_fx( L_temp ); /* Gain is in Q15+x */
1433 723 : FOR( i = 0; i < Nsv; i++ )
1434 : {
1435 720 : L_temp2 = L_mult( temp, hb_synth_fx[i] );
1436 720 : L_temp2 = L_shr( L_temp2, exp2 );
1437 720 : hb_synth_fx[i] = round_fx( L_temp2 );
1438 720 : move16();
1439 : }
1440 :
1441 3 : len = shr( output_frame, 3 ); /* all frame length are divisible by 8 */
1442 : /* This will yield
1443 : 3 for 960, 2 for 640, 1 for 320 & 0 for 160
1444 : This is used as an index into a 1/output_frame table of 4 entries */
1445 3 : temp = mult_r( output_frame, 102 );
1446 :
1447 3 : ptr16 = &hb_synth_fx[Nsv];
1448 : /* gain_flt * gain * 1/frame_len */
1449 3 : L_temp2 = Mult_32_16( L_temp, swb_hr_inv_frm_len[temp] );
1450 : /* Gain in Q30 */
1451 3 : L_temp = L_shr( L_temp, add( exp2, 31 - 30 ) );
1452 : /* Adjust Exponent */
1453 3 : exp2 = add( 30 - 19 - 3 - 3, exp2 ); /* Exp Req to go to Q30 (-19: because 'swb_hr_inv_frm_len' is in Q19) */
1454 : /* Put to Q30 */
1455 3 : L_temp2 = L_shr( L_temp2, exp2 );
1456 : /* 1/frame_len in Q30 */
1457 3 : L_temp2 = L_msu( L_temp2, swb_hr_inv_frm_len[temp], 1024 /*(32768L >> ( 19 - 15 + 1 )*/ ); /* 19-15+1 to Bring to Q30 */
1458 363 : FOR( i = 0; i < len; i++ )
1459 : {
1460 : /* hb_synth[i+Nsv] *= (gain_flt - i*8.0f*(1.0f/output_frame*gain_flt - 1.0f/output_frame)) */
1461 360 : *ptr16 = round_fx( L_shl( Mult_32_16( L_temp, *ptr16 ), 1 ) );
1462 360 : ptr16++;
1463 360 : L_temp = L_sub( L_temp, L_temp2 );
1464 : }
1465 : }
1466 :
1467 669 : hBWE_FD_HR->L_mem_EnergyLT_fx = L_EnergyLT; // exp_temp4
1468 669 : move32();
1469 669 : hBWE_FD_HR->mem_EnergyLT_fx_exp = temp4;
1470 669 : move16();
1471 669 : hBWE_FD_HR->old_is_transient_hr_bwe_fx = is_transient;
1472 669 : move16();
1473 : }
1474 :
1475 : /* post-processing in case of TD/FD switching */
1476 669 : test();
1477 669 : IF( EQ_16( st_fx->last_core, HQ_CORE ) || NE_16( st_fx->last_extl, st_fx->extl ) )
1478 : {
1479 11 : IF( LT_32( L_tilt_wb, 50331648 /* (16777216L * 3) */ /*tilt_wb in Q24*/ ) )
1480 : {
1481 10 : temp = TD_Postprocess( hb_synth_fx, hb_synth_fx_exp, output_frame, st_fx->last_extl );
1482 :
1483 9610 : FOR( i = 0; i < output_frame; i++ )
1484 : {
1485 9600 : hBWE_FD->L_old_wtda_swb_fx[i] = mult_r( hBWE_FD->L_old_wtda_swb_fx[i], temp );
1486 9600 : move16();
1487 : }
1488 :
1489 10 : tmpS = L_FRAME32k - NUM_NONTRANS_START_FREQ_COEF;
1490 10 : move16();
1491 10 : if ( EQ_16( output_frame, L_FRAME48k ) )
1492 : {
1493 10 : tmpS = 2 * END_FREQ_BWE_FULL_FB / 50 - NUM_NONTRANS_START_FREQ_COEF;
1494 10 : move16();
1495 : }
1496 :
1497 4970 : FOR( i = 0; i < tmpS; i++ )
1498 : {
1499 4960 : hBWE_FD_HR->t_audio_prev_fx[i] = mult_r( hBWE_FD_HR->t_audio_prev_fx[i], temp );
1500 4960 : move16();
1501 : }
1502 : }
1503 : }
1504 :
1505 669 : return hb_synth_fx_exp;
1506 : }
1507 :
1508 : /*-------------------------------------------------------------------*
1509 : * hr_bwe_dec_init()
1510 : *
1511 : * Initialize HR BWE state structure at the decoder
1512 : *-------------------------------------------------------------------*/
1513 3 : void hr_bwe_dec_init(
1514 : HR_BWE_DEC_HANDLE hBWE_FD_HR /* i/o: HR BWE data handle */
1515 : )
1516 : {
1517 3 : set16_fx( hBWE_FD_HR->t_audio_prev_fx, 0, 2 * END_FREQ_BWE_FULL_FB / FRAMES_PER_SEC - NUM_NONTRANS_START_FREQ_COEF );
1518 3 : set16_fx( hBWE_FD_HR->t_audio_prev_fx_exp, 0, NUM_TIME_SWITCHING_BLOCKS ); /* one exp per switching block */
1519 3 : hBWE_FD_HR->old_is_transient_hr_bwe_fx = 0;
1520 3 : move16();
1521 3 : hBWE_FD_HR->bwe_highrate_seed_fx = 12345; /*0.75f in Q14*/
1522 3 : move16();
1523 :
1524 3 : hBWE_FD_HR->L_mem_EnergyLT_fx = L_deposit_h( 16384 ); /*1.0f in Q30*/
1525 3 : move32();
1526 3 : hBWE_FD_HR->mem_EnergyLT_fx_exp = 40;
1527 3 : move16(); /* set to a high exponent */
1528 :
1529 3 : return;
1530 : }
|