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