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 "prot_fx.h"
9 : #include "basop_util.h"
10 : #include "basop_proto_func.h"
11 : #include "cnst.h"
12 :
13 : /* Fixed point implementation of exp(negate()) */
14 0 : Word32 expfp( /* o: Q31 */
15 : const Word16 x, /* i: mantissa Q-e */
16 : const Word16 x_e ) /* i: exponent Q0 */
17 : {
18 : Word16 xi, xf, tmp;
19 : Word16 b0, b1, b2, b3;
20 : Word32 y, L_tmp;
21 :
22 :
23 0 : assert( x > 0 );
24 :
25 0 : L_tmp = L_shl( L_deposit_h( x ), x_e ); /* Q31 */
26 :
27 : /* split into integer and fractional parts */
28 0 : xi = round_fx( L_tmp ); /* Q15 */
29 0 : xf = extract_l( L_tmp ); /* Q31 */
30 :
31 : BASOP_SATURATE_WARNING_OFF_EVS;
32 0 : xf = negate( xf );
33 : BASOP_SATURATE_WARNING_ON_EVS;
34 :
35 : /* Fractional part */
36 : /* y = 65536
37 : + xf
38 : + ((xf*xf) / (2*65536))
39 : + ((((((xf*xf) / (2*65536))*xf) / 65536)*65536/3) / 65536)
40 : + ((((((((xf*xf) / (2*65536))*xf) / 65536)*65536/3) / 65536)*xf) / (4*65536)); */
41 0 : y = L_mac0( 65536, xf, 1 ); /* Q16 */
42 0 : tmp = shr( mult( xf, xf ), 2 );
43 0 : y = L_mac0( y, tmp, 1 ); /* Q16 */
44 0 : tmp = shr( mult( shr( mult( tmp, xf ), 1 ), 65536 / 3 ), 1 );
45 0 : y = L_mac0( y, tmp, 1 ); /* Q16 */
46 0 : tmp = shr( mult( tmp, xf ), 3 );
47 0 : y = L_mac0( y, tmp, 1 ); /* Q16 */
48 :
49 : /* Integer part */
50 0 : b0 = s_and( xi, 1 );
51 0 : b1 = s_and( xi, 2 );
52 0 : b2 = s_and( xi, 4 );
53 0 : b3 = s_and( xi, 8 );
54 :
55 0 : IF( b0 != 0 )
56 : {
57 0 : y = Mpy_32_16_1( y, 24109 ); /* exp(-1) in -1Q16 */
58 : }
59 0 : IF( b1 != 0 )
60 : {
61 0 : y = Mpy_32_16_1( y, 17739 ); /* exp(-2) in -2Q17 */
62 : }
63 0 : IF( b2 != 0 )
64 : {
65 0 : y = Mpy_32_16_1( y, 19205 ); /* exp(-4) in -5Q20 */
66 : }
67 0 : IF( b3 != 0 )
68 : {
69 0 : y = Mpy_32_16_1( y, 22513 ); /* exp(-8) in -11Q26 */
70 : }
71 :
72 : /* scaling: -1*b0 - 2*b1 -5*b2 -11*b3 */
73 0 : y = L_shr( y, add( add( xi, shr( xi, 2 ) ), shr( b3, 3 ) ) );
74 :
75 : /* zero for xi >= 16 */
76 0 : if ( shr( xi, 4 ) > 0 )
77 : {
78 0 : y = L_deposit_l( 0 );
79 : }
80 :
81 :
82 0 : return L_shl( y, 15 );
83 : }
84 :
85 : /* Fixed point implementation of pow(), where base is fixed point (16/16) and exponent a small *odd* integer
86 : *
87 : * Returns: *pout1 = ( (base/65536)^(2*exp - 1) ) * 65536
88 : * *pout2 = ( (base/65536)^(2*exp + 1) ) * 65536
89 : *
90 : * NOTE: This function must be in sync with ari_decode_14bits_pow_fx() */
91 0 : void powfp_odd2(
92 : const Word16 base, /* Q15 */
93 : const Word16 exp, /* Q0 */
94 : Word16 *pout1, /* Q15 */
95 : Word16 *pout2 /* Q15 */
96 : )
97 : {
98 : /* this version is in sync with ari_enc_14bits_pow()
99 : * that is, we have to start multiplication from the largest power-of-two, in order to
100 : * get the rounding errors to appear at the same places */
101 : Word16 pows[12]; /* powers of two exponents*/
102 : Word16 exp2;
103 : Word16 out, out2;
104 : Word16 k, h, maxk;
105 :
106 0 : assert( exp >= 0 );
107 :
108 0 : out = base; /* Q15 */
109 0 : move16();
110 0 : out2 = 0x7FFF; /* 1 in Q15 */
111 0 : move16();
112 0 : IF( exp != 0 )
113 : {
114 0 : exp2 = sub( exp, 1 );
115 0 : maxk = sub( 15, norm_s( exp ) );
116 0 : assert( maxk < 12 );
117 :
118 0 : pows[0] = base; /* Q15 */
119 0 : move16();
120 0 : FOR( k = 0; k < maxk; k++ )
121 : {
122 0 : pows[k + 1] = mult_r( pows[k], pows[k] ); /* Q15 */
123 0 : move16();
124 : }
125 0 : k = sub( k, 1 );
126 0 : h = shl( 1, k ); /* highest bit of exp2 */
127 0 : out2 = base;
128 0 : move16();
129 0 : out = mult_r( out, pows[k + 1] ); /* we already know that "exp" has the highest bit set to one since we calculated .. */
130 : /* .. the effective length of "exp" earlier on, thus we omit the branch for out2 */
131 0 : IF( s_and( exp2, h ) != 0 )
132 : {
133 0 : out2 = mult_r( out2, pows[k + 1] ); /* Q15 */
134 : }
135 :
136 0 : h = shr( h, 1 );
137 0 : FOR( k = sub( k, 1 ); k >= 0; k-- )
138 : {
139 0 : IF( s_and( exp, h ) != 0 )
140 : {
141 0 : out = mult_r( out, pows[k + 1] ); /* Q15 */
142 : }
143 :
144 0 : IF( s_and( exp2, h ) != 0 )
145 : {
146 0 : out2 = mult_r( out2, pows[k + 1] ); /* Q15 */
147 : }
148 :
149 0 : h = shr( h, 1 );
150 : }
151 : }
152 :
153 0 : *pout1 = out2; /* Q15 */
154 0 : move16();
155 0 : *pout2 = out; /* Q15 */
156 0 : move16();
157 0 : }
158 :
159 : /*------------------------------------------------------------------------
160 : * Function: tcx_arith_scale_envelope
161 : *
162 : * For optimal performance of the arithmetic coder, the envelope shape must
163 : * be scaled such that the expected bit-consumption of a signal that
164 : * follows the scaled shape coincides with the target bitrate.
165 : * This function calculates a first-guess scaling and then uses the bi-section
166 : * search to find the optimal scaling.
167 : *
168 : * We assume that lines follow the Laplacian distribution, whereby the expected
169 : * bit-consumption would be log2(2*e*s[k]), where s[k] is the envelope value
170 : * for the line in question. However, this theoretical formula assumes that
171 : * all lines are encoded with magnitude+sign. Since the sign is unnecessary
172 : * for 0-values, that estimate of bit-consumption is biased when s[k] is small.
173 : * Analytical solution of the expectation for small s[k] is difficult, whereby
174 : * we use the approximation log2(2*e*s[k] + 0.15 + 0.035 / s[k]) which is accurate
175 : * on the range 0.08 to 1.0.
176 : *
177 : * NOTE: This function must be bit-exact on all platforms such that encoder
178 : * and decoder remain synchronized.
179 : *-------------------------------------------------------------------------*/
180 14024 : void tcx_arith_scale_envelope(
181 : const Word16 L_spec_core, /* i: number of lines to scale Q0 */
182 : Word16 L_frame, /* i: number of lines Q0 */
183 : const Word32 env[], /* i: unscaled envelope Q16 */
184 : Word16 target_bits, /* i: number of available bits Q0 */
185 : const Word16 low_complexity, /* i: low-complexity flag Q0 */
186 : Word16 s_env[], /* o: scaled envelope Q15-e */
187 : Word16 *s_env_e /* o: scaled envelope exponent Q0 */
188 : )
189 : {
190 : Word32 ienv[N_MAX_ARI];
191 : Word16 scale, iscale, iscale_e, a_e, b, b_e;
192 : Word16 lob, hib, adjust;
193 : Word16 k, iter, max_iter, lob_bits, hib_bits;
194 : Word16 statesi, bits;
195 : Word32 mean, a, s, L_tmp;
196 : Word16 mean_e, tmp, tmp2;
197 : #ifndef ISSUE_1836_replace_overflow_libcom
198 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
199 : Flag Overflow = 0;
200 : move32();
201 : #endif
202 : #endif
203 :
204 :
205 14024 : lob_bits = 0;
206 14024 : move16();
207 14024 : hib_bits = 0;
208 14024 : move16();
209 :
210 : /* Boosting to account for expected spectrum truncation (kMax) */
211 : /* target_bits = (int)(target_bits * (1.2f - 0.00045f * target_bits + 0.00000025f * target_bits * target_bits)); */
212 14024 : L_tmp = L_shr( Mpy_32_16_1( L_mult0( target_bits, target_bits ), 17180 ), 6 ); /* Q15; 17180 -> 0.00000025f (Q36) */
213 14024 : L_tmp = L_sub( L_tmp, L_shr( L_mult0( target_bits, 30199 ), 11 ) ); /* Q15; 30199 -> 0.00045f (Q26) */
214 14024 : L_tmp = L_add( L_tmp, 39322 ); /* Q15; 39322 -> 1.2f (Q15) */
215 14024 : L_tmp = Mpy_32_16_1( L_tmp, target_bits ); /* Q0 */
216 14024 : assert( L_tmp < 32768 );
217 14024 : target_bits = extract_l( L_tmp );
218 :
219 : /* Calculate inverse envelope and find initial scale guess based on mean */
220 14024 : mean = L_deposit_l( 0 );
221 2943512 : FOR( k = 0; k < L_frame; k++ )
222 : {
223 : /* ienv[k] = 1.0f / env[k];
224 : mean += ienv[k]; */
225 :
226 2929488 : tmp = norm_l( env[k] );
227 2929488 : tmp2 = sub( 15, tmp );
228 : #ifdef ISSUE_1836_replace_overflow_libcom
229 2929488 : tmp = Inv16( round_fx_sat( L_shl( env[k], tmp ) ), &tmp2 ); /* exp(tmp2) */
230 : #else
231 : tmp = Inv16( round_fx_o( L_shl_o( env[k], tmp, &Overflow ), &Overflow ), &tmp2 ); /* exp(tmp2) */
232 : #endif
233 2929488 : ienv[k] = L_shl( L_deposit_h( tmp ), sub( tmp2, 15 ) ); /* Q16 */
234 2929488 : move32();
235 2929488 : mean = L_add( mean, ienv[k] ); /* Q16 */
236 : }
237 14024 : tmp = norm_s( L_frame );
238 14024 : tmp = shl( div_s( 8192, shl( L_frame, tmp ) ), sub( tmp, 7 ) );
239 14024 : mean = L_shr( Mpy_32_16_1( mean, tmp ), 6 ); /* Q16 */
240 :
241 : /* Rate dependent compensation to get closer to the target on average */
242 : /* mean = (float)pow(mean, (float)L_frame / (float)target_bits * 0.357f); */
243 14024 : tmp = BASOP_Util_Divide1616_Scale( L_frame, target_bits, &tmp2 ); /* exp(tmp2) */
244 14024 : tmp = mult_r( tmp, 11698 /*0.357f Q15*/ );
245 14024 : mean = BASOP_Util_fPow( mean, 15, L_deposit_h( tmp ), tmp2, &mean_e ); /* exp(mean_e) */
246 :
247 : /* Find first-guess scaling coefficient "scale" such that if "mean" is the
248 : * mean of the envelope, then the mean bit-consumption is approximately
249 : *
250 : * log2(2*e*mean*scale + 0.15 + 0.035/(mean*scale)) * L_frame = target_bits
251 : */
252 : /* a = 2*2.71828183f*mean*mean; */
253 14024 : tmp = round_fx( mean ); /* Q15 - mean_e */
254 14024 : a = L_mult( mult_r( tmp, 22268 /*2.71828183f Q13*/ ), tmp ); /* 2 * mean_e + 3 */
255 14024 : a_e = add( shl( mean_e, 1 ), 3 );
256 :
257 : /* b = (0.15f - (float)pow(2.0f, target_bits/(float)L_frame)) * mean; */
258 14024 : tmp = BASOP_Util_Divide1616_Scale( target_bits, L_frame, &tmp2 ); /* exp(tmp2) */
259 14024 : tmp = round_fx( BASOP_util_Pow2( L_deposit_h( tmp ), tmp2, &tmp2 ) );
260 14024 : b_e = BASOP_Util_Add_MantExp( 4915 /*0.15f Q15*/, 0, negate( tmp ), tmp2, &b );
261 14024 : b = mult_r( b, round_fx( mean ) ); /* exp(b_e + mean_e) */
262 14024 : b_e = add( b_e, mean_e );
263 :
264 : /* scale = (-b + (float)sqrt(b*b - 4.0f*a*0.035f)) / (2.0f * a); */
265 : #ifdef ISSUE_1836_replace_overflow_libcom
266 14024 : tmp = round_fx_sat( BASOP_Util_Add_Mant32Exp( L_mult( b, b ), shl( b_e, 1 ), Mpy_32_16_1( a, -4588 /*-4.0f*0.035f Q15*/ ), a_e, &tmp2 ) );
267 : #else
268 : tmp = round_fx_o( BASOP_Util_Add_Mant32Exp( L_mult( b, b ), shl( b_e, 1 ), Mpy_32_16_1( a, -4588 /*-4.0f*0.035f Q15*/ ), a_e, &tmp2 ), &Overflow );
269 : #endif
270 :
271 14024 : IF( tmp <= 0 )
272 : {
273 0 : tmp = 0;
274 0 : move16();
275 0 : set16_fx( s_env, 0, L_frame );
276 : }
277 : ELSE
278 : {
279 14024 : tmp = Sqrt16( tmp, &tmp2 );
280 : }
281 :
282 14024 : tmp2 = BASOP_Util_Add_MantExp( negate( b ), b_e, tmp, tmp2, &scale ); /* exp(scale) */
283 14024 : scale = BASOP_Util_Divide1616_Scale( scale, round_fx( a ), &tmp );
284 : #ifdef ISSUE_1836_replace_overflow_libcom
285 14024 : scale = shl_sat( scale, sub( sub( add( tmp, tmp2 ), a_e ), 1 ) ); /* Q15 */
286 : #else
287 : scale = shl_o( scale, sub( sub( add( tmp, tmp2 ), a_e ), 1 ), &Overflow ); /* Q15 */
288 : #endif
289 :
290 : /* iscale = 1.0f / scale; */
291 14024 : iscale_e = 0;
292 14024 : move16();
293 14024 : iscale = Inv16( s_max( 1, scale ), &iscale_e ); /* exp(isacle_e) */
294 :
295 14024 : lob = 0;
296 14024 : move16();
297 14024 : hib = 0;
298 14024 : move16();
299 :
300 14024 : max_iter = 2;
301 14024 : move16();
302 14024 : if ( low_complexity )
303 : {
304 12648 : max_iter = 1;
305 12648 : move16();
306 : }
307 :
308 29424 : FOR( iter = 0; iter < max_iter; iter++ )
309 : {
310 15400 : statesi = 0x7FFF; /* 1 in Q15 */
311 15400 : move16();
312 15400 : bits = 0;
313 15400 : move16();
314 :
315 3233006 : FOR( k = 0; k < L_frame; k++ )
316 : {
317 3217606 : s = Mpy_32_16_1( ienv[k], scale ); /* Q16 */
318 :
319 3217606 : IF( LE_32( s, 5243l /*0.08f Q16*/ ) )
320 : {
321 : /* If s = 0.08, the expected bit-consumption is log2(1.0224). Below 0.08, the bit-consumption
322 : estimate function becomes inaccurate, so use log2(1.0224) for all values below 0.08. */
323 : /* round(state * 1.0224 * 32768) */
324 12662 : statesi = mult_r( statesi, 16751 /*1.0224 Q14*/ ); /* Q14 */
325 12662 : tmp = norm_s( statesi );
326 12662 : statesi = shl( statesi, tmp ); /* Q15 */
327 12662 : bits = add( bits, sub( 1, tmp ) ); /* Q0 */
328 : }
329 3204944 : ELSE IF( LE_32( s, 16711680l /*255.0 Q16*/ ) )
330 : {
331 : /* a = 5.436564f * s + 0.15f + 0.035f * env[k] * iscale; */
332 3204944 : L_tmp = L_shl( Mpy_32_16_1( s, 22268 /*5.436564f Q12*/ ), 3 ); /* Q16 */
333 3204944 : L_tmp = L_add( L_tmp, 9830l /*0.15f Q16*/ ); /* Q16 */
334 3204944 : L_tmp = L_add( L_tmp, L_shl( Mpy_32_16_1( env[k], mult_r( 1147 /*0.035f Q15*/, iscale ) ), iscale_e ) ); /* Q16 */
335 :
336 3204944 : tmp = norm_l( L_tmp );
337 : #ifdef ISSUE_1836_replace_overflow_libcom
338 3204944 : statesi = mult_r( statesi, round_fx_sat( L_shl( L_tmp, tmp ) ) );
339 : #else
340 : statesi = mult_r( statesi, round_fx_o( L_shl_o( L_tmp, tmp, &Overflow ), &Overflow ) );
341 : #endif
342 3204944 : bits = add( bits, sub( 15, tmp ) );
343 :
344 3204944 : tmp = norm_s( statesi );
345 3204944 : statesi = shl( statesi, tmp );
346 3204944 : bits = sub( bits, tmp ); /* Q0 */
347 : }
348 : ELSE
349 : {
350 : /* for large envelope values, s > 255, bit consumption is approx log2(2*e*s)
351 : * further, we use round(log2(x)) = floor(log2(x)+0.5) = floor(log2(x*sqrt(2))) */
352 : /* a = 5.436564f * s; */
353 0 : L_tmp = Mpy_32_16_1( s, 31492 /*5.436564f * 1.4142f Q12*/ ); /* Q13 */
354 0 : bits = add( bits, sub( 17, norm_l( L_tmp ) ) ); /* Q0 */
355 : }
356 : }
357 :
358 15400 : IF( LE_16( bits, target_bits ) ) /* Bits leftover => scale is too small */
359 : {
360 1727 : lob = scale; /* Q0 */
361 1727 : move16();
362 1727 : lob_bits = bits; /* Q0 */
363 1727 : move16();
364 :
365 1727 : IF( hib > 0 ) /* Bisection search */
366 : {
367 1237 : adjust = div_s( sub( hib_bits, target_bits ), sub( hib_bits, lob_bits ) ); /* Q15 */
368 1237 : scale = add( mult_r( sub( lob, hib ), adjust ), hib );
369 : }
370 : ELSE /* Initial scale adaptation */
371 : {
372 : /* adjust = 1.05f * target_bits / (float)bits;
373 : scale *= adjust; */
374 490 : adjust = mult_r( 17203 /*1.05f Q14*/, target_bits );
375 490 : adjust = BASOP_Util_Divide1616_Scale( adjust, bits, &tmp ); /* exp(tmp) */
376 490 : scale = shl( mult_r( scale, adjust ), add( 1, tmp ) );
377 : }
378 : }
379 : ELSE /* Ran out of bits => scale is too large */
380 : {
381 13673 : hib = scale;
382 13673 : move16();
383 13673 : hib_bits = bits;
384 13673 : move16();
385 :
386 13673 : IF( lob > 0 ) /* Bisection search */
387 : {
388 54 : adjust = div_s( sub( hib_bits, target_bits ), sub( hib_bits, lob_bits ) ); /* Q15 */
389 54 : scale = add( mult_r( sub( lob, hib ), adjust ), hib );
390 : }
391 : ELSE
392 : { /* Initial scale adaptation */
393 13619 : test();
394 13619 : IF( target_bits <= 0 || bits <= 0 ) /* safety check in case of bit errors */
395 : {
396 0 : adjust = 0;
397 0 : move16();
398 0 : set16_fx( s_env, 0, L_frame );
399 : }
400 : ELSE
401 : {
402 13619 : adjust = div_s( mult_r( 31130 /*0.95f Q15*/, target_bits ), bits ); /* Q15 */
403 : }
404 13619 : scale = mult_r( scale, adjust );
405 : }
406 : }
407 15400 : iscale_e = 0;
408 15400 : move16();
409 :
410 15400 : IF( scale == 0 ) /* safety check in case of bit errors */
411 : {
412 0 : iscale = 0;
413 0 : move16();
414 0 : set16_fx( s_env, 0, L_frame );
415 : }
416 : ELSE
417 : {
418 15400 : iscale = Inv16( scale, &iscale_e );
419 : }
420 : }
421 14024 : L_frame = L_spec_core; /* Q0 */
422 14024 : move16();
423 :
424 14024 : tmp = getScaleFactor32( env, L_frame );
425 14024 : *s_env_e = sub( add( 15, iscale_e ), tmp );
426 14024 : move16();
427 : BASOP_SATURATE_WARNING_OFF_EVS;
428 : #ifdef ISSUE_1836_replace_overflow_libcom
429 14024 : a = L_shl_sat( 1265000, sub( 15, *s_env_e ) );
430 : #else
431 : a = L_shl_o( 1265000, sub( 15, *s_env_e ), &Overflow );
432 : #endif
433 : BASOP_SATURATE_WARNING_ON_EVS;
434 :
435 8751064 : FOR( k = 0; k < L_frame; k++ )
436 : {
437 8737040 : L_tmp = Mpy_32_16_1( L_shl( env[k], tmp ), iscale ); /* Q31 - e */
438 8737040 : L_tmp = L_min( L_tmp, a ); /* Q31 - e */
439 8737040 : s_env[k] = round_fx( L_tmp ); /* Q15 - e */
440 8737040 : move16();
441 : }
442 14024 : }
443 :
444 : /*------------------------------------------------------------------------
445 : * Function: tcx_arith_render_envelope
446 : *
447 : * Calculate the envelope of the spectrum based on the LPC shape. The
448 : * envelope is used in a perceptual domain, whereby the LPC shape has to
449 : * be multiplied by the perceptual model.
450 : * Operations that are performed on the spectrum, which change the magnitude
451 : * expectation of lines, such as low-frequency emphasis, are included in the
452 : * envelope shape.
453 : * NOTE: This function must be bit-exact on all platforms such that encoder
454 : * and decoder remain synchronized.
455 : *-------------------------------------------------------------------------*/
456 0 : void tcx_arith_render_envelope(
457 : const Word16 A_ind[], /* i: LPC coefficients of signal envelope Q12*/
458 : const Word16 L_frame, /* i: number of spectral lines Q0*/
459 : const Word16 L_spec, /* Q0 */
460 : const Word16 preemph_fac, /* i: pre-emphasis factor Q15*/
461 : const Word16 gamma_w, /* i: A_ind -> weighted envelope factor Q15*/
462 : const Word16 gamma_uw, /* i: A_ind -> non-weighted envelope factor Q14*/
463 : Word32 env[] /* o: shaped signal envelope Q16*/
464 : )
465 : {
466 : Word16 k;
467 : Word16 tmpA[M + 2];
468 : Word16 signal_env[FDNS_NPTS], signal_env_e[FDNS_NPTS];
469 : Word16 gainlpc[FDNS_NPTS], gainlpc_e[FDNS_NPTS];
470 :
471 :
472 : /* Compute perceptual LPC envelope, transform it into freq.-domain gains */
473 0 : weight_a_fx( A_ind, tmpA, gamma_w, M );
474 0 : lpc2mdct( tmpA, M, NULL, NULL, gainlpc, gainlpc_e, FDNS_NPTS, 0 );
475 :
476 : /* Add pre-emphasis tilt to LPC envelope, transform LPC into MDCT gains */
477 0 : E_LPC_a_weight_inv( A_ind, signal_env, gamma_uw, M );
478 0 : E_LPC_a_add_tilt( signal_env, tmpA, preemph_fac, M );
479 0 : lpc2mdct( tmpA, M + 1, signal_env, signal_env_e, NULL, NULL, FDNS_NPTS, 0 );
480 :
481 : /* Compute weighted signal envelope in perceptual domain */
482 0 : FOR( k = 0; k < FDNS_NPTS; k++ )
483 : {
484 0 : signal_env[k] = mult_r( signal_env[k], gainlpc[k] ); /* exp(signal_env_e + gainlpc_e) */
485 0 : move16();
486 0 : signal_env_e[k] = add( signal_env_e[k], gainlpc_e[k] );
487 0 : move16();
488 : }
489 :
490 : /* Adaptive low frequency emphasis */
491 0 : set32_fx( env, 0x10000 /* 1 in Q16 */, L_frame );
492 :
493 0 : AdaptLowFreqDeemph( env, 15,
494 : 1,
495 : gainlpc, gainlpc_e,
496 : L_frame, NULL );
497 :
498 : /* Scale from FDNS_NPTS to L_frame and multiply LFE gains */
499 0 : mdct_noiseShaping_interp( env, L_frame, signal_env, signal_env_e );
500 :
501 0 : FOR( k = L_frame; k < L_spec; ++k )
502 : {
503 0 : env[k] = env[k - 1]; /* Q16 */
504 0 : move32();
505 : }
506 0 : }
507 :
508 : #define WMC_TOOL_SKIP
509 :
510 : /*-------------------------------------------------------*
511 : * expfp_evs()
512 : *
513 : * Fixed point implementation of exp()
514 : *-------------------------------------------------------*/
515 :
516 : /*! r: Q15 */
517 8614277 : Word16 expfp_evs_fx(
518 : const Word16 x, /* i : mantissa Q15-e */
519 : const Word16 x_e /* i : exponent Q0 */
520 : )
521 : {
522 : Word16 xi, xf, tmp;
523 : Word16 b0, b1, b2, b3;
524 : Word32 y, L_tmp;
525 :
526 8614277 : assert( x <= 0 );
527 :
528 8614277 : L_tmp = L_negate( L_shl( L_deposit_h( x ), sub( x_e, 15 ) ) ); /* Q16 */
529 :
530 : /* split into integer and fractional parts */
531 8614277 : xi = round_fx( L_tmp ); /* Q0 */
532 8614277 : xf = extract_l( L_tmp ); /* Q16 */
533 :
534 : BASOP_SATURATE_WARNING_OFF;
535 8614277 : xf = negate( xf );
536 : BASOP_SATURATE_WARNING_ON;
537 :
538 : /* Fractional part */
539 : /* y = 65536
540 : + xf
541 : + ((xf*xf) / (2*65536))
542 : + ((((((xf*xf) / (2*65536))*xf) / 65536)*65536/3) / 65536)
543 : + ((((((((xf*xf) / (2*65536))*xf) / 65536)*65536/3) / 65536)*xf) / (4*65536)); */
544 8614277 : y = L_mac0( 65536, xf, 1 ); /* Q16 */
545 8614277 : tmp = shr( mult( xf, xf ), 2 ); /* Q15 */
546 8614277 : y = L_mac0( y, tmp, 1 ); /* Q16 */
547 8614277 : tmp = shr( mult( shr( mult( tmp, xf ), 1 ), 65536 / 3 ), 1 );
548 8614277 : y = L_mac0( y, tmp, 1 ); /* Q16 */
549 8614277 : tmp = shr( mult( tmp, xf ), 3 );
550 8614277 : y = L_mac0( y, tmp, 1 ); /* Q16 */
551 :
552 : /* Integer part */
553 8614277 : b0 = s_and( xi, 1 );
554 8614277 : b1 = s_and( xi, 2 );
555 8614277 : b2 = s_and( xi, 4 );
556 8614277 : b3 = s_and( xi, 8 );
557 :
558 8614277 : if ( b0 != 0 )
559 4172279 : y = Mpy_32_16_1( y, 24109 ); /* exp(-1) in -1Q16 */
560 8614277 : if ( b1 != 0 )
561 3989340 : y = Mpy_32_16_1( y, 17739 ); /* exp(-2) in -2Q17 */
562 8614277 : if ( b2 != 0 )
563 5008142 : y = Mpy_32_16_1( y, 19205 ); /* exp(-4) in -5Q20 */
564 8614277 : if ( b3 != 0 )
565 588988 : y = Mpy_32_16_1( y, 22513 ); /* exp(-8) in -11Q26 */
566 :
567 : /* scaling: -1*b0 - 2*b1 -5*b2 -11*b3 */
568 8614277 : y = L_shr( y, add( add( xi, shr( xi, 2 ) ), shr( b3, 3 ) ) ); /* Q16 */
569 :
570 : /* zero for xi >= 16 */
571 8614277 : if ( shr( xi, 4 ) > 0 )
572 : {
573 0 : y = L_deposit_l( 0 );
574 0 : move16();
575 : }
576 :
577 8614277 : return round_fx( L_shl( y, 15 ) );
578 : }
579 :
580 : /*-------------------------------------------------------*
581 : * powfp_odd2_evs()
582 : *
583 : * Fixed point implementation of pow(), where base is fixed point (16/16) and exponent a small *odd* integer
584 : *-------------------------------------------------------*/
585 : /*
586 : *
587 : * Returns: *pout1 = ( (base/65536)^(2*exp - 1) ) * 65536
588 : * *pout2 = ( (base/65536)^(2*exp + 1) ) * 65536
589 : *
590 : * NOTE: This function must be in sync with ari_decode_14bits_pow_ivas() */
591 :
592 :
593 : /*------------------------------------------------------------------------
594 : * Function: tcx_arith_render_envelope_flt
595 : *
596 : * Calculate the envelope of the spectrum based on the LPC shape. The
597 : * envelope is used in a perceptual domain, whereby the LPC shape has to
598 : * be multiplied by the perceptual model.
599 : * Operations that are performed on the spectrum, which change the magnitude
600 : * expectation of lines, such as low-frequency emphasis, are included in the
601 : * envelope shape.
602 : * NOTE: This function must be bit-exact on all platforms such that encoder
603 : * and decoder remain synchronized.
604 : *-------------------------------------------------------------------------*/
605 :
606 14024 : void tcx_arith_render_envelope_ivas_fx(
607 : const Word16 A_ind[], /* i : LPC coefficients of signal envelope Q12*/
608 : const Word16 L_frame, /* i : number of spectral lines Q0*/
609 : const Word16 L_spec, /* i : length of the coded spectrum Q0*/
610 : const Word16 preemph_fac, /* i : pre-emphasis factor Q15*/
611 : const Word16 gamma_w, /* i : A_ind -> weighted envelope factor Q15*/
612 : const Word16 gamma_uw, /* i : A_ind -> non-weighted envelope factor Q14*/
613 : Word32 env[] /* o : shaped signal envelope Q16*/
614 : )
615 : {
616 : Word16 k;
617 : Word16 tmpA[M + 2];
618 : Word16 signal_env[FDNS_NPTS], signal_env_e[FDNS_NPTS];
619 : Word16 gainlpc[FDNS_NPTS], gainlpc_e[FDNS_NPTS];
620 :
621 : /* Compute perceptual LPC envelope, transform it into freq.-domain gains */
622 14024 : basop_weight_a( A_ind, tmpA, gamma_w );
623 14024 : basop_lpc2mdct_fx( tmpA, M, NULL, NULL, gainlpc, gainlpc_e );
624 :
625 : /* Add pre-emphasis tilt to LPC envelope, transform LPC into MDCT gains */
626 14024 : basop_weight_a_inv( A_ind, signal_env, gamma_uw );
627 14024 : basop_E_LPC_a_add_tilt( signal_env, tmpA, preemph_fac );
628 14024 : basop_lpc2mdct_fx( tmpA, M + 1, signal_env, signal_env_e, NULL, NULL );
629 :
630 : /* Compute weighted signal envelope in perceptual domain */
631 911560 : FOR( k = 0; k < FDNS_NPTS; k++ )
632 : {
633 897536 : signal_env[k] = mult_r( signal_env[k], gainlpc[k] ); /* exp(signal_env_e + gainlpc_e) */
634 897536 : move16();
635 897536 : signal_env_e[k] = add( signal_env_e[k], gainlpc_e[k] );
636 897536 : move16();
637 : }
638 :
639 : /* Adaptive low frequency emphasis */
640 3688008 : FOR( k = 0; k < L_frame; k++ )
641 : {
642 3673984 : env[k] = 0x10000; /* 1 in Q16 */
643 3673984 : move32();
644 : }
645 :
646 14024 : basop_PsychAdaptLowFreqDeemph_fx( env, gainlpc, gainlpc_e, NULL );
647 :
648 : /* Scale from FDNS_NPTS to L_frame and multiply LFE gains */
649 14024 : basop_mdct_noiseShaping_interp_fx( env, L_frame, signal_env, signal_env_e );
650 :
651 5077080 : FOR( k = L_frame; k < L_spec; ++k )
652 : {
653 5063056 : env[k] = env[k - 1]; /* Q16 */
654 5063056 : move32();
655 : }
656 :
657 14024 : return;
658 : }
659 :
660 : #undef WMC_TOOL_SKIP
|