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