Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
4 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
5 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
6 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
7 : contributors to this repository. All Rights Reserved.
8 :
9 : This software is protected by copyright law and by international treaties.
10 : The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
11 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
12 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
13 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
14 : contributors to this repository retain full ownership rights in their respective contributions in
15 : the software. This notice grants no license of any kind, including but not limited to patent
16 : license, nor is any license granted by implication, estoppel or otherwise.
17 :
18 : Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
19 : contributions.
20 :
21 : This software is provided "AS IS", without any express or implied warranties. The software is in the
22 : development stage. It is intended exclusively for experts who have experience with such software and
23 : solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
24 : and fitness for a particular purpose are hereby disclaimed and excluded.
25 :
26 : Any dispute, controversy or claim arising under or in relation to providing this software shall be
27 : submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
28 : accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
29 : the United Nations Convention on Contracts on the International Sales of Goods.
30 :
31 : *******************************************************************************************************/
32 :
33 : /*====================================================================================
34 : EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
35 : ====================================================================================*/
36 :
37 : #include <assert.h>
38 : #include <stdint.h>
39 : #include "options.h"
40 : #ifdef DEBUGGING
41 : #include "debug.h"
42 : #endif
43 : #include <math.h>
44 : #include "cnst.h"
45 : #include "prot.h"
46 : #include "basop_util.h"
47 : #include "basop_proto_func.h"
48 : #include "wmc_auto.h"
49 :
50 :
51 : #define WMC_TOOL_SKIP
52 :
53 : /*-------------------------------------------------------*
54 : * expfp()
55 : *
56 : * Fixed point implementation of exp()
57 : *-------------------------------------------------------*/
58 :
59 : /*! r: Q15 */
60 42580947 : Word16 expfp(
61 : const Word16 x, /* i : mantissa Q15-e */
62 : const Word16 x_e /* i : exponent Q0 */
63 : )
64 : {
65 : Word16 xi, xf, tmp;
66 : Word16 b0, b1, b2, b3;
67 : Word32 y, L_tmp;
68 :
69 42580947 : assert( x <= 0 );
70 :
71 42580947 : L_tmp = L_negate( L_shl( L_deposit_h( x ), sub( x_e, 15 ) ) );
72 :
73 : /* split into integer and fractional parts */
74 42580947 : xi = round_fx( L_tmp );
75 42580947 : xf = extract_l( L_tmp );
76 :
77 : BASOP_SATURATE_WARNING_OFF;
78 42580947 : xf = negate( xf );
79 : BASOP_SATURATE_WARNING_ON;
80 :
81 : /* Fractional part */
82 : /* y = 65536
83 : + xf
84 : + ((xf*xf) / (2*65536))
85 : + ((((((xf*xf) / (2*65536))*xf) / 65536)*65536/3) / 65536)
86 : + ((((((((xf*xf) / (2*65536))*xf) / 65536)*65536/3) / 65536)*xf) / (4*65536)); */
87 42580947 : y = L_mac0( 65536, xf, 1 );
88 42580947 : tmp = shr( mult( xf, xf ), 2 );
89 42580947 : y = L_mac0( y, tmp, 1 );
90 42580947 : tmp = shr( mult( shr( mult( tmp, xf ), 1 ), 65536 / 3 ), 1 );
91 42580947 : y = L_mac0( y, tmp, 1 );
92 42580947 : tmp = shr( mult( tmp, xf ), 3 );
93 42580947 : y = L_mac0( y, tmp, 1 );
94 :
95 : /* Integer part */
96 42580947 : b0 = s_and( xi, 1 );
97 42580947 : b1 = s_and( xi, 2 );
98 42580947 : b2 = s_and( xi, 4 );
99 42580947 : b3 = s_and( xi, 8 );
100 :
101 42580947 : if ( b0 != 0 )
102 20643122 : y = Mpy_32_16( y, 24109 ); /* exp(-1) in -1Q16 */
103 42580947 : if ( b1 != 0 )
104 19897189 : y = Mpy_32_16( y, 17739 ); /* exp(-2) in -2Q17 */
105 42580947 : if ( b2 != 0 )
106 24788878 : y = Mpy_32_16( y, 19205 ); /* exp(-4) in -5Q20 */
107 42580947 : if ( b3 != 0 )
108 3114959 : y = Mpy_32_16( y, 22513 ); /* exp(-8) in -11Q26 */
109 :
110 : /* scaling: -1*b0 - 2*b1 -5*b2 -11*b3 */
111 42580947 : y = L_shr( y, add( add( xi, shr( xi, 2 ) ), shr( b3, 3 ) ) );
112 :
113 : /* zero for xi >= 16 */
114 42580947 : if ( shr( xi, 4 ) > 0 )
115 : {
116 0 : y = L_deposit_l( 0 );
117 0 : move16();
118 : }
119 :
120 42580947 : return round_fx( L_shl( y, 15 ) );
121 : }
122 :
123 :
124 : /*-------------------------------------------------------*
125 : * powfp_odd2()
126 : *
127 : * Fixed point implementation of pow(), where base is fixed point (16/16) and exponent a small *odd* integer
128 : *-------------------------------------------------------*/
129 : /*
130 : *
131 : * Returns: *pout1 = ( (base/65536)^(2*exp - 1) ) * 65536
132 : * *pout2 = ( (base/65536)^(2*exp + 1) ) * 65536
133 : *
134 : * NOTE: This function must be in sync with ari_decode_14bits_pow() */
135 :
136 876988 : void powfp_odd2(
137 : const Word16 base, /* Q15 */
138 : const Word16 exp, /* Q0 */
139 : Word16 *pout1, /* Q15 */
140 : Word16 *pout2 /* Q15 */
141 : )
142 : {
143 : /* this version is in sync with ari_enc_14bits_pow()
144 : * that is, we have to start multiplication from the largest power-of-two, in order to
145 : * get the rounding errors to appear at the same places */
146 : Word16 pows[12]; /* powers of two exponents*/
147 : Word16 exp2;
148 : Word16 out, out2;
149 : Word16 k, h, maxk;
150 :
151 876988 : assert( exp >= 0 );
152 :
153 876988 : out = base;
154 876988 : move16();
155 876988 : out2 = 0x7FFF;
156 876988 : move16();
157 876988 : IF( exp != 0 )
158 : {
159 876988 : exp2 = sub( exp, 1 );
160 876988 : maxk = sub( 15, norm_s( exp ) );
161 876988 : assert( maxk < 12 );
162 :
163 876988 : pows[0] = base;
164 876988 : move16();
165 2532865 : FOR( k = 0; k < maxk; k++ )
166 : {
167 1655877 : pows[k + 1] = mult_r( pows[k], pows[k] );
168 1655877 : move16();
169 : }
170 876988 : k = sub( k, 1 );
171 876988 : h = shl( 1, k ); /* highest bit of exp2 */
172 876988 : out2 = base;
173 876988 : move16();
174 876988 : out = mult_r( out, pows[k + 1] ); /* we already know that "exp" has the highest bit set to one since we calculated .. */
175 : /* .. the effective length of "exp" earlier on, thus we omit the branch for out2 */
176 876988 : if ( s_and( exp2, h ) != 0 )
177 : {
178 233012 : out2 = mult_r( out2, pows[k + 1] );
179 : }
180 :
181 876988 : h = shr( h, 1 );
182 1655877 : FOR( k = sub( k, 1 ); k >= 0; k-- )
183 : {
184 778889 : if ( s_and( exp, h ) != 0 )
185 : {
186 285503 : out = mult_r( out, pows[k + 1] );
187 : }
188 :
189 778889 : if ( s_and( exp2, h ) != 0 )
190 : {
191 445447 : out2 = mult_r( out2, pows[k + 1] );
192 : }
193 :
194 778889 : h = shr( h, 1 );
195 : }
196 : }
197 :
198 876988 : *pout1 = out2;
199 876988 : move16();
200 876988 : *pout2 = out;
201 876988 : move16();
202 :
203 876988 : return;
204 : }
205 :
206 :
207 : /*------------------------------------------------------------------------
208 : * Function: tcx_arith_scale_envelope
209 : *
210 : * For optimal performance of the arithmetic coder, the envelope shape must
211 : * be scaled such that the expected bit-consumption of a signal that
212 : * follows the scaled shape coincides with the target bitrate.
213 : * This function calculates a first-guess scaling and then uses the bi-section
214 : * search to find the optimal scaling.
215 : *
216 : * We assume that lines follow the Laplacian distribution, whereby the expected
217 : * bit-consumption would be log2(2*e*s[k]), where s[k] is the envelope value
218 : * for the line in question. However, this theoretical formula assumes that
219 : * all lines are encoded with magnitude+sign. Since the sign is unnecessary
220 : * for 0-values, that estimate of bit-consumption is biased when s[k] is small.
221 : * Analytical solution of the expectation for small s[k] is difficult, whereby
222 : * we use the approximation log2(2*e*s[k] + 0.15 + 0.035 / s[k]) which is accurate
223 : * on the range 0.08 to 1.0.
224 : *
225 : * NOTE: This function must be bit-exact on all platforms such that encoder
226 : * and decoder remain synchronized.
227 : *-------------------------------------------------------------------------*/
228 :
229 68415 : void tcx_arith_scale_envelope(
230 : const Word16 L_spec_core, /* i : number of lines to scale Q0 */
231 : Word16 L_frame, /* i : number of lines Q0 */
232 : const Word32 env[], /* i : unscaled envelope Q16 */
233 : Word16 target_bits, /* i : number of available bits Q0 */
234 : const Word16 low_complexity, /* i : low-complexity Q0 */
235 : Word16 s_env[], /* o : scaled envelope Q15-e */
236 : Word16 *s_env_e /* o : scaled envelope exponent Q0 */
237 : )
238 : {
239 : Word32 ienv[N_MAX_ARI];
240 : Word16 scale, iscale, iscale_e, a_e, b, b_e;
241 : Word16 lob, hib, adjust;
242 : Word16 k, iter, max_iter, lob_bits, hib_bits;
243 : Word16 statesi, bits;
244 : Word32 mean, a, s, L_tmp;
245 : Word16 mean_e, tmp, tmp2;
246 : #ifdef BASOP_NOGLOB
247 : Flag Overflow;
248 : #endif /* BASOP_NOGLOB */
249 :
250 :
251 68415 : lob_bits = 0;
252 68415 : move16();
253 68415 : hib_bits = 0;
254 68415 : move16();
255 :
256 : /* Boosting to account for expected spectrum truncation (kMax) */
257 : /* target_bits = (int16_t)(target_bits * (1.2f - 0.00045f * target_bits + 0.00000025f * target_bits * target_bits)); */
258 68415 : L_tmp = L_shr( Mpy_32_16( L_mult0( target_bits, target_bits ), 17180 ), 6 ); /* Q15; 17180 -> 0.00000025f (Q36) */
259 68415 : L_tmp = L_sub( L_tmp, L_shr( L_mult0( target_bits, 30199 ), 11 ) ); /* Q15; 30199 -> 0.00045f (Q26) */
260 68415 : L_tmp = L_add( L_tmp, 39322 ); /* Q15; 39322 -> 1.2f (Q15) */
261 68415 : L_tmp = Mpy_32_16( L_tmp, target_bits ); /* Q0 */
262 68415 : assert( L_tmp < 32768 );
263 68415 : target_bits = extract_l( L_tmp );
264 :
265 : /* Calculate inverse envelope and find initial scale guess based on mean */
266 68415 : mean = L_deposit_l( 0 );
267 14319995 : FOR( k = 0; k < L_frame; k++ )
268 : {
269 : /* ienv[k] = 1.0f / env[k];
270 : mean += ienv[k]; */
271 :
272 14251580 : tmp = norm_l( env[k] );
273 14251580 : tmp2 = sub( 15, tmp );
274 : #ifndef BASOP_NOGLOB
275 : tmp = Inv16( round_fx( L_shl( env[k], tmp ) ), &tmp2 );
276 : #else /* BASOP_NOGLOB */
277 14251580 : tmp = Inv16( round_fx_o( L_shl( env[k], tmp ), &Overflow ), &tmp2 );
278 : #endif /* BASOP_NOGLOB */
279 14251580 : ienv[k] = L_shl( L_deposit_h( tmp ), sub( tmp2, 15 ) ); /* Q16 */
280 14251580 : move32();
281 14251580 : mean = L_add( mean, ienv[k] );
282 : }
283 68415 : tmp = norm_s( L_frame );
284 68415 : tmp2 = div_s( 8192, shl( L_frame, tmp ) );
285 68415 : tmp = shl( tmp2, sub( tmp, 7 ) );
286 68415 : mean = L_shr( Mpy_32_16( mean, tmp ), 6 ); /* Q16 */
287 :
288 : /* Rate dependent compensation to get closer to the target on average */
289 : /* mean = powf(mean, (float)L_frame / target_bits * 0.357f); */
290 68415 : tmp = BASOP_Util_Divide1616_Scale( L_frame, target_bits, &tmp2 );
291 68415 : tmp = mult_r( tmp, FL2WORD16( 0.357f ) );
292 68415 : mean = BASOP_Util_fPow( mean, 15, L_deposit_h( tmp ), tmp2, &mean_e );
293 :
294 : /* Find first-guess scaling coefficient "scale" such that if "mean" is the
295 : * mean of the envelope, then the mean bit-consumption is approximately
296 : *
297 : * log2(2*e*mean*scale + 0.15 + 0.035/(mean*scale)) * L_frame = target_bits
298 : */
299 : /* a = 2*2.71828183f*mean*mean; */
300 68415 : tmp = round_fx( mean );
301 68415 : a = L_mult( mult_r( tmp, FL2WORD16_SCALE( 2.71828183f, 2 ) ), tmp );
302 68415 : a_e = add( shl( mean_e, 1 ), 3 );
303 :
304 : /* b = (0.15f - powf(2.0f, target_bits/(float)L_frame)) * mean; */
305 68415 : tmp = BASOP_Util_Divide1616_Scale( target_bits, L_frame, &tmp2 );
306 68415 : tmp = round_fx( BASOP_util_Pow2( L_deposit_h( tmp ), tmp2, &tmp2 ) );
307 68415 : b_e = BASOP_Util_Add_MantExp( FL2WORD16( 0.15f ), 0, negate( tmp ), tmp2, &b );
308 68415 : b = mult_r( b, round_fx( mean ) );
309 68415 : b_e = add( b_e, mean_e );
310 :
311 : /* scale = (-b + sqrtf(b*b - 4.0f*a*0.035f)) / (2.0f * a); */
312 : #ifndef BASOP_NOGLOB
313 : tmp = round_fx( BASOP_Util_Add_Mant32Exp( L_mult( b, b ), shl( b_e, 1 ), Mpy_32_16( a, FL2WORD16( -4.0f * 0.035f ) ), a_e, &tmp2 ) );
314 : #else
315 68415 : tmp = round_fx_o( BASOP_Util_Add_Mant32Exp( L_mult( b, b ), shl( b_e, 1 ), Mpy_32_16( a, FL2WORD16( -4.0f * 0.035f ) ), a_e, &tmp2 ), &Overflow );
316 : #endif
317 :
318 68415 : IF( tmp <= 0 )
319 : {
320 0 : tmp = 0;
321 :
322 0 : FOR( k = 0; k < L_frame; k++ )
323 : {
324 0 : s_env[k] = 0;
325 0 : move16();
326 : }
327 : }
328 : ELSE
329 : {
330 68415 : tmp = Sqrt16( tmp, &tmp2 );
331 : }
332 :
333 68415 : tmp2 = BASOP_Util_Add_MantExp( negate( b ), b_e, tmp, tmp2, &scale );
334 68415 : scale = BASOP_Util_Divide1616_Scale( scale, round_fx( a ), &tmp );
335 : #ifndef BASOP_NOGLOB
336 : scale = shl( scale, sub( sub( add( tmp, tmp2 ), a_e ), 1 ) ); /* Q15 */
337 : #else
338 68415 : scale = shl_o( scale, sub( sub( add( tmp, tmp2 ), a_e ), 1 ), &Overflow ); /* Q15 */
339 : #endif
340 :
341 : /* iscale = 1.0f / scale; */
342 68415 : iscale_e = 0;
343 68415 : move16();
344 68415 : iscale = Inv16( s_max( 1, scale ), &iscale_e );
345 :
346 68415 : lob = 0;
347 68415 : move16();
348 68415 : hib = 0;
349 68415 : move16();
350 :
351 68415 : max_iter = 2;
352 68415 : move16();
353 68415 : if ( low_complexity )
354 : {
355 62973 : max_iter = 1;
356 62973 : move16();
357 : }
358 :
359 142272 : FOR( iter = 0; iter < max_iter; iter++ )
360 : {
361 73857 : statesi = 0x7FFF;
362 73857 : move16();
363 73857 : bits = 0;
364 73857 : move16();
365 :
366 15464837 : FOR( k = 0; k < L_frame; k++ )
367 : {
368 15390980 : s = Mpy_32_16( ienv[k], scale ); /* Q16 */
369 :
370 15390980 : IF( L_sub( s, FL2WORD32_SCALE( 0.08f, 15 ) ) <= 0 )
371 : {
372 : /* If s = 0.08, the expected bit-consumption is log2(1.0224). Below 0.08, the bit-consumption
373 : estimate function becomes inaccurate, so use log2(1.0224) for all values below 0.08. */
374 : /* round(state * 1.0224 * 32768) */
375 61480 : statesi = mult_r( statesi, FL2WORD16_SCALE( 1.0224, 1 ) );
376 61480 : tmp = norm_s( statesi );
377 61480 : statesi = shl( statesi, tmp );
378 61480 : bits = add( bits, sub( 1, tmp ) );
379 : }
380 15329500 : ELSE IF( L_sub( s, FL2WORD32_SCALE( 255.0, 15 ) ) <= 0 )
381 : {
382 : /* a = 5.436564f * s + 0.15f + 0.035f * env[k] * iscale; */
383 15329500 : L_tmp = L_shl( Mpy_32_16( s, FL2WORD16_SCALE( 5.436564f, 3 ) ), 3 );
384 15329500 : L_tmp = L_add( L_tmp, FL2WORD32_SCALE( 0.15f, 15 ) );
385 15329500 : L_tmp = L_add( L_tmp, L_shl( Mpy_32_16( env[k], mult_r( FL2WORD16( 0.035f ), iscale ) ), iscale_e ) );
386 :
387 15329500 : tmp = norm_l( L_tmp );
388 : #ifndef BASOP_NOGLOB
389 : statesi = mult_r( statesi, round_fx( L_shl( L_tmp, tmp ) ) );
390 : #else /* BASOP_NOGLOB */
391 15329500 : statesi = mult_r( statesi, round_fx_o( L_shl( L_tmp, tmp ), &Overflow ) );
392 : #endif /* BASOP_NOGLOB */
393 15329500 : bits = add( bits, sub( 15, tmp ) );
394 :
395 15329500 : tmp = norm_s( statesi );
396 15329500 : statesi = shl( statesi, tmp );
397 15329500 : bits = sub( bits, tmp );
398 : }
399 : ELSE
400 : {
401 : /* for large envelope values, s > 255, bit consumption is approx log2(2*e*s)
402 : * further, we use round(log2(x)) = floor(log2(x)+0.5) = floor(log2(x*sqrt(2))) */
403 : /* a = 5.436564f * s; */
404 0 : L_tmp = Mpy_32_16( s, FL2WORD16_SCALE( 5.436564f * 1.4142f, 3 ) ); /* Q13 */
405 0 : bits = add( bits, sub( 17, norm_l( L_tmp ) ) );
406 : }
407 : }
408 :
409 73857 : IF( sub( bits, target_bits ) <= 0 )
410 : {
411 : /* Bits leftover => scale is too small */
412 6884 : lob = scale;
413 6884 : move16();
414 6884 : lob_bits = bits;
415 6884 : move16();
416 :
417 6884 : IF( hib > 0 ) /* Bisection search */
418 : {
419 4895 : adjust = div_s( sub( hib_bits, target_bits ), sub( hib_bits, lob_bits ) );
420 4895 : scale = add( mult_r( sub( lob, hib ), adjust ), hib );
421 : }
422 : ELSE
423 : {
424 : /* Initial scale adaptation */
425 : /* adjust = 1.05f * target_bits / (float)bits;
426 : scale *= adjust; */
427 1989 : adjust = mult_r( FL2WORD16_SCALE( 1.05f, 1 ), target_bits );
428 1989 : adjust = BASOP_Util_Divide1616_Scale( adjust, bits, &tmp );
429 1989 : scale = shl( mult_r( scale, adjust ), add( 1, tmp ) );
430 : }
431 : }
432 : ELSE
433 : {
434 : /* Ran out of bits => scale is too large */
435 66973 : hib = scale;
436 66973 : move16();
437 66973 : hib_bits = bits;
438 66973 : move16();
439 :
440 66973 : IF( lob > 0 ) /* Bisection search */
441 : {
442 207 : adjust = div_s( sub( hib_bits, target_bits ), sub( hib_bits, lob_bits ) );
443 207 : scale = add( mult_r( sub( lob, hib ), adjust ), hib );
444 : }
445 : ELSE
446 : { /* Initial scale adaptation */
447 66766 : test();
448 66766 : IF( target_bits <= 0 || bits <= 0 ) /* safety check in case of bit errors */
449 : {
450 0 : adjust = 0;
451 0 : move16();
452 :
453 0 : FOR( k = 0; k < L_frame; k++ )
454 : {
455 0 : s_env[k] = 0;
456 0 : move16();
457 : }
458 : }
459 : ELSE
460 : {
461 66766 : adjust = div_s( mult_r( 31130 /*0.95f Q15*/, target_bits ), bits );
462 : }
463 66766 : scale = mult_r( scale, adjust );
464 : }
465 : }
466 73857 : iscale_e = 0;
467 73857 : move16();
468 :
469 73857 : IF( scale == 0 ) /* safety check in case of bit errors */
470 : {
471 0 : iscale = 0;
472 0 : move16();
473 :
474 0 : FOR( k = 0; k < L_frame; k++ )
475 : {
476 0 : s_env[k] = 0;
477 0 : move16();
478 : }
479 : }
480 : ELSE
481 : {
482 73857 : iscale = Inv16( scale, &iscale_e );
483 : }
484 : }
485 68415 : L_frame = L_spec_core;
486 68415 : move16();
487 :
488 68415 : tmp = getScaleFactor32( env, L_frame );
489 68415 : *s_env_e = sub( add( 15, iscale_e ), tmp );
490 68415 : move16();
491 : BASOP_SATURATE_WARNING_OFF;
492 : #ifndef BASOP_NOGLOB
493 : a = L_shl( 1265000, sub( 15, *s_env_e ) );
494 : #else /* BASOP_NOGLOB */
495 68415 : a = L_shl_o( 1265000, sub( 15, *s_env_e ), &Overflow );
496 : #endif /* BASOP_NOGLOB */
497 : BASOP_SATURATE_WARNING_ON;
498 :
499 43142655 : FOR( k = 0; k < L_frame; k++ )
500 : {
501 43074240 : L_tmp = Mpy_32_16( L_shl( env[k], tmp ), iscale );
502 43074240 : L_tmp = L_min( L_tmp, a );
503 43074240 : s_env[k] = round_fx( L_tmp );
504 43074240 : move16();
505 : }
506 :
507 68415 : return;
508 : }
509 :
510 :
511 : /*------------------------------------------------------------------------
512 : * Function: tcx_arith_render_envelope
513 : *
514 : * Calculate the envelope of the spectrum based on the LPC shape. The
515 : * envelope is used in a perceptual domain, whereby the LPC shape has to
516 : * be multiplied by the perceptual model.
517 : * Operations that are performed on the spectrum, which change the magnitude
518 : * expectation of lines, such as low-frequency emphasis, are included in the
519 : * envelope shape.
520 : * NOTE: This function must be bit-exact on all platforms such that encoder
521 : * and decoder remain synchronized.
522 : *-------------------------------------------------------------------------*/
523 :
524 68415 : void tcx_arith_render_envelope(
525 : const Word16 A_ind[], /* i : LPC coefficients of signal envelope */
526 : const Word16 L_frame, /* i : number of spectral lines */
527 : const Word16 L_spec, /* i : length of the coded spectrum */
528 : const Word16 preemph_fac, /* i : pre-emphasis factor */
529 : const Word16 gamma_w, /* i : A_ind -> weighted envelope factor */
530 : const Word16 gamma_uw, /* i : A_ind -> non-weighted envelope factor */
531 : Word32 env[] /* o : shaped signal envelope */
532 : )
533 : {
534 : Word16 k;
535 : Word16 tmpA[M + 2];
536 : Word16 signal_env[FDNS_NPTS], signal_env_e[FDNS_NPTS];
537 : Word16 gainlpc[FDNS_NPTS], gainlpc_e[FDNS_NPTS];
538 :
539 : /* Compute perceptual LPC envelope, transform it into freq.-domain gains */
540 68415 : basop_weight_a( A_ind, tmpA, gamma_w );
541 68415 : basop_lpc2mdct( tmpA, M, NULL, NULL, gainlpc, gainlpc_e );
542 :
543 : /* Add pre-emphasis tilt to LPC envelope, transform LPC into MDCT gains */
544 68415 : basop_weight_a_inv( A_ind, signal_env, gamma_uw );
545 68415 : basop_E_LPC_a_add_tilt( signal_env, tmpA, preemph_fac );
546 68415 : basop_lpc2mdct( tmpA, M + 1, signal_env, signal_env_e, NULL, NULL );
547 :
548 : /* Compute weighted signal envelope in perceptual domain */
549 4446975 : FOR( k = 0; k < FDNS_NPTS; k++ )
550 : {
551 4378560 : signal_env[k] = mult_r( signal_env[k], gainlpc[k] );
552 4378560 : move16();
553 4378560 : signal_env_e[k] = add( signal_env_e[k], gainlpc_e[k] );
554 4378560 : move16();
555 : }
556 :
557 : /* Adaptive low frequency emphasis */
558 18006975 : FOR( k = 0; k < L_frame; k++ )
559 : {
560 17938560 : env[k] = 0x10000;
561 17938560 : move32();
562 : }
563 :
564 68415 : basop_PsychAdaptLowFreqDeemph( env, gainlpc, gainlpc_e, NULL );
565 :
566 : /* Scale from FDNS_NPTS to L_frame and multiply LFE gains */
567 68415 : basop_mdct_noiseShaping_interp( env, L_frame, signal_env, signal_env_e );
568 :
569 25204095 : FOR( k = L_frame; k < L_spec; ++k )
570 : {
571 25135680 : env[k] = env[k - 1];
572 25135680 : move32();
573 : }
574 :
575 68415 : return;
576 : }
577 :
578 : #undef WMC_TOOL_SKIP
|