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