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 <assert.h>
6 : #include "options.h"
7 : #include "cnst.h" /* Common constants */
8 : #include "rom_enc.h" /* Encoder static table prototypes */
9 : #include "rom_com_fx.h" /* Static table prototypes */
10 : #include "rom_com.h" /* Common constants */
11 : #include "prot_fx.h" /* Function prototypes */
12 : #include "prot_fx_enc.h" /* Function prototypes */
13 : #include "basop_util.h" /* Function prototypes */
14 :
15 :
16 : /*-------------------------------------------------------------------*
17 : * Local constants
18 : *-------------------------------------------------------------------*/
19 :
20 : /* Values that Allow to Use Left/Right Shifting instead of Division &
21 : 'and' (&) instead of 'modulo' (%) which is also a costly division. */
22 : #define NUM_TIME_SW_BLKS_SHIFT 2
23 : #define NUM_TIME_SW_BLKS_MASK ( NUM_TIME_SWITCHING_BLOCKS - 1 )
24 : #define WIDTH_BAND_SHIFT 3
25 :
26 : /* Values for Max Scaling of Different Sub Function */
27 : #define DETECT_TRANSIENT_MAX_Q ( 11 + 2 )
28 : #define MAX_Q_NEW_INPUT 8
29 : #define NON_TRANSIENT_RESCALE_Q_GUARD 4
30 : #define TRANSIENT_RESCALE_Q_GUARD 0
31 : #define SPECTRUM_RESCALE_Q_GUARD 1
32 : #define MAX_Q_UPSCALING 6
33 : #define MAX_AVQ_COD_Q_IN 14
34 :
35 : /*-------------------------------------------------------------------*
36 : * en_band_quant_fx()
37 : *
38 : * Quantize the band envelop
39 : *-------------------------------------------------------------------*/
40 :
41 1480 : static Word16 en_band_quant_fx( /* o : quantization index */
42 : Word16 *en_band, /* i/o: (un)quantized envelope value */
43 : const Word16 *env_code, /* i : envelope codebook */
44 : const Word16 N /* i : codebook dimension */
45 : )
46 : {
47 : Word16 i, ind, tmp16;
48 : Word32 L_err, L_maxerr;
49 :
50 1480 : L_maxerr = 2147483647L;
51 1480 : move32();
52 1480 : ind = 0;
53 1480 : move16();
54 :
55 62488 : FOR( i = 0; i < N; i++ )
56 : {
57 : /* This is More Efficient */
58 61008 : tmp16 = sub( en_band[0], env_code[i * 2] );
59 61008 : L_err = L_mult0( tmp16, tmp16 );
60 61008 : tmp16 = sub( en_band[1], env_code[i * 2 + 1] );
61 61008 : L_err = L_mac0( L_err, tmp16, tmp16 );
62 : /* L_err = 0; move32();
63 : FOR (j = 0; j < 2; j++)
64 : {
65 : tmp16 = sub(en_band[j], env_code[i*2+j]);
66 : L_err = L_mac0(L_err, tmp16, tmp16);
67 : } */
68 61008 : if ( LT_32( L_err, L_maxerr ) )
69 : {
70 16935 : ind = i;
71 16935 : move16();
72 : }
73 61008 : L_maxerr = L_min( L_maxerr, L_err );
74 : }
75 :
76 1480 : en_band[0] = env_code[2 * ind];
77 1480 : move16();
78 1480 : en_band[1] = env_code[2 * ind + 1];
79 1480 : move16();
80 :
81 1480 : return ( ind );
82 : }
83 :
84 : /*-------------------------------------------------------------------*
85 : * swb_bwe_enc_hr_fx()
86 : *
87 : * HR SWB BWE encoder
88 : *-------------------------------------------------------------------*/
89 674 : void swb_bwe_enc_hr_fx(
90 : Encoder_State *st_fx, /* i/o: encoder state structure */
91 : Word16 *new_input_fx, /* i : input signal */
92 : Word16 new_input_fx_exp, /* i : Exponent of input signal */
93 : const Word16 input_frame, /* i : frame length */
94 : const Word16 unbits /* i : number of core unused bits */
95 : )
96 : {
97 : Word16 i, j, k, nBits, nBits_total, nBits_block, Nsv, Nsv2, width_noncoded;
98 : Word16 is_transient, pos;
99 : Word16 x_norm_fx[NSV_MAX * ( WIDTH_BAND + 1 )], x_norm1_fx[NSV_MAX * ( WIDTH_BAND + 1 )];
100 : Word32 t_audio32[L_FRAME48k];
101 : Word16 *t_audio_fx, t_audio_fx_exp;
102 : Word16 *t_audio_tmp_fx; /* same exponent as 't_audio_fx' */
103 : Word16 en_band_fx[N_BANDS_BWE_HR]; /* in Q9 */
104 : Word16 gain1_fx, exp1, gain2_fx, exp2;
105 : Word32 L_gain_fx;
106 : Word16 ind1, ind2;
107 : Word16 nq[NSV_MAX], nq2[NSV_MAX];
108 : Word32 L_tmp, L_temp;
109 : Word16 temp, temp2;
110 : Word16 *ptr16;
111 : Word16 min_env_fx;
112 : Word32 L_en_noncoded_fx; /* in Q16 */
113 : Word16 en_noncoded_fx_exp;
114 : Word16 scl;
115 : #if ( N_BANDS_BWE_HR * WIDTH_NONTRANS_FREQ_COEF ) > L_FRAME48k
116 : Word32 L_t_audio_tmp_fx[N_BANDS_BWE_HR * WIDTH_NONTRANS_FREQ_COEF];
117 : #else
118 : Word32 L_t_audio_tmp_fx[L_FRAME48k];
119 : #endif
120 : #ifndef ISSUE_1867_replace_overflow_libenc
121 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
122 : Flag Overflow = 0;
123 : move16();
124 : #endif
125 : #endif
126 674 : FD_BWE_ENC_HANDLE hBWE_FD = st_fx->hBWE_FD;
127 674 : BSTR_ENC_HANDLE hBstr = st_fx->hBstr;
128 :
129 : Word32 *ptr32;
130 :
131 : /*---------------------------------------------------------------------*
132 : * initializations
133 : *---------------------------------------------------------------------*/
134 :
135 : /* Use 32 Bits Buffer to Store Two 16 Bits Vectors in Order to Save Stack Space */
136 674 : t_audio_fx = (Word16 *) &t_audio32[0];
137 674 : t_audio_tmp_fx = (Word16 *) &t_audio32[L_FRAME48k / 2];
138 :
139 674 : ind2 = 0;
140 674 : move16(); /* only to suppress warnings */
141 674 : Nsv2 = 0;
142 674 : move16(); /* only to suppress warnings */
143 674 : L_en_noncoded_fx = 0;
144 674 : move16(); /* only to suppress warnings */
145 674 : en_noncoded_fx_exp = 0;
146 674 : move16(); /* only to suppress warnings */
147 674 : gain2_fx = 0;
148 674 : move16();
149 :
150 : /* reset memories in case that last frame was a different technology */
151 674 : test();
152 674 : IF( EQ_16( st_fx->last_core, HQ_CORE ) || NE_16( st_fx->last_extl, st_fx->extl ) )
153 : {
154 14 : set16_fx( hBWE_FD->L_old_wtda_swb_fx, 0, L_FRAME48k );
155 14 : st_fx->Q_old_wtda = 0;
156 14 : move16();
157 : }
158 :
159 : /* calculate SWB BWE bit-budget (extension layer bit-rate + AVQ unused bits from the core layer) */
160 : /* nBits = st->extl_brate/50 + unbits */
161 674 : assert( SWB_BWE_16k == st_fx->extl_brate );
162 674 : nBits = add( SWB_BWE_16k / 50, unbits ); /* st->extl_brate is always 16kbps */
163 674 : nBits_total = nBits;
164 674 : move16();
165 :
166 : /*---------------------------------------------------------------------*
167 : * detect transient frames
168 : *---------------------------------------------------------------------*/
169 : /* Calc Room for Energy */
170 674 : temp = norm_l( st_fx->EnergyLT_fx );
171 : /* Calc Max Exponent for 'new_input_fx' */
172 674 : temp = shr( temp, 1 );
173 674 : temp = add( temp, st_fx->EnergyLT_fx_exp );
174 674 : temp = sub( temp, new_input_fx_exp );
175 : /* Do not Upscale */
176 674 : temp = s_min( 0, temp );
177 : /* Limit Input to 'Q_DETECT_TRANSIENT_MAX_Q' (to avoid overflow in 'detect_transient_fx' for Energy Loop)*/
178 674 : exp1 = Find_Max_Norm16( new_input_fx, input_frame );
179 674 : exp1 = sub( exp1, 15 - DETECT_TRANSIENT_MAX_Q );
180 : /* Downscale at Least by 'exp1' */
181 674 : temp = s_min( temp, exp1 );
182 : /* Set Exponent of Input */
183 674 : exp1 = add( new_input_fx_exp, temp );
184 :
185 674 : Copy_Scale_sig( new_input_fx, t_audio_fx, input_frame, temp );
186 : /* Bring Energy in 2*Q'exp1' */
187 674 : st_fx->EnergyLT_fx = L_shl( st_fx->EnergyLT_fx, shl( sub( exp1, st_fx->EnergyLT_fx_exp ), 1 ) );
188 674 : move32();
189 :
190 674 : is_transient = detect_transient_fx( t_audio_fx, input_frame, exp1, st_fx );
191 674 : st_fx->EnergyLT_fx_exp = exp1;
192 674 : move16();
193 :
194 674 : push_indice( hBstr, IND_HR_IS_TRANSIENT, is_transient, 1 );
195 :
196 : /*---------------------------------------------------------------------*
197 : * OLA and MDCT
198 : *---------------------------------------------------------------------*/
199 :
200 : /* To Bring Back to Q15 + 'new_input_fx_exp' */
201 : /* Save Exponent of Memory (relative to Q15) */
202 674 : st_fx->Q_old_wtda = new_input_fx_exp;
203 674 : move16();
204 674 : new_input_fx_exp = 0;
205 674 : move16();
206 674 : wtda_fx( new_input_fx, &new_input_fx_exp, L_t_audio_tmp_fx, hBWE_FD->L_old_wtda_swb_fx,
207 : &st_fx->Q_old_wtda, ALDO_WINDOW, ALDO_WINDOW, input_frame );
208 :
209 674 : direct_transform_fx( L_t_audio_tmp_fx, t_audio32, is_transient, input_frame, &new_input_fx_exp, /*st_fx->element_mode*/ EVS_MONO );
210 :
211 : /* Convert to 16 Bits (Calc Shift Required to Stay within MAX_Q_NEW_INPUT) */
212 674 : scl = sub( 16 + MAX_Q_NEW_INPUT, new_input_fx_exp );
213 : /* Possible to Upscale? */
214 674 : IF( scl > 0 )
215 : {
216 : /* Yes */
217 : /* Calc Room to Upscale */
218 674 : t_audio_fx_exp = Find_Max_Norm32( t_audio32, input_frame );
219 : /* Stay within MAX_Q_NEW_INPUT */
220 674 : scl = s_min( t_audio_fx_exp, scl );
221 : }
222 674 : Copy_Scale_sig32_16( t_audio32, t_audio_fx, input_frame, scl );
223 674 : t_audio_fx_exp = add( sub( new_input_fx_exp, 16 ), scl );
224 :
225 674 : IF( is_transient )
226 : {
227 66 : nBits = -1;
228 66 : move16(); /* is_transient flag */
229 : /* 'nBits_block = nBits_total / NUM_TIME_SWITCHING_BLOCKS' */
230 66 : nBits_block = shr( nBits_total, NUM_TIME_SW_BLKS_SHIFT );
231 : /* 'nBits += nBits_total % NUM_TIME_SWITCHING_BLOCKS' */
232 66 : nBits = add( nBits, s_and( nBits_total, NUM_TIME_SW_BLKS_MASK ) );
233 :
234 : /* set width of noncoded (blind estimated) spectrum */
235 66 : IF( EQ_16( st_fx->extl, SWB_BWE_HIGHRATE ) )
236 : {
237 66 : width_noncoded = L_FRAME32k / NUM_TIME_SWITCHING_BLOCKS - NUM_TRANS_END_FREQ_COEF;
238 66 : move16();
239 : }
240 : ELSE /* st->extl == FB_BWE_HIGHRATE */
241 : {
242 0 : width_noncoded = ( 2 * END_FREQ_BWE_FULL_FB / 50 ) / NUM_TIME_SWITCHING_BLOCKS - NUM_TRANS_END_FREQ_COEF;
243 0 : move16();
244 : }
245 :
246 : /* Find Max Scaling on Remaining Frequencies (after frequencies of non interest are zeroed) */
247 66 : temp = shr( input_frame, NUM_TIME_SW_BLKS_SHIFT );
248 66 : scl = 99;
249 66 : move16();
250 66 : ptr16 = &t_audio_fx[NUM_TRANS_START_FREQ_COEF];
251 316 : FOR( k = 0; k < input_frame; k += temp )
252 : {
253 : /* from t_audio_fx[k..NUM_TRANS_START_FREQ_COEF+k-1] will be zeroed out */
254 : /* AND */
255 : /* from t_audio_fx[k+L_FRAME32k/NUM_TIME_SWITCHING_BLOCKS..k+switching_block_length-1] will be zeroed out */
256 : /* Find Max Scaling on Remaining Frequencies */
257 256 : scl = s_min( Find_Max_Norm16( ptr16 + k, L_FRAME32k / NUM_TIME_SWITCHING_BLOCKS - NUM_TRANS_START_FREQ_COEF ), scl );
258 256 : IF( scl == 0 )
259 : {
260 6 : BREAK;
261 : }
262 : }
263 : /* Need to Keep at Least some Guard Bits */
264 66 : scl = s_max( 0, sub( scl, TRANSIENT_RESCALE_Q_GUARD ) );
265 : /* Reduce if 't_audio_fx_exp' is Q14 or more (AVQ Cod overflow with more than Q14 Input) */
266 66 : scl = sub( scl, s_max( 0, sub( add( scl, t_audio_fx_exp ), MAX_AVQ_COD_Q_IN ) ) );
267 : /* Update Exponent of 't_audio_fx' */
268 : /* Here tne Signal is not Upscaled yet and some adjustement to 't_audio_fx_exp' will be used
269 : until the signal is indeed upscaled by 'scl'. That Occurs at the 'normalization with global gain'. */
270 66 : t_audio_fx_exp = add( t_audio_fx_exp, scl );
271 :
272 : /*---------------------------------------------------------------------*
273 : * transient frames: processing in blocks (subframes)
274 : *---------------------------------------------------------------------*/
275 :
276 330 : FOR( k = 0; k < NUM_TIME_SWITCHING_BLOCKS; k++ )
277 : {
278 264 : nBits = add( nBits, nBits_block );
279 :
280 264 : temp = i_mult2( k, shr( input_frame, NUM_TIME_SW_BLKS_SHIFT ) );
281 :
282 : /* Calculate Original Exponent (because the part of the signal that is used
283 : to Calculate the Energy is not yet Scaled) */
284 264 : j = sub( t_audio_fx_exp, scl );
285 :
286 : /* compute energy of noncoded (14.4-20kHz) spectrum */
287 264 : IF( EQ_16( st_fx->extl, FB_BWE_HIGHRATE ) )
288 : {
289 0 : L_tmp = Calc_Energy_Autoscaled( t_audio_fx + add( temp, NUM_TRANS_END_FREQ_COEF ), j, width_noncoded, &temp2 );
290 0 : L_en_noncoded_fx = Sqrt_Ratio32( L_tmp, temp2, L_deposit_l( width_noncoded ), 0, &en_noncoded_fx_exp );
291 0 : en_noncoded_fx_exp = sub( 31, en_noncoded_fx_exp );
292 : }
293 :
294 : /* keep only frequencies in interest */
295 264 : set16_fx( t_audio_fx + temp, 0, NUM_TRANS_START_FREQ_COEF );
296 264 : set16_fx( t_audio_fx + add( temp, L_FRAME32k / NUM_TIME_SWITCHING_BLOCKS ), 0, shr( sub( input_frame, L_FRAME32k ), NUM_TIME_SW_BLKS_SHIFT ) );
297 :
298 : /*---------------------------------------------------------------------*
299 : * global gain coding
300 : *---------------------------------------------------------------------*/
301 :
302 : /* compute and quantize global energy */
303 : /* Original float Code: 'gain = (float)sqrt( gain ) / (WIDTH_TRANS_FREQ_COEF*N_BANDS_TRANS_BWE_HR)' */
304 : /* Put Divisor to Square to Move it Inside the Sqrt */
305 : /* So we can do 'sqrt( gain (WIDTH_TRANS_FREQ_COEF*N_BANDS_TRANS_BWE_HR)^2)' */
306 264 : L_temp = L_mult0( WIDTH_TRANS_FREQ_COEF * N_BANDS_TRANS_BWE_HR, WIDTH_TRANS_FREQ_COEF * N_BANDS_TRANS_BWE_HR );
307 264 : L_tmp = Calc_Energy_Autoscaled( t_audio_fx + add( temp, NUM_TRANS_START_FREQ_COEF ), j, WIDTH_TRANS_FREQ_COEF * N_BANDS_TRANS_BWE_HR, &temp2 );
308 264 : L_tmp = Sqrt_Ratio32( L_tmp, temp2, L_temp, /*L_temp is in Q0*/ 0, &exp2 );
309 : /* Put in Q16 */
310 264 : L_gain_fx = L_shr( L_tmp, sub( 31 - 16, exp2 ) ); /* 31: 'L_tmp' is already in Q31 */
311 :
312 264 : ind1 = gain_quant_fx( &L_gain_fx, &gain1_fx, LG10_MIN_GLOB_GAIN_BWE_HR_Q14, LG10_MAX_GLOB_GAIN_BWE_HR_Q13, NBITS_GLOB_GAIN_BWE_HR, &exp1 );
313 :
314 264 : push_indice( hBstr, IND_HR_GAIN, ind1, NBITS_GLOB_GAIN_BWE_HR );
315 264 : nBits = sub( nBits, NBITS_GLOB_GAIN_BWE_HR );
316 :
317 : /* normalization with global gain */
318 264 : ptr16 = &t_audio_fx[NUM_TRANS_START_FREQ_COEF + temp];
319 264 : temp2 = negate( exp1 );
320 264 : gain2_fx = Invert16( gain1_fx, &temp2 );
321 :
322 : /* Also Upscale by 'scl' */
323 264 : temp2 = sub( temp2, scl );
324 18216 : FOR( i = 0; i < WIDTH_TRANS_FREQ_COEF * N_BANDS_TRANS_BWE_HR; i++ )
325 : {
326 17952 : L_temp = L_mult( *ptr16, gain2_fx );
327 17952 : L_temp = L_shr( L_temp, temp2 );
328 17952 : *ptr16++ = round_fx( L_temp );
329 17952 : move16();
330 : }
331 4488 : FOR( ; i < L_FRAME32k / NUM_TIME_SWITCHING_BLOCKS - NUM_TRANS_START_FREQ_COEF; i++ )
332 : {
333 4224 : temp2 = shl( *ptr16, scl );
334 4224 : *ptr16++ = temp2;
335 4224 : move16();
336 : }
337 :
338 : /*---------------------------------------------------------------------*
339 : * envelope coding
340 : *---------------------------------------------------------------------*/
341 :
342 : /* compute energy per band */
343 264 : ptr16 = &t_audio_fx[temp + NUM_TRANS_START_FREQ_COEF];
344 792 : FOR( i = 0; i < N_BANDS_TRANS_BWE_HR; i++ )
345 : {
346 528 : L_temp = Calc_Energy_Autoscaled( ptr16, t_audio_fx_exp, WIDTH_TRANS_FREQ_COEF, &temp2 );
347 528 : ptr16 += WIDTH_TRANS_FREQ_COEF;
348 528 : L_temp = Sqrt_Ratio32( L_temp, temp2, WIDTH_TRANS_FREQ_COEF, /*WIDTH_TRANS_FREQ_COEF is in Q0*/ 0, &temp2 );
349 528 : en_band_fx[i] = round_fx_sat( L_shr_sat( L_temp, sub( 15 - 9, temp2 ) ) );
350 528 : move16();
351 : }
352 :
353 : /* Q energy per band */
354 264 : IF( k == 0 )
355 : {
356 66 : ind1 = en_band_quant_fx( en_band_fx, swb_hr_env_code3_fx, NUM_ENVLOPE_CODE_HR_TR );
357 :
358 66 : push_indice( hBstr, IND_HR_ENVELOPE, ind1, NBITS_ENVELOPE_BWE_HR_TR );
359 66 : nBits = sub( nBits, NBITS_ENVELOPE_BWE_HR_TR );
360 66 : ind2 = ind1;
361 66 : move16();
362 : }
363 : ELSE
364 : {
365 198 : IF( LT_16( ind2, NUM_ENVLOPE_CODE_HR_TR2 ) )
366 : {
367 42 : ind1 = en_band_quant_fx( en_band_fx, swb_hr_env_code3_fx, NUM_ENVLOPE_CODE_HR_TR2 );
368 : }
369 : ELSE
370 : {
371 156 : ind1 = en_band_quant_fx( en_band_fx, swb_hr_env_code3_fx + ( NUM_ENVLOPE_CODE_HR_TR2 * 2 ), NUM_ENVLOPE_CODE_HR_TR2 );
372 : }
373 :
374 198 : push_indice( hBstr, IND_HR_ENVELOPE, ind1, NBITS_ENVELOPE_BWE_HR_TR - 1 );
375 198 : nBits = sub( nBits, NBITS_ENVELOPE_BWE_HR_TR - 1 );
376 : }
377 :
378 : /* normalize spectrum per bands */
379 264 : ptr16 = &t_audio_fx[temp + NUM_TRANS_START_FREQ_COEF];
380 792 : FOR( i = 0; i < N_BANDS_TRANS_BWE_HR; i++ )
381 : {
382 528 : temp2 = 9;
383 528 : move16();
384 528 : gain2_fx = Invert16( en_band_fx[i], &temp2 );
385 :
386 18480 : FOR( j = 0; j < WIDTH_TRANS_FREQ_COEF; j++ )
387 : {
388 17952 : L_temp = L_mult( *ptr16, gain2_fx );
389 17952 : L_temp = L_shr( L_temp, temp2 );
390 17952 : *ptr16++ = round_fx( L_temp );
391 17952 : move16();
392 : }
393 : }
394 :
395 : /*---------------------------------------------------------------------*
396 : * estimate energy of noncoded spectrum (14.4-20kHz)
397 : *---------------------------------------------------------------------*/
398 :
399 264 : IF( NE_16( st_fx->extl, SWB_BWE_HIGHRATE ) )
400 : {
401 : /* st->extl == FB_BWE_HIGHRATE */
402 : /* 'en_noncoded /= (gain * en_band[N_BANDS_TRANS_BWE_HR-1])' */
403 : /* Normalize 'L_en_noncoded_fx' */
404 0 : j = norm_l( L_en_noncoded_fx );
405 0 : L_en_noncoded_fx = L_shl( L_en_noncoded_fx, j );
406 0 : en_noncoded_fx_exp = add( en_noncoded_fx_exp, j );
407 : /* Calc Divisor */
408 0 : L_temp = L_mult0( gain1_fx, en_band_fx[N_BANDS_TRANS_BWE_HR - 1] );
409 : /* Normalize Divisor */
410 0 : temp2 = norm_l( L_temp );
411 0 : L_temp = L_shl( L_temp, temp2 );
412 0 : temp2 = sub( add( 9, temp2 ), exp1 ); /* Q9 for 'en_band_fx' */
413 0 : j = Invert16( round_fx( L_temp ), &temp2 );
414 0 : L_temp = Mult_32_16( L_en_noncoded_fx, j );
415 0 : temp2 = add( temp2, en_noncoded_fx_exp );
416 : /* Put in Q16 */
417 0 : L_temp = L_shr( L_temp, temp2 );
418 :
419 0 : IF( L_msu0( L_temp, BWE_HR_TRANS_EN_LIMIT1_FX_Q16, 1 ) < 0 )
420 : {
421 0 : ind1 = 1;
422 0 : move16();
423 0 : L_en_noncoded_fx = L_mult0( en_band_fx[N_BANDS_TRANS_BWE_HR - 1], BWE_HR_TRANS_EN_LIMIT1_FX_Q16 );
424 : }
425 0 : ELSE IF( L_msu0( L_temp, BWE_HR_TRANS_EN_LIMIT2_FX_Q16, 1 ) < 0 )
426 : {
427 0 : ind1 = 2;
428 0 : move16();
429 0 : L_en_noncoded_fx = L_mult0( en_band_fx[N_BANDS_TRANS_BWE_HR - 1], BWE_HR_TRANS_EN_LIMIT2_FX_Q16 );
430 : }
431 0 : ELSE IF( L_msu0( L_temp, BWE_HR_TRANS_EN_LIMIT3_FX_Q16, 1 ) < 0 )
432 : {
433 0 : ind1 = 3;
434 0 : move16();
435 0 : L_en_noncoded_fx = L_mult0( en_band_fx[N_BANDS_TRANS_BWE_HR - 1], BWE_HR_TRANS_EN_LIMIT3_FX_Q16 );
436 : }
437 : ELSE
438 : {
439 0 : ind1 = 0;
440 0 : move16();
441 0 : L_en_noncoded_fx = L_deposit_h( en_band_fx[N_BANDS_TRANS_BWE_HR - 1] ); /* to Put in Q16+9 */
442 : }
443 :
444 0 : push_indice( hBstr, IND_HR_HF_GAIN, ind1, NBITS_HF_GAIN_BWE_HR );
445 0 : nBits = sub( nBits, NBITS_HF_GAIN_BWE_HR );
446 : }
447 : ELSE
448 : {
449 264 : L_en_noncoded_fx = L_deposit_h( en_band_fx[N_BANDS_TRANS_BWE_HR - 1] );
450 : }
451 264 : en_noncoded_fx_exp = 9 + 16;
452 264 : move16(); /* 9 for 'en_band_fx', 16 for 'BWE_HR_TRANS_EN_LIMIT...' */
453 :
454 : /*---------------------------------------------------------------------*
455 : * AVQ coding (quantize normalized spectrum)
456 : *---------------------------------------------------------------------*/
457 :
458 264 : Nsv = ( NUM_TRANS_END_FREQ_COEF - NUM_TRANS_START_FREQ_COEF ) / WIDTH_BAND;
459 264 : move16();
460 264 : AVQ_cod_fx( t_audio_fx + add( temp, NUM_TRANS_START_FREQ_COEF ), x_norm_fx, nBits, Nsv, t_audio_fx_exp );
461 264 : AVQ_encmux_fx( hBstr, st_fx->extl, x_norm_fx, &nBits, Nsv, nq, 0, sub( Nsv, 1 ) );
462 : }
463 : }
464 : ELSE /* !is_transient */
465 : {
466 : /* subtract one bit for is_transient flag */
467 608 : nBits = sub( nBits, 1 );
468 :
469 : /*---------------------------------------------------------------------*
470 : * processing of normal (non-transient) frames
471 : *---------------------------------------------------------------------*/
472 :
473 : /* set width of noncoded (blind estimated) spectrum */
474 608 : IF( EQ_16( st_fx->extl, SWB_BWE_HIGHRATE ) )
475 : {
476 608 : width_noncoded = L_FRAME32k - NUM_NONTRANS_END_FREQ_COEF;
477 608 : move16();
478 : }
479 : ELSE /* st->extl == FB_BWE_HIGHRATE */
480 : {
481 0 : width_noncoded = 2 * END_FREQ_BWE_FULL_FB / 50 - NUM_NONTRANS_END_FREQ_COEF;
482 0 : move16();
483 : }
484 :
485 : /* compute energy of noncoded (14.4-20kHz) spectrum */
486 608 : IF( EQ_16( st_fx->extl, FB_BWE_HIGHRATE ) )
487 : {
488 0 : L_tmp = Calc_Energy_Autoscaled( t_audio_fx + NUM_NONTRANS_END_FREQ_COEF, t_audio_fx_exp, width_noncoded, &temp2 );
489 0 : L_en_noncoded_fx = Sqrt_Ratio32( L_tmp, temp2, L_deposit_l( width_noncoded ), 0, &en_noncoded_fx_exp );
490 0 : en_noncoded_fx_exp = sub( 31, en_noncoded_fx_exp );
491 : }
492 :
493 : /* keep only frequencies in interest */
494 608 : set16_fx( t_audio_fx, 0, NUM_NONTRANS_START_FREQ_COEF );
495 608 : set16_fx( t_audio_fx + NUM_NONTRANS_END_FREQ_COEF, 0, sub( input_frame, NUM_NONTRANS_END_FREQ_COEF ) );
496 :
497 : /*---------------------------------------------------------------------*
498 : * global gain coding
499 : *---------------------------------------------------------------------*/
500 :
501 : /* compute and quantize global gain */
502 608 : L_tmp = Calc_Energy_Autoscaled( t_audio_fx + NUM_NONTRANS_START_FREQ_COEF, t_audio_fx_exp, WIDTH_NONTRANS_FREQ_COEF * N_BANDS_BWE_HR, &temp2 );
503 : /* Original float Code: 'gain = (float)sqrt( gain ) / (WIDTH_TRANS_FREQ_COEF*N_BANDS_TRANS_BWE_HR)' */
504 : /* Put Divisor to Square to Move it Inside the Sqrt */
505 : /* So we can do 'sqrt( gain (WIDTH_NONTRANS_FREQ_COEF*N_BANDS_BWE_HR)^2)' */
506 608 : L_temp = L_mult0( WIDTH_NONTRANS_FREQ_COEF * N_BANDS_BWE_HR, WIDTH_NONTRANS_FREQ_COEF * N_BANDS_BWE_HR );
507 608 : L_tmp = Sqrt_Ratio32( L_tmp, temp2, L_temp, /*L_temp is in Q0*/ 0, &exp2 );
508 : /* Put in Q16 */
509 608 : L_gain_fx = L_shr( L_tmp, sub( 31 - 16, exp2 ) ); /* 31: 'L_tmp' is already in Q31 */
510 608 : ind1 = gain_quant_fx( &L_gain_fx, &gain1_fx, LG10_MIN_GLOB_GAIN_BWE_HR_Q14, LG10_MAX_GLOB_GAIN_BWE_HR_Q13, NBITS_GLOB_GAIN_BWE_HR, &exp1 );
511 :
512 608 : push_indice( hBstr, IND_HR_GAIN, ind1, NBITS_GLOB_GAIN_BWE_HR );
513 608 : nBits = sub( nBits, NBITS_GLOB_GAIN_BWE_HR );
514 :
515 : /* normalization with global gain */
516 608 : ptr16 = &t_audio_fx[NUM_NONTRANS_START_FREQ_COEF];
517 : /* Find Max Scaling on Remaining Frequencies */
518 608 : temp2 = Find_Max_Norm16( ptr16, NUM_NONTRANS_END_FREQ_COEF - NUM_NONTRANS_START_FREQ_COEF );
519 608 : temp2 = s_max( 0, sub( temp2, NON_TRANSIENT_RESCALE_Q_GUARD ) );
520 608 : temp2 = s_min( temp2, MAX_Q_UPSCALING );
521 608 : t_audio_fx_exp = add( t_audio_fx_exp, temp2 );
522 608 : temp2 = sub( temp2, exp1 );
523 608 : temp = Invert16( gain1_fx, &temp2 );
524 :
525 165984 : FOR( i = 0; i < WIDTH_NONTRANS_FREQ_COEF * N_BANDS_BWE_HR; i++ )
526 : {
527 165376 : L_temp = L_mult( *ptr16, temp );
528 165376 : L_temp = L_shr( L_temp, temp2 );
529 165376 : *ptr16++ = round_fx( L_temp );
530 165376 : move16();
531 : }
532 :
533 : /*---------------------------------------------------------------------*
534 : * envelope coding
535 : *---------------------------------------------------------------------*/
536 :
537 : /* compute energy per band */
538 608 : ptr16 = &t_audio_fx[NUM_NONTRANS_START_FREQ_COEF];
539 3040 : FOR( i = 0; i < N_BANDS_BWE_HR; i++ )
540 : {
541 2432 : L_temp = Calc_Energy_Autoscaled( ptr16, t_audio_fx_exp, WIDTH_NONTRANS_FREQ_COEF, &temp2 );
542 2432 : ptr16 += WIDTH_NONTRANS_FREQ_COEF;
543 2432 : L_temp = Sqrt_Ratio32( L_temp, temp2, WIDTH_NONTRANS_FREQ_COEF, /*WIDTH_TRANS_FREQ_COEF is in Q0*/ 0, &temp2 );
544 2432 : en_band_fx[i] = round_fx_sat( L_shr_sat( L_temp, sub( 15 - 9, temp2 ) ) ); /* Put in Q9 */
545 2432 : move16();
546 : }
547 :
548 : /* Q energy per band */
549 608 : ind1 = en_band_quant_fx( en_band_fx, swb_hr_env_code1_fx, NUM_ENVLOPE_CODE_HR1 );
550 608 : ind2 = en_band_quant_fx( en_band_fx + 2, swb_hr_env_code2_fx, NUM_ENVLOPE_CODE_HR2 );
551 :
552 608 : push_indice( hBstr, IND_HR_ENVELOPE, ind1, NBITS_ENVELOPE_BWE_HR1 );
553 608 : push_indice( hBstr, IND_HR_ENVELOPE, ind2, NBITS_ENVELOPE_BWE_HR2 );
554 :
555 608 : nBits = sub( nBits, NBITS_ENVELOPE_BWE_HR1 + NBITS_ENVELOPE_BWE_HR2 );
556 :
557 : /* normalize spectrum per bands */
558 608 : ptr32 = &L_t_audio_tmp_fx[0];
559 608 : ptr16 = &t_audio_fx[NUM_NONTRANS_START_FREQ_COEF];
560 3040 : FOR( i = 0; i < N_BANDS_BWE_HR; i++ )
561 : {
562 2432 : temp2 = 9;
563 2432 : move16(); /* 'en_band_fx' is in Q9 */
564 2432 : temp = Invert16( en_band_fx[i], &temp2 );
565 167808 : FOR( j = 0; j < WIDTH_NONTRANS_FREQ_COEF; j++ )
566 : {
567 165376 : L_temp = L_mult( *ptr16++, temp );
568 165376 : L_temp = L_shr( L_temp, temp2 );
569 165376 : *ptr32++ = L_temp;
570 165376 : move32();
571 : }
572 : }
573 :
574 : /* Find Max Scaling */
575 608 : L_temp = L_abs( L_t_audio_tmp_fx[0] );
576 165376 : FOR( i = 1; i < N_BANDS_BWE_HR * WIDTH_NONTRANS_FREQ_COEF; i++ )
577 : {
578 164768 : L_temp = L_max( L_temp, L_t_audio_tmp_fx[i] );
579 : }
580 608 : temp = norm_l( L_temp );
581 : /* Keep some Guard and do not Downscale (and do not upscale too much) */
582 608 : temp = s_max( 0, sub( temp, SPECTRUM_RESCALE_Q_GUARD ) );
583 608 : temp = s_min( temp, MAX_Q_UPSCALING );
584 : /* Reduce if 't_audio_fx_exp' is Q14 or more (AVQ Cod overflow with more than Q14 Input) */
585 608 : temp = sub( temp, s_max( 0, sub( add( temp, t_audio_fx_exp ), MAX_AVQ_COD_Q_IN ) ) );
586 : /* Upscale and copy into 16 Bits 't_audio_fx' */
587 608 : Copy_Scale_sig32_16( L_t_audio_tmp_fx, &t_audio_fx[NUM_NONTRANS_START_FREQ_COEF],
588 : N_BANDS_BWE_HR * WIDTH_NONTRANS_FREQ_COEF, temp );
589 : /* Adjust exponent of 't_audio_fx_exp' */
590 608 : t_audio_fx_exp = add( t_audio_fx_exp, temp );
591 :
592 : /*---------------------------------------------------------------------*
593 : * choose sub-bands to be quantized
594 : *---------------------------------------------------------------------*/
595 :
596 : /* find the subband with the min envelope */
597 608 : pos = 0;
598 2432 : FOR( i = 1; i < N_BANDS_BWE_HR; i++ )
599 : {
600 1824 : if ( LT_16( en_band_fx[i], en_band_fx[pos] ) )
601 : {
602 1390 : pos = i;
603 1390 : move16();
604 : }
605 : }
606 608 : min_env_fx = en_band_fx[pos];
607 608 : move16();
608 :
609 : /* decide the spectrum to be quantized */
610 608 : IF( GT_16( nBits_total, NBITS_THRESH_BWE_HR ) )
611 : {
612 0 : i = NUM_NONTRANS_END_FREQ_COEF - NUM_NONTRANS_START_FREQ_COEF;
613 0 : move16();
614 0 : Copy( t_audio_fx + NUM_NONTRANS_START_FREQ_COEF, t_audio_tmp_fx, NUM_NONTRANS_END_FREQ_COEF - NUM_NONTRANS_START_FREQ_COEF );
615 : }
616 : ELSE
617 : {
618 : /* reorder the spectrum */
619 608 : ind1 = add( shl( pos, 6 ), shl( shr( pos, 1 ), WIDTH_BAND_SHIFT ) );
620 608 : Copy( t_audio_fx + NUM_NONTRANS_START_FREQ_COEF, t_audio_tmp_fx, ind1 );
621 :
622 608 : ind2 = add( pos, 1 );
623 608 : ind2 = add( shl( ind2, 6 ), shl( shr( ind2, 1 ), WIDTH_BAND_SHIFT ) );
624 608 : Copy( t_audio_fx + add( NUM_NONTRANS_START_FREQ_COEF, ind2 ), t_audio_tmp_fx + ind1, sub( NUM_NONTRANS_END_FREQ_COEF - NUM_NONTRANS_START_FREQ_COEF, ind2 ) );
625 :
626 608 : i = sub( add( ind1, NUM_NONTRANS_END_FREQ_COEF - NUM_NONTRANS_START_FREQ_COEF ), ind2 );
627 : }
628 :
629 : /*---------------------------------------------------------------------*
630 : * estimate energy of noncoded spectrum (14.4-20kHz)
631 : *---------------------------------------------------------------------*/
632 608 : IF( NE_16( st_fx->extl, SWB_BWE_HIGHRATE ) )
633 : {
634 : /* st->extl == FB_BWE_HIGHRATE */
635 : /* 'en_noncoded /= (gain * min_env)' */
636 : /* Normalize 'L_en_noncoded_fx' */
637 0 : temp = norm_l( L_en_noncoded_fx );
638 0 : L_en_noncoded_fx = L_shl( L_en_noncoded_fx, temp );
639 0 : en_noncoded_fx_exp = add( en_noncoded_fx_exp, temp );
640 : /* Calc Divisor */
641 0 : L_temp = L_mult0( gain1_fx, min_env_fx );
642 : /* Normalize Divisor */
643 0 : temp2 = norm_l( L_temp );
644 0 : L_temp = L_shl( L_temp, temp2 );
645 0 : temp2 = sub( add( 9, temp2 ), exp1 ); /* Q9 for 'min_env_fx', 'exp1' for 'gain1' */
646 0 : j = Invert16( round_fx( L_temp ), &temp2 );
647 0 : L_temp = Mult_32_16( L_en_noncoded_fx, j );
648 0 : temp2 = add( temp2, en_noncoded_fx_exp );
649 : /* Put in Q16 */
650 0 : L_temp = L_shr( L_temp, temp2 );
651 0 : IF( L_msu( L_temp, BWE_HR_NONTRANS_EN_LIMIT1_FX_Q15, 1 ) < 0 )
652 : {
653 0 : ind1 = 1;
654 0 : move16();
655 : /* 'en_noncoded = 0.5f * min_env * BWE_HR_NONTRANS_EN_LIMIT1' */
656 0 : L_en_noncoded_fx = L_mult0( min_env_fx, BWE_HR_NONTRANS_EN_LIMIT1_FX_Q15 / 2 );
657 : }
658 0 : ELSE IF( L_msu( L_temp, BWE_HR_NONTRANS_EN_LIMIT2_FX_Q14, 2 ) > 0 )
659 : {
660 0 : ind1 = 2;
661 0 : move16();
662 : /* 'min_env * BWE_HR_NONTRANS_EN_LIMIT2' */
663 0 : L_en_noncoded_fx = L_mult( min_env_fx, BWE_HR_NONTRANS_EN_LIMIT2_FX_Q14 );
664 : }
665 0 : ELSE IF( L_msu( L_temp, BWE_HR_NONTRANS_EN_LIMIT3_FX_Q15, 1 ) > 0 )
666 : {
667 0 : ind1 = 3;
668 0 : move16();
669 0 : L_en_noncoded_fx = L_mult0( min_env_fx, BWE_HR_NONTRANS_EN_LIMIT3_FX_Q15 );
670 : }
671 : ELSE
672 : {
673 0 : ind1 = 0;
674 0 : move16();
675 0 : L_en_noncoded_fx = L_mult0( min_env_fx, 16384 );
676 : }
677 :
678 0 : push_indice( hBstr, IND_HR_HF_GAIN, ind1, NBITS_HF_GAIN_BWE_HR );
679 0 : nBits = sub( nBits, NBITS_HF_GAIN_BWE_HR );
680 : }
681 : ELSE
682 : {
683 608 : L_en_noncoded_fx = L_mult0( min_env_fx, 16384 );
684 : }
685 608 : en_noncoded_fx_exp = 9 + 16 - 1;
686 608 : move16(); /* 9 for 'en_band_fx', 16 for 'BWE_HR_TRANS_EN_LIMIT...' & -1 becaues of 'L_mult0' */
687 :
688 : /*---------------------------------------------------------------------*
689 : * AVQ coding (quantize normalized spectrum)
690 : *---------------------------------------------------------------------*/
691 :
692 608 : Nsv = shr( i, WIDTH_BAND_SHIFT );
693 608 : AVQ_cod_fx( t_audio_tmp_fx /*same exponent as t_audio_fx*/, x_norm_fx, nBits, Nsv, t_audio_fx_exp );
694 608 : AVQ_encmux_fx( hBstr, st_fx->extl, x_norm_fx, &nBits, Nsv, nq, 0, sub( Nsv, 1 ) );
695 :
696 : /*---------------------------------------------------------------------*
697 : * second stage coding
698 : *---------------------------------------------------------------------*/
699 :
700 608 : test();
701 608 : IF( GE_16( nBits, 9 + NBITS_GLOB_GAIN_BWE_HR ) && sum16_fx( nq, Nsv ) > 0 )
702 : {
703 : /* select spectrum of the second stage coding */
704 598 : ptr16 = &t_audio_fx[0];
705 15620 : FOR( i = 0; i < Nsv; i++ )
706 : {
707 15022 : IF( nq[i] == 0 )
708 : {
709 26685 : FOR( j = 0; j < WIDTH_BAND; j++ )
710 : {
711 23720 : *ptr16++ = t_audio_tmp_fx[i * WIDTH_BAND + j];
712 23720 : move16();
713 : }
714 : }
715 : }
716 598 : temp2 = shl( 1, t_audio_fx_exp );
717 15620 : FOR( i = 0; i < Nsv; i++ )
718 : {
719 15022 : IF( nq[i] != 0 )
720 : {
721 108513 : FOR( j = 0; j < WIDTH_BAND; j++ )
722 : {
723 96456 : L_temp = L_deposit_l( t_audio_tmp_fx[i * WIDTH_BAND + j] );
724 96456 : L_temp = L_msu0( L_temp, temp2, x_norm_fx[i * WIDTH_BAND + j] );
725 96456 : *ptr16++ = extract_l( L_temp );
726 96456 : move16();
727 : }
728 : }
729 : }
730 :
731 : /* calculate the number of subbands according to the rest bits */
732 598 : IF( GT_16( nBits, 396 ) )
733 : {
734 0 : Nsv2 = 33;
735 0 : move16();
736 : }
737 : ELSE
738 : {
739 : /* Here what is acheived is an integer divide by 12 with truncation. */
740 : /* nBits/12 */
741 598 : Nsv2 = mult( nBits, 2731 );
742 : /* But, we have imprecision of the fraction so correction is necessary. */
743 : /* We crosscheck if 'Nsv2' is either too high or too low. */
744 : /* Finally, the result must satisfy: */
745 : /* Nsv2 * 12 <= nBits (Nsv2 is not too high) AND */
746 : /* nBits - Nsv2 * 12 < 12 (Nsv2 is the highest divisor) */
747 598 : L_temp = L_msu0( L_deposit_l( nBits ), 12, Nsv2 );
748 598 : IF( GE_32( L_temp, 12L ) )
749 0 : Nsv2 = add( Nsv2, 1 );
750 598 : IF( L_temp < 0 )
751 0 : Nsv2 = sub( Nsv2, 1 );
752 : }
753 :
754 : /* second stage global gain estimation and coding */
755 598 : L_tmp = L_mult0( Nsv2, WIDTH_BAND );
756 598 : L_temp = Calc_Energy_Autoscaled( t_audio_fx, t_audio_fx_exp, extract_l( L_tmp ), &temp2 );
757 : /* Original Float Code: 'gain2 = (float)(16*sqrt( gain2 / (Nsv2*WIDTH_BAND) ))' */
758 : /* Or Instead: 'gain2 = (float)sqrt( gain2 / (Nsv2*WIDTH_BAND) * 256) )' */
759 598 : L_temp = Sqrt_Ratio32( L_temp, temp2, L_tmp, /*Log2 of 256*/ 8, &temp2 );
760 : /* Put in Q16 */
761 598 : L_gain_fx = L_shr( L_temp, sub( 31 - 16, temp2 ) ); /* 31: 'L_temp' is already in Q31 */
762 598 : ind1 = gain_quant_fx( &L_gain_fx, &gain2_fx, LG10_MIN_GLOB_GAIN_BWE_HR_Q14, LG10_MAX_GLOB_GAIN_BWE_HR_Q13, NBITS_GLOB_GAIN_BWE_HR, &exp2 );
763 598 : push_indice( hBstr, IND_HR_GAIN, ind1, NBITS_GLOB_GAIN_BWE_HR );
764 598 : nBits = sub( nBits, NBITS_GLOB_GAIN_BWE_HR );
765 :
766 : /* normalize with global gain */
767 598 : temp2 = sub( 4, exp2 ); /* 1/16 */
768 598 : temp = Invert16( gain2_fx, &temp2 );
769 21638 : FOR( i = 0; i < Nsv2 * WIDTH_BAND; i++ )
770 : {
771 21040 : L_tmp = L_mult( temp, t_audio_fx[i] );
772 21040 : L_tmp = L_shr_sat( L_tmp, temp2 );
773 : #ifdef ISSUE_1867_replace_overflow_libenc
774 21040 : t_audio_fx[i] = round_fx_sat( L_tmp );
775 : #else
776 : t_audio_fx[i] = round_fx_o( L_tmp, &Overflow );
777 : #endif
778 21040 : move16();
779 : }
780 :
781 598 : set16_fx( nq2, 0, Nsv );
782 :
783 598 : AVQ_cod_fx( t_audio_fx, x_norm1_fx, nBits, Nsv2, t_audio_fx_exp );
784 598 : AVQ_encmux_fx( hBstr, st_fx->extl, x_norm1_fx, &nBits, Nsv2, nq2, 0, sub( Nsv2, 1 ) );
785 : }
786 :
787 : } /* 'ELSE' of ' IF( is_transient )' */
788 :
789 : /* write unused bits */
790 1380 : WHILE( nBits > 0 )
791 : {
792 706 : i = s_min( nBits, 16 );
793 706 : push_indice( hBstr, IND_UNUSED, 0, i );
794 706 : nBits = sub( nBits, i );
795 : }
796 674 : return;
797 : }
|