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.452 Aug 12, 2021. Version 16.3.0
35 : ====================================================================================*/
36 :
37 : #include <stdlib.h>
38 : #include <assert.h>
39 : #include <stdint.h>
40 : #include "options.h"
41 : #include "stl.h"
42 : #include <math.h>
43 : #include "cnst.h"
44 : #include "prot_fx.h"
45 : #include "basop_util.h"
46 : #include "basop32.h"
47 : #include "wmc_auto.h"
48 : #include "prot_fx_enc.h"
49 : #include "ivas_prot_fx.h"
50 :
51 : #define INV_BANDS10 3277 /* 1/10 in Q15 */
52 : #define INV_BANDS9 3641 /* 1/9 in Q15 */
53 : #define INV_BANDS3 10923 /* 1/9 in Q15 */
54 : const Word16 b_hp400_fx[3] = { 3660, -7320, 3660 }; /* Q12 (/4) */
55 : const Word16 a_hp400_fx[3] = { 16384, 29280, -14160 };
56 : const Word16 a_hp400_ivas_fx[3] = { 4096, 7320, -3540 }; /*Q12*/
57 :
58 : #define WMC_TOOL_SKIP
59 :
60 : // conversion functions:
61 6527875 : Word32 float_to_fix( float number, Word32 Q )
62 : {
63 6527875 : assert( Q >= 0 );
64 6527875 : if ( number == 1.0f && Q == Q31 )
65 : {
66 0 : return ONE_IN_Q31;
67 : }
68 6527875 : if ( isnan( number ) )
69 : {
70 0 : number = 0;
71 : }
72 6527875 : assert( fabs( number ) < pow( 2, 31 - Q ) );
73 6527875 : Word32 ret = (Word32) ( number * ( (UWord32) 1 << Q ) );
74 6527875 : return ret;
75 : }
76 :
77 0 : float fix_to_float( Word32 number, Word32 Q )
78 : {
79 0 : assert( Q >= 0 );
80 0 : float ret = (float) number / ( (UWord32) 1 << Q );
81 0 : return ret;
82 : }
83 :
84 525436 : Word16 float_to_fix16( float number, Word16 Q )
85 : {
86 525436 : assert( Q >= 0 );
87 525436 : IF( isnan( number ) )
88 0 : return 0;
89 525436 : if ( number == 1.0f && Q == Q15 )
90 0 : return MAX16B;
91 525436 : if ( number == -1.0f && Q == Q15 )
92 0 : return MIN16B;
93 525436 : assert( fabs( number ) < pow( 2, 15 - Q ) );
94 525436 : Word16 ret = (Word16) ( number * ( (UWord16) 1 << Q ) );
95 525436 : return ret;
96 : }
97 :
98 0 : Word16 float_to_fix16_thrld( float number, Word16 Q )
99 : {
100 0 : assert( Q >= 0 );
101 0 : if ( number == 1.0f && Q == Q15 )
102 0 : return MAX16B;
103 0 : float limit = (float) pow( 2, 15 - Q );
104 : /*Add threshold*/
105 0 : if ( number > MAX16B_FLT )
106 : {
107 0 : number = MAX16B_FLT;
108 : }
109 0 : else if ( number < MIN16B_FLT )
110 : {
111 0 : number = MIN16B_FLT;
112 : }
113 0 : assert( number <= limit && number >= -limit );
114 0 : Word16 ret = (Word16) ( number * ( (UWord16) 1 << Q ) );
115 0 : return ret;
116 : }
117 :
118 68942 : float fix16_to_float( Word16 number, Word16 Q )
119 : {
120 68942 : assert( Q >= 0 );
121 68942 : float ret = (float) number / ( (UWord16) 1 << Q );
122 68942 : return ret;
123 : }
124 :
125 : // Float to 32-bit Mantissa and Exponent
126 4214584 : void f2me( float n, Word32 *mantissa, Word16 *expo )
127 : {
128 : Word32 e;
129 4214584 : float mf = (float) frexp( n, &e );
130 4214584 : *expo = (Word16) e;
131 4214584 : *mantissa = float_to_fix( mf, Q31 );
132 4214584 : }
133 :
134 : // 32-bit Mantissa and Exponent to Float
135 0 : float me2f( Word32 m, Word16 expo )
136 : {
137 0 : float mf = fix_to_float( m, Q31 );
138 0 : return (float) ldexp( mf, expo );
139 : }
140 :
141 : // Float buffer to 32-bit mantissa buffer and common exponent.
142 72 : void f2me_buf( const float *x, Word32 *m, Word16 *e, const Word32 n )
143 : {
144 72 : Word16 max_e = -32, tmp_e;
145 : Word32 i;
146 :
147 2107364 : for ( i = 0; i < n; i++ )
148 : {
149 2107292 : f2me( x[i], &m[i], &tmp_e );
150 2107292 : max_e = ( max_e > tmp_e ) ? max_e : tmp_e;
151 : }
152 :
153 2107364 : for ( i = 0; i < n; i++ )
154 : {
155 2107292 : f2me( x[i], &m[i], &tmp_e );
156 2107292 : m[i] = L_shr( m[i], max_e - tmp_e );
157 : }
158 :
159 72 : *e = max_e;
160 72 : }
161 :
162 : // 32-bit Mantissa buffer and exponent into float buffer.
163 0 : void me2f_buf( const Word32 *m, const Word16 e, float *out, const Word32 n )
164 : {
165 0 : for ( int i = 0; i < n; i++ )
166 : {
167 0 : out[i] = me2f( m[i], e );
168 : }
169 0 : }
170 :
171 : // Float to 16-bit Mantissa and Exponent
172 0 : void f2me_16( float n, Word16 *mantissa, Word16 *expo )
173 : {
174 : Word32 e;
175 0 : float mf = (float) frexp( n, &e );
176 0 : *expo = (Word16) e;
177 0 : *mantissa = float_to_fix16( mf, 15 );
178 0 : }
179 :
180 : // 16-bit Mantissa and Exponent to Float
181 0 : float me2f_16( Word16 m, Word16 expo )
182 : {
183 0 : float mf = fix16_to_float( m, 15 );
184 0 : return (float) ldexp( mf, expo );
185 : }
186 :
187 : // Float buffer to 16-bit mantissa buffer and common exponent.
188 0 : void f2me_buf_16( const float *x, Word16 *m, Word16 *e, const Word32 n )
189 : {
190 0 : Word16 max_e = -16, tmp_e;
191 : Word32 i;
192 :
193 0 : for ( i = 0; i < n; i++ )
194 : {
195 0 : f2me_16( x[i], &m[i], &tmp_e );
196 0 : max_e = ( max_e > tmp_e ) ? max_e : tmp_e;
197 : }
198 :
199 0 : for ( i = 0; i < n; i++ )
200 : {
201 0 : f2me_16( x[i], &m[i], &tmp_e );
202 0 : m[i] = shr( m[i], max_e - tmp_e );
203 : }
204 :
205 0 : *e = max_e;
206 0 : }
207 :
208 : // 16-bit Mantissa buffer and exponent into float buffer.
209 0 : void me2f_buf_16( const Word16 *m, const Word16 e, float *out, const Word32 n )
210 : {
211 0 : for ( int i = 0; i < n; i++ )
212 : {
213 0 : out[i] = me2f_16( m[i], e );
214 : }
215 0 : }
216 0 : void f2fix( float *var_flt, Word32 *var_fix, Word32 expo )
217 : {
218 0 : *var_fix = (Word32) ( *var_flt * pow( 2, 31 - expo ) );
219 0 : }
220 :
221 0 : void fix2f( Word32 *var_fix, float *var_flt, Word32 expo )
222 : {
223 0 : float mf = fix_to_float( *var_fix, 31 );
224 0 : *var_flt = (float) ldexp( mf, expo );
225 0 : }
226 :
227 0 : void f2fix_16( float *var_flt, Word16 *var_fix, Word32 expo )
228 : {
229 0 : *var_fix = (Word16) ( *var_flt * pow( 2, 15 - expo ) );
230 0 : }
231 :
232 0 : void fix2f_16( Word16 *var_fix, float *var_flt, Word32 expo )
233 : {
234 0 : float mf = fix16_to_float( *var_fix, 15 );
235 0 : *var_flt = (float) ldexp( mf, expo );
236 0 : }
237 :
238 : #undef WMC_TOOL_SKIP
239 :
240 : /*-------------------------------------------------------------------*
241 : * usdequant_fx()
242 : *
243 : * Uniform scalar de-quantizer routine
244 : *
245 : * Applies de-quantization based on scale and round operations.
246 : *-------------------------------------------------------------------*/
247 300452 : Word16 usdequant_fx( /* Qx*/
248 : const Word16 idx, /* i: quantizer index Q0*/
249 : const Word16 qlow, /* i: lowest codebook entry (index 0) Qx*/
250 : const Word16 delta /* i: quantization step Qx-1*/
251 : )
252 : {
253 : Word16 g;
254 : Word32 L_tmp;
255 :
256 : /*g = idx * delta + qlow;*/
257 300452 : L_tmp = L_deposit_l( qlow ); /*Qx */
258 300452 : L_tmp = L_mac( L_tmp, idx, delta ); /*Qx */
259 300452 : g = round_fx_sat( L_shl_sat( L_tmp, 16 ) ); /*Qx */
260 300452 : return ( g );
261 : }
262 :
263 188420 : Word32 usdequant32_fx( /* Qx*/
264 : const Word16 idx, /* i: quantizer index Q0*/
265 : const Word32 qlow, /* i: lowest codebook entry (index 0) Qx*/
266 : const Word32 delta /* i: quantization step Qx-1*/
267 : )
268 : {
269 : Word32 g;
270 : Word64 L_tmp;
271 :
272 : /*g = idx * delta + qlow;*/
273 188420 : L_tmp = W_deposit32_l( qlow ); /*Qx */
274 188420 : L_tmp = W_mac_32_16( L_tmp, delta, idx );
275 188420 : IF( GE_64( L_tmp, MAX_32 ) )
276 : {
277 41249 : g = MAX_32;
278 41249 : move32();
279 : }
280 : ELSE
281 : {
282 147171 : g = W_extract_l( L_tmp ); /*Qx */
283 : }
284 188420 : return ( g );
285 : }
286 :
287 : /*-------------------------------------------------------------------*
288 : * usquant()
289 : *
290 : * Uniform scalar quantizer according to MMSE criterion
291 : * (nearest neighbour in Euclidean space)
292 : *
293 : * Applies quantization based on scale and round operations.
294 : * Index of the winning codeword and the winning codeword itself are returned.
295 : *-------------------------------------------------------------------*/
296 1197618 : Word16 usquant_fx( /* o: index of the winning codeword */
297 : const Word16 x, /* i: scalar value to quantize Qx*/
298 : Word16 *xq, /* o: quantized value Qx*/
299 : const Word16 qlow, /* i: lowest codebook entry (index 0) Qx*/
300 : const Word16 delta, /* i: quantization step Qx-1*/
301 : const Word16 cbsize /* i: codebook size */
302 : )
303 : {
304 : Word16 idx;
305 : Word16 tmp, exp;
306 : Word32 L_tmp;
307 : #ifndef ISSUE_1836_replace_overflow_libcom
308 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
309 : Flag Overflow = 0;
310 : move32();
311 : #endif
312 : #endif
313 :
314 : /* idx = (short)( (x - qlow)/delta + 0.5f); */
315 1197618 : exp = norm_s( delta );
316 1197618 : tmp = div_s( shl( 1, sub( 14, exp ) ), delta ); /*Q(29-exp-(Qx-1))->Q(30-exp-Qx) */
317 : #ifdef ISSUE_1836_replace_overflow_libcom
318 1197618 : L_tmp = L_mult( sub_sat( x, qlow ), tmp ); /*Q(31-exp) */
319 1197618 : idx = extract_l( L_shr_r( L_add( L_tmp, shl_sat( 1, sub( 30, exp ) ) ), sub( 31, exp ) ) ); /*Q0 */
320 : #else
321 : L_tmp = L_mult( sub_o( x, qlow, &Overflow ), tmp ); /*Q(31-exp) */
322 : idx = extract_l( L_shr_r( L_add( L_tmp, shl_o( 1, sub( 30, exp ), &Overflow ) ), sub( 31, exp ) ) ); /*Q0 */
323 : #endif
324 :
325 1197618 : idx = s_min( idx, sub( cbsize, 1 ) );
326 1197618 : idx = s_max( idx, 0 );
327 :
328 : /* *xq = idx*delta + qlow; */
329 1197618 : L_tmp = L_deposit_l( qlow ); /*Qx */
330 1197618 : L_tmp = L_mac( L_tmp, idx, delta ); /*Qx */
331 : #ifdef ISSUE_1836_replace_overflow_libcom
332 1197618 : *xq = round_fx_sat( L_shl_sat( L_tmp, 16 ) ); /*Qx */
333 : #else
334 : *xq = round_fx_o( L_shl_o( L_tmp, 16, &Overflow ), &Overflow ); /*Qx */
335 : #endif
336 1197618 : return idx;
337 : }
338 : /*-------------------------------------------------------------------*
339 : * Dot_product:
340 : *
341 : * Compute scalar product of <x[],y[]> using accumulator.
342 : * Performs no normalization, as opposed to Dot_product12()
343 : *-------------------------------------------------------------------*/
344 51234322 : Word32 Dot_product( /* o : Sum */
345 : const Word16 x[], /* i : 12bits: x vector */
346 : const Word16 y[], /* i : 12bits: y vector */
347 : const Word16 lg /* i : vector length */
348 : )
349 : {
350 : Word16 i;
351 : Word32 L_sum;
352 : Word64 L64_sum;
353 :
354 51234322 : L64_sum = 1;
355 51234322 : move64();
356 3144009533 : FOR( i = 0; i < lg; i++ )
357 : {
358 3092775211 : L64_sum = W_mac_16_16( L64_sum, x[i], y[i] );
359 : }
360 51234322 : L_sum = W_sat_l( L64_sum );
361 51234322 : return L_sum;
362 : }
363 : /*---------------------------------------------------------------------*
364 : * dotp_fx()
365 : *
366 : * Dot product of vector x[] and vector y[]
367 : *---------------------------------------------------------------------*/
368 :
369 1389980 : Word32 dotp_fx( /* o : dot product of x[] and y[] */
370 : const Word16 x[], /* i : vector x[] */
371 : const Word16 y[], /* i : vector y[] */
372 : const Word16 n, /* i : vector length */
373 : Word16 *exp /* (o) : exponent of result (0..+30) */
374 : )
375 : {
376 : Word16 sft;
377 : Word32 L_sum;
378 :
379 1389980 : assert( *exp == 0 );
380 :
381 1389980 : L_sum = L_add( L_shr( Dot_product( x, y, n ), 1 ), 1 );
382 :
383 : /* Normalize acc in Q31 */
384 :
385 1389980 : sft = norm_l( L_sum );
386 1389980 : L_sum = L_shl( L_sum, sft );
387 :
388 1389980 : *exp = sub( 30, sft );
389 1389980 : move16(); /* exponent = 0..30 */
390 :
391 1389980 : return L_sum;
392 : }
393 :
394 396065 : Word32 sum2_fx( /* o : sum of all squared vector elements Q(2x+1)*/
395 : const Word16 *vec, /* i : input vector Qx*/
396 : const Word16 lvec /* i : length of input vector */
397 : )
398 : {
399 : Word16 i;
400 : Word32 L_tmp;
401 : #ifndef ISSUE_1836_replace_overflow_libcom
402 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
403 : Flag Overflow = 0;
404 : move32();
405 : #endif
406 : #endif
407 396065 : L_tmp = L_deposit_l( 0 );
408 30705553 : FOR( i = 0; i < lvec; i++ )
409 : {
410 : #ifdef ISSUE_1836_replace_overflow_libcom
411 30309488 : L_tmp = L_mac_sat( L_tmp, vec[i], vec[i] ); /*Q(2x+1) */
412 : #else
413 : L_tmp = L_mac_o( L_tmp, vec[i], vec[i], &Overflow ); /*Q(2x+1) */
414 : #endif
415 : }
416 :
417 396065 : return L_tmp;
418 : }
419 :
420 131508 : Word64 sum2_fx_no_sat( /* o : sum of all squared vector elements Q(2*Qx)*/
421 : const Word16 *vec, /* i : input vector Qx*/
422 : const Word16 lvec /* i : length of input vector */
423 : )
424 : {
425 : Word16 i;
426 : Word64 sum;
427 :
428 131508 : sum = 0;
429 131508 : move64();
430 56241588 : FOR( i = 0; i < lvec; i++ )
431 : {
432 56110080 : sum = W_mac0_16_16( sum, vec[i], vec[i] ); // 2*Qx
433 : }
434 :
435 131508 : return sum;
436 : }
437 :
438 93375 : Word32 sum_32_fx(
439 : const Word32 *vec, /* i : input vector */
440 : const Word16 lvec, /* i : length of input vector */
441 : Word16 *e )
442 : {
443 : Word16 i, shift;
444 93375 : Word64 tmp = 0;
445 93375 : move64();
446 : Word32 ans;
447 :
448 301777 : FOR( i = 0; i < lvec; i++ )
449 : {
450 208402 : tmp = W_add( tmp, vec[i] ); // e
451 : }
452 93375 : shift = W_norm( tmp );
453 93375 : tmp = W_shl( tmp, shift ); // shift + (31 - e)
454 93375 : ans = W_extract_h( tmp ); // shift + (31 - e) - 32
455 93375 : *e = add( sub( *e, shift ), 32 );
456 93375 : move16();
457 :
458 93375 : return ans;
459 : }
460 :
461 70294 : Word32 sum2_fx_mod( /* o : sum of all squared vector elements Q(2x+1 -5)*/
462 : const Word16 *vec, /* i : input vector Qx*/
463 : const Word16 lvec /* i : length of input vector */
464 : )
465 : {
466 : Word16 i;
467 : Word32 L_tmp;
468 : #ifndef ISSUE_1836_replace_overflow_libcom
469 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
470 : Flag Overflow = 0;
471 : move32();
472 : #endif
473 : #endif
474 :
475 70294 : L_tmp = L_deposit_l( 0 );
476 45058454 : FOR( i = 0; i < lvec; i++ )
477 : {
478 : #ifdef ISSUE_1836_replace_overflow_libcom
479 44988160 : L_tmp = L_add_sat( L_tmp, L_shr( L_mult_sat( vec[i], vec[i] ), 9 ) );
480 : #else
481 : L_tmp = L_add_o( L_tmp, L_shr( L_mult_o( vec[i], vec[i], &Overflow ), 9 ), &Overflow );
482 : #endif
483 : }
484 :
485 70294 : return L_tmp;
486 : }
487 : /*-------------------------------------------------------------------*
488 : * Copy:
489 : *
490 : * Copy vector x[] to y[]
491 : *
492 : *-------------------------------------------------------------------*/
493 176865465 : void Copy(
494 : const Word16 x[], /* i : input vector */
495 : Word16 y[], /* o : output vector */
496 : const Word16 L /* i : vector length */
497 : )
498 : {
499 : Word16 i;
500 :
501 176865465 : IF( y < x )
502 : {
503 17585189660 : FOR( i = 0; i < L; i++ )
504 : {
505 17495282013 : y[i] = x[i];
506 17495282013 : move16();
507 : }
508 :
509 : /* Location of x and y may differ depending on platform/memory allocation. Since IF and ELSE has different complexity count, the early return is used instead of ELSE to ensure the same complexity number regardless of x and y memory addresses. */
510 89907647 : return;
511 : }
512 :
513 17169131725 : FOR( i = L - 1; i >= 0; i-- )
514 : {
515 17082173907 : y[i] = x[i];
516 17082173907 : move16();
517 : }
518 :
519 86957818 : return;
520 : }
521 : /*-------------------------------------------------------------------*
522 : * Copy64:
523 : *
524 : * Copy vector x[] to y[] (64 bits)
525 : *-------------------------------------------------------------------*/
526 8214 : void Copy64(
527 : const Word64 x[], /* i : input vector */
528 : Word64 y[], /* o : output vector */
529 : const Word16 L /* i : vector length */
530 : )
531 : {
532 : Word16 i;
533 8214 : IF( y < x )
534 : {
535 0 : FOR( i = 0; i < L; i++ )
536 : {
537 0 : y[i] = x[i];
538 0 : move64();
539 : }
540 :
541 : /* Location of x and y may differ depending on platform/memory allocation. Since IF and ELSE has different complexity count, the early return is used instead of ELSE to ensure the same complexity number regardless of x and y memory addresses. */
542 0 : return;
543 : }
544 :
545 35814 : FOR( i = L - 1; i >= 0; i-- )
546 : {
547 27600 : y[i] = x[i];
548 27600 : move64();
549 : }
550 :
551 8214 : return;
552 : }
553 :
554 10120249 : void set64_fx(
555 : Word64 y[], /* i/o: Vector to set */
556 : const Word64 a, /* i : Value to set the vector to */
557 : const Word16 N /* i : Lenght of the vector */
558 : )
559 : {
560 : Word16 i;
561 397851773 : FOR( i = 0; i < N; i++ )
562 : {
563 387731524 : y[i] = a;
564 387731524 : move64();
565 : }
566 :
567 10120249 : return;
568 : }
569 :
570 146722 : void Copy_pword(
571 : const PWord16 x[], /* i : input vector */
572 : PWord16 y[], /* o : output vector */
573 : const Word16 L /* i : vector length */
574 : )
575 : {
576 : Word16 i;
577 :
578 146722 : IF( y < x )
579 : {
580 2865090 : FOR( i = 0; i < L; i++ )
581 : {
582 2731118 : y[i].v.im = x[i].v.im;
583 2731118 : y[i].v.re = x[i].v.re;
584 2731118 : move16();
585 2731118 : move16();
586 : }
587 :
588 : /* Location of x and y may differ depending on platform/memory allocation. Since IF and ELSE has different complexity count, the early return is used instead of ELSE to ensure the same complexity number regardless of x and y memory addresses. */
589 133972 : return;
590 : }
591 :
592 792650 : FOR( i = L - 1; i >= 0; i-- )
593 : {
594 779900 : y[i].v.im = x[i].v.im;
595 779900 : y[i].v.re = x[i].v.re;
596 779900 : move16();
597 779900 : move16();
598 : }
599 :
600 12750 : return;
601 : }
602 : /*-------------------------------------------------------------------*
603 : * Copy32:
604 : *
605 : * Copy vector x[] to y[] (32 bits)
606 : *-------------------------------------------------------------------*/
607 320665764 : void Copy32(
608 : const Word32 x[], /* i : input vector */
609 : Word32 y[], /* o : output vector */
610 : const Word16 L /* i : vector length */
611 : )
612 : {
613 : Word16 i;
614 320665764 : IF( y < x )
615 : {
616 35372221041 : FOR( i = 0; i < L; i++ )
617 : {
618 35213441121 : y[i] = x[i];
619 35213441121 : move32();
620 : }
621 :
622 158779920 : return;
623 : }
624 :
625 32470002237 : FOR( i = L - 1; i >= 0; i-- )
626 : {
627 32308116393 : y[i] = x[i];
628 32308116393 : move32();
629 : }
630 : }
631 :
632 86971 : void set8_fx(
633 : Word8 y[], /* i/o: Vector to set */
634 : const Word8 a, /* i : Value to set the vector to */
635 : const Word16 N /* i : Lenght of the vector */
636 : )
637 : {
638 : Word16 i;
639 :
640 49445867 : FOR( i = 0; i < N; i++ )
641 : {
642 49358896 : y[i] = a;
643 49358896 : move16();
644 : }
645 :
646 86971 : return;
647 : }
648 :
649 : /*-------------------------------------------------------------------*
650 : * set16_fx()
651 : * set32_fx()
652 : *
653 : * Set the vector elements to a value
654 : *-------------------------------------------------------------------*/
655 265118329 : void set16_fx(
656 : Word16 y[], /* i/o: Vector to set */
657 : const Word16 a, /* i : Value to set the vector to */
658 : const Word16 N /* i : Lenght of the vector */
659 : )
660 : {
661 : Word16 i;
662 :
663 34631906662 : FOR( i = 0; i < N; i++ )
664 : {
665 34366788333 : y[i] = a;
666 34366788333 : move16();
667 : }
668 :
669 265118329 : return;
670 : }
671 :
672 670298935 : void set32_fx(
673 : Word32 y[], /* i/o: Vector to set */
674 : const Word32 a, /* i : Value to set the vector to */
675 : const Word16 N /* i : Lenght of the vector */
676 : )
677 : {
678 : Word16 i;
679 :
680 66776738762 : FOR( i = 0; i < N; i++ )
681 : {
682 66106439827 : y[i] = a;
683 66106439827 : move32();
684 : }
685 :
686 670298935 : return;
687 : }
688 : /*-------------------------------------------------------------------*
689 : * Copy_Scale_sig
690 : *
691 : * Up/down scale a 16 bits vector x and move it into y
692 : *-------------------------------------------------------------------*/
693 20160305 : void Copy_Scale_sig(
694 : const Word16 x[], /* i : signal to scale input Qx */
695 : Word16 y[], /* o : scaled signal output Qx */
696 : const Word16 lg, /* i : size of x[] Q0 */
697 : const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */
698 : )
699 : {
700 : Word16 i;
701 : Word16 tmp;
702 : #ifndef ISSUE_1836_replace_overflow_libcom
703 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
704 : Flag Overflow = 0;
705 : move32();
706 : #endif
707 : #endif
708 20160305 : IF( exp0 == 0 )
709 : {
710 1962459905 : FOR( i = 0; i < lg; i++ )
711 : {
712 1958809919 : y[i] = x[i];
713 1958809919 : move16();
714 : }
715 3649986 : return;
716 : }
717 16510319 : IF( exp0 < 0 )
718 : {
719 12621075 : tmp = shl( -32768, exp0 ); /* we use negative to correctly represent 1.0 */
720 5539962438 : FOR( i = 0; i < lg; i++ )
721 : {
722 5527341363 : y[i] = msu_r( 0, x[i], tmp );
723 5527341363 : move16();
724 : }
725 12621075 : return;
726 : }
727 2020655445 : FOR( i = 0; i < lg; i++ )
728 : {
729 : #ifdef ISSUE_1836_replace_overflow_libcom
730 2016766201 : y[i] = shl_sat( x[i], exp0 );
731 : #else
732 : y[i] = shl_o( x[i], exp0, &Overflow );
733 : #endif
734 2016766201 : move16(); /* saturation can occur here */
735 : }
736 : }
737 : /*-------------------------------------------------------------------*
738 : * Copy_Scale_sig
739 : *
740 : * Up/down scale a 16 bits vector x and move it into y
741 : *-------------------------------------------------------------------*/
742 3703527 : void Copy_Scale_sig_16_32_DEPREC(
743 : const Word16 x[], /* i : signal to scale input Qx */
744 : Word32 y[], /* o : scaled signal output Qx */
745 : const Word16 lg, /* i : size of x[] Q0 */
746 : const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */
747 : )
748 : {
749 : Word16 i;
750 : Word16 tmp;
751 : #ifndef ISSUE_1836_replace_overflow_libcom
752 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
753 : Flag Overflow = 0;
754 : move32();
755 : #endif
756 : #endif
757 :
758 :
759 3703527 : IF( exp0 == 0 )
760 : {
761 1097287870 : FOR( i = 0; i < lg; i++ )
762 : {
763 1095090667 : y[i] = L_deposit_l( x[i] );
764 1095090667 : move32();
765 : }
766 2197203 : return;
767 : }
768 1506324 : IF( exp0 < 0 )
769 : {
770 : /*Should not happen */
771 61691106 : FOR( i = 0; i < lg; i++ )
772 : {
773 : #ifdef ISSUE_1836_replace_overflow_libcom
774 61512748 : y[i] = L_deposit_l( shl_sat( x[i], exp0 ) );
775 : #else
776 : y[i] = L_deposit_l( shl_o( x[i], exp0, &Overflow ) );
777 : #endif
778 61512748 : move32();
779 : }
780 178358 : return;
781 : }
782 : #ifdef DEBUGGING
783 : if ( exp0 >= 16 )
784 : {
785 : printf( "Issue in Copy_Scale_sig_16_32_DEPREC\n" );
786 : }
787 : #else
788 1327966 : assert( exp0 < 16 );
789 : #endif
790 : #ifdef ISSUE_1836_replace_overflow_libcom
791 1327966 : tmp = shl_sat( 1, exp0 );
792 : #else
793 : tmp = shl_o( 1, exp0, &Overflow );
794 : #endif
795 421457972 : FOR( i = 0; i < lg; i++ )
796 : {
797 420130006 : y[i] = L_mult0( x[i], tmp );
798 420130006 : move32(); /* saturation can occur here */
799 : }
800 : }
801 :
802 16810513 : void Copy_Scale_sig_16_32_no_sat(
803 : const Word16 x[], /* i : signal to scale input Qx */
804 : Word32 y[], /* o : scaled signal output Qx */
805 : const Word16 lg, /* i : size of x[] Q0 */
806 : const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */
807 : )
808 : {
809 : Word16 i;
810 : Word32 L_tmp;
811 : #ifndef ISSUE_1836_replace_overflow_libcom
812 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
813 : Flag Overflow = 0;
814 : move32();
815 : #endif
816 : #endif
817 :
818 :
819 16810513 : IF( exp0 == 0 )
820 : {
821 572200102 : FOR( i = 0; i < lg; i++ )
822 : {
823 569980919 : y[i] = L_deposit_l( x[i] );
824 569980919 : move32();
825 : }
826 2219183 : return;
827 : }
828 14591330 : IF( exp0 < 0 )
829 : {
830 : /*Should not happen */
831 273541668 : FOR( i = 0; i < lg; i++ )
832 : {
833 : #ifdef ISSUE_1836_replace_overflow_libcom
834 272884714 : y[i] = L_deposit_l( shl_sat( x[i], exp0 ) );
835 : #else
836 : y[i] = L_deposit_l( shl_o( x[i], exp0, &Overflow ) );
837 : #endif
838 272884714 : move32();
839 : }
840 656954 : return;
841 : }
842 : #ifdef ISSUE_1836_replace_overflow_libcom
843 13934376 : L_tmp = L_shl_sat( 1, exp0 - 1 );
844 : #else
845 : L_tmp = L_shl_o( 1, exp0 - 1, &Overflow );
846 : #endif
847 :
848 13934376 : IF( L_tmp >= 0x7FFF )
849 : {
850 1541747252 : FOR( i = 0; i < lg; i++ )
851 : {
852 : // y[i] = L_mult0(x[i], L_tmp);
853 1539129961 : y[i] = W_extract_l( W_mult_32_16( L_tmp, x[i] ) );
854 1539129961 : move32(); /* Overflow can occur here */
855 : }
856 2617291 : return;
857 : }
858 : // ELSE
859 : {
860 11317085 : Word16 tmp = extract_l( L_tmp );
861 5218173985 : FOR( i = 0; i < lg; i++ )
862 : {
863 5206856900 : y[i] = L_mult( x[i], tmp );
864 5206856900 : move32();
865 : }
866 : }
867 : }
868 :
869 10263768 : void Copy_Scale_sig_32_16(
870 : const Word32 x[], /* i : signal to scale input Qx */
871 : Word16 y[], /* o : scaled signal output Qx */
872 : const Word16 lg, /* i : size of x[] Q0 */
873 : const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */
874 : )
875 : {
876 : Word16 i;
877 : Word16 tmp;
878 : #ifndef ISSUE_1836_replace_overflow_libcom
879 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
880 : Flag Overflow = 0;
881 : move32();
882 : #endif
883 : #endif
884 :
885 10263768 : tmp = add( 16, exp0 );
886 10263768 : IF( tmp != 0 )
887 : {
888 6744362302 : FOR( i = 0; i < lg; i++ )
889 : {
890 : #ifdef ISSUE_1836_replace_overflow_libcom
891 6734427596 : y[i] = round_fx_sat( L_shl_sat( x[i], tmp ) );
892 : #else
893 : y[i] = round_fx_o( L_shl_o( x[i], tmp, &Overflow ), &Overflow );
894 : #endif
895 6734427596 : move16();
896 : }
897 : }
898 : ELSE
899 : {
900 85833472 : FOR( i = 0; i < lg; i++ )
901 : {
902 : #ifdef ISSUE_1836_replace_overflow_libcom
903 85504410 : y[i] = round_fx_sat( x[i] );
904 : #else
905 : y[i] = round_fx_o( x[i], &Overflow );
906 : #endif
907 85504410 : move16();
908 : }
909 : }
910 10263768 : }
911 :
912 : /*-------------------------------------------------------------------*
913 : * Scale_sig32
914 : *
915 : * Up/down scale a 32 bits vector
916 : *-------------------------------------------------------------------*/
917 112112567 : void Scale_sig32(
918 : Word32 x[], /* i/o: signal to scale Qx */
919 : const Word16 lg, /* i : size of x[] Q0 */
920 : const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */
921 : )
922 : {
923 : Word16 i;
924 : #ifndef ISSUE_1836_replace_overflow_libcom
925 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
926 : Flag Overflow = 0;
927 : move32();
928 : #endif
929 : #endif
930 112112567 : IF( 0 == exp0 )
931 : {
932 32110348 : return;
933 : }
934 :
935 29605660366 : FOR( i = 0; i < lg; i++ )
936 : {
937 : #ifdef ISSUE_1836_replace_overflow_libcom
938 29525658147 : x[i] = L_shl_sat( x[i], exp0 );
939 : #else
940 : x[i] = L_shl_o( x[i], exp0, &Overflow );
941 : #endif
942 29525658147 : move32(); /* saturation can occur here */
943 : }
944 : }
945 :
946 : /*------------------------------------------------------------------*
947 : * function Random_Fill
948 : *
949 : * Signed 16 bits random generator.
950 : * (Avoids Store of Seed to Memory for 'n' Random Values and
951 : * Combines Scaling Operation.)
952 : *------------------------------------------------------------------*/
953 62672 : void Random_Fill(
954 : Word16 *seed, /* i/o: random seed */
955 : Word16 n, /* i : number of values */
956 : Word16 *y, /* o : output values */
957 : Word16 scaling /* i : scaling of values */
958 : )
959 : {
960 : Word16 i;
961 : Word16 local_seed;
962 :
963 62672 : local_seed = *seed;
964 62672 : move16();
965 5849232 : FOR( i = 0; i < n; i++ )
966 : {
967 5786560 : local_seed = extract_l( L_mac0( 13849L, local_seed, 31821 ) );
968 5786560 : *y++ = shr( local_seed, scaling );
969 5786560 : move16();
970 : }
971 62672 : *seed = local_seed;
972 62672 : move16();
973 62672 : }
974 : /*-------------------------------------------------------------------*
975 : * Scale_sig
976 : * Up/down scale a 16 bits vector
977 : *-------------------------------------------------------------------*/
978 89421030 : void Scale_sig(
979 : Word16 x[], /* i/o: signal to scale Qx */
980 : const Word16 lg, /* i : size of x[] Q0 */
981 : const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */
982 : )
983 : {
984 : Word16 i;
985 : Word16 tmp;
986 :
987 89421030 : IF( exp0 > 0 )
988 : {
989 9909085040 : FOR( i = 0; i < lg; i++ )
990 : {
991 9889299077 : x[i] = shl_sat( x[i], exp0 );
992 9889299077 : move16(); /* saturation can occur here */
993 : }
994 19785963 : return;
995 : }
996 69635067 : IF( exp0 < 0 )
997 : {
998 36258107 : tmp = shl_sat( -32768, exp0 ); /* we use negative to correctly represent 1.0 */
999 14755156941 : FOR( i = 0; i < lg; i++ )
1000 : {
1001 14718898834 : x[i] = msu_r_sat( 0, x[i], tmp );
1002 14718898834 : move16(); /* msu instead of mac because factor is negative */
1003 : }
1004 36258107 : return;
1005 : }
1006 : }
1007 :
1008 : /*-------------------------------------------------------------------*
1009 : * scale_sig
1010 : * Up/down scale a 16 bits vector
1011 : *-------------------------------------------------------------------*/
1012 9160317 : void scale_sig(
1013 : Word16 x[], /* i/o: signal to scale Qx */
1014 : const Word16 lg, /* i : size of x[] Q0 */
1015 : const Word16 exp0 /* i : exponent: x = round(x << exp) Qx exp */
1016 : )
1017 : {
1018 : Word16 i;
1019 :
1020 9160317 : IF( exp0 != 0 )
1021 : {
1022 2347871685 : FOR( i = 0; i < lg; i++ )
1023 : {
1024 2341940950 : x[i] = shl( x[i], exp0 );
1025 2341940950 : move16();
1026 : }
1027 : }
1028 9160317 : }
1029 :
1030 : /*---------------------------------------------------------------------*
1031 : * mean_fx()
1032 : *
1033 : *---------------------------------------------------------------------*/
1034 33065 : Word16 mean_fx( /* o : mean of vector */
1035 : const Word16 *vec_fx, /* i : input vector */
1036 : const Word16 lvec_fx /* i : length of input vector */
1037 : )
1038 : {
1039 : Word16 tmp;
1040 : // PMT("TBV : this function could be written differently to minimize the risk of saturation");
1041 33065 : tmp = sum16_fx( vec_fx, lvec_fx );
1042 33065 : tmp = mult_r( tmp, div_s( 1, lvec_fx ) );
1043 :
1044 33065 : return tmp;
1045 : }
1046 :
1047 21405 : Word16 mean_no_sat_fx( /* o : mean of vector Qx */
1048 : const Word16 *vec_fx, /* i : input vector Qx */
1049 : const Word16 lvec_fx /* i : length of input vector */
1050 : )
1051 : {
1052 : Word16 i;
1053 21405 : Word32 L_tmp = 0;
1054 21405 : move32();
1055 706365 : FOR( i = 0; i < lvec_fx; ++i )
1056 : {
1057 684960 : L_tmp = L_add( L_tmp, vec_fx[i] );
1058 : }
1059 21405 : L_tmp = Mpy_32_16_1( L_tmp, div_s( 1, lvec_fx ) ); /* Qx */
1060 :
1061 21405 : return extract_l( L_tmp );
1062 : }
1063 7424 : Word32 mean_no_sat_Word32_fx( /* o : mean of vector Qx */
1064 : const Word32 *vec_fx, /* i : input vector Qx */
1065 : const Word16 lvec_fx, /* i : length of input vector */
1066 : const Word16 gb )
1067 : {
1068 : Word16 i;
1069 7424 : Word32 L_tmp = 0;
1070 7424 : move32();
1071 37120 : FOR( i = 0; i < lvec_fx; ++i )
1072 : {
1073 29696 : L_tmp = L_add( L_tmp, L_shr( vec_fx[i], gb ) );
1074 : }
1075 7424 : L_tmp = Mpy_32_16_1( L_tmp, div_s( 1, lvec_fx ) ); /* Qx-gb */
1076 :
1077 7424 : return L_tmp;
1078 : }
1079 : /*-------------------------------------------------------------------*
1080 : * Vr_add
1081 : *
1082 : * Add two Word16 vectors together integer by integer
1083 : *-------------------------------------------------------------------*/
1084 3955150 : void Vr_add(
1085 : const Word16 *in1, /* i : Input vector 1 */
1086 : const Word16 *in2, /* i : Input vector 2 */
1087 : Word16 *out, /* o : Output vector that contains vector 1 + vector 2 */
1088 : Word16 Len /* i : Vector lenght */
1089 : )
1090 : {
1091 : Word16 i;
1092 :
1093 100845358 : FOR( i = 0; i < Len; i++ )
1094 : {
1095 96890208 : out[i] = add_sat( in1[i], in2[i] );
1096 96890208 : move16();
1097 : }
1098 3955150 : }
1099 :
1100 1429421 : void sort_fx(
1101 : Word16 *r, /* i/o: Vector to be sorted in place */
1102 : Word16 lo, /* i : Low limit of sorting range */
1103 : Word16 up /* I : High limit of sorting range */
1104 : )
1105 : {
1106 : Word16 i, j, i1;
1107 : Word16 tempr;
1108 :
1109 22865400 : FOR( i = sub( up, 1 ); i >= lo; i-- )
1110 : {
1111 21435979 : i1 = add( i, 1 );
1112 21435979 : tempr = r[i];
1113 21435979 : move16();
1114 21435979 : move16(); /*supplementary move for the j-1 PTR initialization*/
1115 21457595 : FOR( j = i1; j <= up; j++ )
1116 : {
1117 21456539 : IF( LE_16( tempr, r[j] ) )
1118 : {
1119 21434923 : BREAK;
1120 : }
1121 :
1122 21616 : r[j - 1] = r[j];
1123 21616 : move16();
1124 : }
1125 21435979 : r[j - 1] = tempr;
1126 21435979 : move16();
1127 : }
1128 1429421 : }
1129 :
1130 6150 : void sort_32_fx(
1131 : Word32 *r, /* i/o: Vector to be sorted in place */
1132 : const Word16 lo, /* i : Low limit of sorting range */
1133 : const Word16 up /* I : High limit of sorting range */
1134 : )
1135 : {
1136 : Word16 i, j;
1137 : Word32 tempr;
1138 164000 : FOR( i = sub( up, 1 ); i >= lo; i-- )
1139 : {
1140 157850 : tempr = r[i];
1141 157850 : move32();
1142 1416574 : FOR( j = add( i, 1 ); j <= up; j++ )
1143 : {
1144 1390083 : IF( LE_32( tempr, r[j] ) )
1145 : {
1146 131359 : BREAK;
1147 : }
1148 1258724 : r[j - 1] = r[j];
1149 1258724 : move32();
1150 : }
1151 :
1152 157850 : r[j - 1] = tempr;
1153 157850 : move32();
1154 : }
1155 :
1156 6150 : return;
1157 : }
1158 :
1159 2701095 : Word16 minimum_fx( /* o : index of the minimum value in the input vector */
1160 : const Word16 *vec_fx, /* i : input vector */
1161 : const Word16 lvec_fx, /* i : length of input vector */
1162 : Word16 *min_fx /* o : minimum value in the input vector */
1163 : )
1164 : {
1165 : Word16 j, ind;
1166 : Word16 tmp;
1167 2701095 : ind = 0;
1168 2701095 : move16();
1169 2701095 : tmp = vec_fx[0];
1170 2701095 : move16();
1171 :
1172 75576330 : FOR( j = 1; j < lvec_fx; j++ )
1173 : {
1174 72875235 : if ( LT_16( vec_fx[j], tmp ) )
1175 : {
1176 1380976 : ind = j;
1177 1380976 : move16();
1178 : /*tmp = vec_fx[j]; move16(); */
1179 : }
1180 72875235 : tmp = s_min( tmp, vec_fx[j] );
1181 : }
1182 :
1183 2701095 : *min_fx = tmp;
1184 2701095 : move16();
1185 :
1186 2701095 : return ind;
1187 : }
1188 :
1189 27396584 : Word16 maximum_fx( /* o : index of the maximum value in the input vector */
1190 : const Word16 *vec_fx, /* i : input vector */
1191 : const Word16 lvec_fx, /* i : length of input vector */
1192 : Word16 *max_fx /* o : maximum value in the input vector */
1193 : )
1194 : {
1195 : Word16 j, ind;
1196 : Word16 tmp;
1197 27396584 : ind = 0;
1198 27396584 : move16();
1199 27396584 : tmp = vec_fx[0];
1200 27396584 : move16();
1201 :
1202 180515441 : FOR( j = 1; j < lvec_fx; j++ )
1203 : {
1204 153118857 : if ( GT_16( vec_fx[j], tmp ) )
1205 : {
1206 26683747 : ind = j;
1207 26683747 : move16();
1208 : }
1209 153118857 : tmp = s_max( tmp, vec_fx[j] );
1210 : }
1211 27396584 : *max_fx = tmp;
1212 27396584 : move16();
1213 :
1214 27396584 : return ind;
1215 : }
1216 :
1217 24536664 : Word16 maximum_exp_fx( /* o : index of the maximum value in the input vector */
1218 : const Word16 *vec_fx, /* i : input vector */
1219 : const Word16 *exp_vec, /* i : exponents of input vector */
1220 : const Word16 lvec_fx /* i : length of input vector */
1221 : )
1222 : {
1223 : Word16 j, ind;
1224 : Word16 tmp, exp;
1225 24536664 : ind = 0;
1226 24536664 : move16();
1227 24536664 : tmp = vec_fx[0];
1228 24536664 : move16();
1229 24536664 : exp = exp_vec[0];
1230 24536664 : move16();
1231 :
1232 698782848 : FOR( j = 1; j < lvec_fx; j++ )
1233 : {
1234 674246184 : IF( LT_16( tmp, shr_sat( vec_fx[j], sub( exp, exp_vec[j] ) ) ) )
1235 : {
1236 121946525 : ind = j;
1237 121946525 : move16();
1238 121946525 : tmp = vec_fx[j];
1239 121946525 : move16();
1240 121946525 : exp = exp_vec[j];
1241 121946525 : move16();
1242 : }
1243 : }
1244 :
1245 24536664 : return ind;
1246 : }
1247 :
1248 : /*---------------------------------------------------------------------*
1249 : * maximum_abs_16_fx()
1250 : *
1251 : * Find index and value of the absolute maximum in a vector
1252 : *---------------------------------------------------------------------*/
1253 :
1254 870116 : Word16 maximum_abs_16_fx( /* o : index of the maximum abs value in the input vector */
1255 : const Word16 *vec, /* i : input vector */
1256 : const Word16 lvec, /* i : length of input vector */
1257 : Word16 *max_val /* o : maximum value in the input vector */
1258 : )
1259 : {
1260 : Word16 j, ind;
1261 : Word16 tmp;
1262 870116 : ind = 0;
1263 870116 : move16();
1264 870116 : tmp = abs_s( vec[0] );
1265 :
1266 104712536 : FOR( j = 1; j < lvec; j++ )
1267 : {
1268 103842420 : if ( GT_16( abs_s( vec[j] ), tmp ) )
1269 : {
1270 4321161 : ind = j;
1271 4321161 : move16();
1272 : }
1273 103842420 : tmp = s_max( tmp, abs_s( vec[j] ) );
1274 : }
1275 870116 : *max_val = tmp;
1276 870116 : move16();
1277 :
1278 870116 : return ind;
1279 : }
1280 :
1281 : /*---------------------------------------------------------------------*
1282 : * minimum_abs32_fx()
1283 : *
1284 : * Find index and value of the absolute minimum in a vector
1285 : *---------------------------------------------------------------------*/
1286 0 : Word16 minimum_abs32_fx( /* o : index of the minimum value in the input vector */
1287 : const Word32 *vec_fx, /* i : input vector */
1288 : const Word16 lvec_fx, /* i : length of input vector */
1289 : Word32 *min_fx /* o : minimum value in the input vector */
1290 : )
1291 : {
1292 : Word16 j, ind;
1293 : Word32 tmp;
1294 0 : ind = 0;
1295 0 : move16();
1296 0 : tmp = vec_fx[0];
1297 0 : move16();
1298 :
1299 0 : FOR( j = 1; j < lvec_fx; j++ )
1300 : {
1301 0 : IF( LT_32( L_abs( vec_fx[j] ), tmp ) )
1302 : {
1303 0 : ind = j;
1304 0 : move16();
1305 : /*tmp = vec_fx[j]; move16(); */
1306 : }
1307 0 : tmp = L_min( tmp, L_abs( vec_fx[j] ) );
1308 : }
1309 :
1310 0 : *min_fx = tmp;
1311 0 : move16();
1312 :
1313 0 : return ind;
1314 : }
1315 :
1316 : /*---------------------------------------------------------------------*
1317 : * minimum_32_fx()
1318 : *
1319 : * Find index and value of the minimum in a vector
1320 : *---------------------------------------------------------------------*/
1321 :
1322 447481 : Word16 minimum_32_fx( /* o : index of the minimum value in the input vector */
1323 : const Word32 *vec_fx, /* i : input vector */
1324 : const Word16 lvec_fx, /* i : length of input vector */
1325 : Word32 *min_fx /* o : minimum value in the input vector */
1326 : )
1327 : {
1328 : Word16 j, ind;
1329 : Word32 tmp;
1330 447481 : ind = 0;
1331 447481 : move16();
1332 447481 : tmp = vec_fx[0];
1333 447481 : move16();
1334 :
1335 1035537 : FOR( j = 1; j < lvec_fx; j++ )
1336 : {
1337 588056 : if ( LT_32( vec_fx[j], tmp ) )
1338 : {
1339 240655 : ind = j;
1340 240655 : move16();
1341 : /*tmp = vec_fx[j]; move32(); */
1342 : }
1343 588056 : tmp = L_min( tmp, vec_fx[j] );
1344 : }
1345 447481 : if ( min_fx != NULL )
1346 : {
1347 348058 : *min_fx = tmp;
1348 : }
1349 447481 : move32();
1350 :
1351 447481 : return ind;
1352 : }
1353 :
1354 : /*---------------------------------------------------------------------*
1355 : * maximum_32_fx()
1356 : *
1357 : * Find index and value of the maximum in a vector
1358 : *---------------------------------------------------------------------*/
1359 :
1360 5571469 : Word16 maximum_32_fx( /* o : index of the maximum value in the input vector */
1361 : const Word32 *vec, /* i : input vector */
1362 : const Word16 lvec, /* i : length of input vector */
1363 : Word32 *max_val /* o : maximum value in the input vector */
1364 : )
1365 : {
1366 : Word16 j, ind;
1367 : Word32 tmp;
1368 5571469 : ind = 0;
1369 5571469 : move16();
1370 5571469 : tmp = vec[0];
1371 5571469 : move16();
1372 :
1373 66841385 : FOR( j = 1; j < lvec; j++ )
1374 : {
1375 61269916 : IF( GT_32( vec[j], tmp ) )
1376 : {
1377 5405660 : ind = j;
1378 5405660 : move16();
1379 : }
1380 61269916 : tmp = L_max( tmp, vec[j] );
1381 : }
1382 5571469 : if ( max_val != NULL )
1383 : {
1384 5557548 : *max_val = tmp;
1385 : }
1386 5571469 : move32();
1387 :
1388 5571469 : return ind;
1389 : }
1390 :
1391 4905909 : Word16 maximum_abs_32_fx( /* o : index of the maximum abs value in the input vector */
1392 : const Word32 *vec, /* i : input vector */
1393 : const Word16 lvec, /* i : length of input vector */
1394 : Word32 *max_val /* o : maximum value in the input vector */
1395 : )
1396 : {
1397 : Word16 j, ind;
1398 : Word32 tmp;
1399 4905909 : ind = 0;
1400 4905909 : move16();
1401 4905909 : tmp = L_abs( vec[0] );
1402 :
1403 1801845650 : FOR( j = 1; j < lvec; j++ )
1404 : {
1405 1796939741 : if ( GT_32( L_abs( vec[j] ), tmp ) )
1406 : {
1407 19377206 : ind = j;
1408 19377206 : move16();
1409 : }
1410 1796939741 : tmp = L_max( tmp, L_abs( vec[j] ) );
1411 : }
1412 4905909 : *max_val = tmp;
1413 4905909 : move32();
1414 :
1415 4905909 : return ind;
1416 : }
1417 :
1418 :
1419 : /*----------------------------------------------------------------
1420 : *Function:
1421 : *Finds number of shifts to normalize a 16-bit array variable.
1422 : *Return value
1423 : *Number of shifts
1424 : *----------------------------------------------------------------*/
1425 92655 : Word16 Exp16Array(
1426 : const Word16 n, /* (i): Array size */
1427 : const Word16 *sx /* (i): Data array */
1428 : )
1429 : {
1430 : Word16 k;
1431 : Word16 exp;
1432 : Word16 sMax;
1433 : Word16 sAbs;
1434 :
1435 92655 : sMax = abs_s( sx[0] );
1436 92655 : move16();
1437 :
1438 5994560 : FOR( k = 1; k < n; k++ )
1439 : {
1440 5901905 : sAbs = abs_s( sx[k] );
1441 5901905 : sMax = s_max( sMax, sAbs );
1442 : }
1443 :
1444 92655 : exp = norm_s( sMax );
1445 92655 : return exp;
1446 : }
1447 :
1448 0 : Word16 Exp32Array(
1449 : const Word16 n, /* (i): Array size */
1450 : const Word32 *sx /* (i): Data array */
1451 : )
1452 : {
1453 : Word16 k;
1454 : Word16 exp;
1455 : Word32 L_Max;
1456 : Word32 L_Abs;
1457 :
1458 0 : L_Max = L_abs( sx[0] );
1459 0 : FOR( k = 1; k < n; k++ )
1460 : {
1461 0 : L_Abs = L_abs( sx[k] );
1462 0 : L_Max = L_max( L_Max, L_Abs );
1463 : }
1464 0 : exp = norm_l( L_Max );
1465 :
1466 0 : if ( L_Max == 0 )
1467 : {
1468 0 : exp = 31;
1469 0 : move16();
1470 : }
1471 0 : return exp;
1472 : }
1473 :
1474 16124 : Word32 sum16_32_fx( /* o : sum of all vector elements Qx*/
1475 : const Word16 *vec, /* i : input vector Qx*/
1476 : const Word16 lvec /* i : length of input vector */
1477 : )
1478 : {
1479 : Word16 i;
1480 : Word32 tmp, L_var;
1481 16124 : tmp = 0;
1482 16124 : move16();
1483 1708778 : FOR( i = 0; i < lvec; i++ )
1484 : {
1485 1692654 : L_var = L_deposit_l( vec[i] );
1486 1692654 : tmp = L_add( tmp, L_var ); /*Qx */
1487 : }
1488 :
1489 16124 : return tmp;
1490 : }
1491 :
1492 2095 : Word32 sum32_sat( /* o : sum of all vector elements Qx*/
1493 : const Word32 *vec, /* i : input vector Qx*/
1494 : const Word16 lvec /* i : length of input vector */
1495 : )
1496 : {
1497 : Word16 i;
1498 : Word32 tmp;
1499 2095 : tmp = 0;
1500 2095 : move16();
1501 136175 : FOR( i = 0; i < lvec; i++ )
1502 : {
1503 134080 : tmp = L_add_sat( tmp, vec[i] ); /*Qx */
1504 : }
1505 :
1506 2095 : return tmp;
1507 : }
1508 :
1509 7351 : Word32 var_fx_32( /* o: variance of vector Qx+16*/
1510 : const Word16 *x, /* i: input vector Qx*/
1511 : const Word16 Qx,
1512 : const Word16 len /* i: length of inputvector */
1513 : )
1514 : {
1515 : Word16 m;
1516 : Word32 v;
1517 : Word16 i;
1518 : Word16 tmp, exp, inv_len;
1519 : Word32 L_tmp;
1520 :
1521 :
1522 7351 : L_tmp = L_add( x[0], 0 );
1523 200275 : FOR( i = 1; i < len; i++ )
1524 : {
1525 192924 : L_tmp = L_add( L_tmp, x[i] ); /*Qx */
1526 : }
1527 7351 : exp = norm_s( len );
1528 7351 : inv_len = div_s( shl( 1, sub( 14, exp ) ), len ); /*Q(29-exp) */
1529 7351 : L_tmp = Mult_32_16( L_tmp, inv_len ); /*Q(14-exp+Qx) */
1530 7351 : m = round_fx( L_shl( L_tmp, add( exp, 2 ) ) ); /*Qx */
1531 :
1532 7351 : v = L_deposit_l( 0 );
1533 207626 : FOR( i = 0; i < len; i++ )
1534 : {
1535 200275 : tmp = sub( x[i], m ); /*Qx */
1536 200275 : v = L_mac0_sat( v, tmp, tmp ); /*(Qx+Qx) */
1537 : }
1538 7351 : L_tmp = Mult_32_16( v, inv_len ); /*Q(14-exp+Qx+Qx) */
1539 7351 : v = L_shl( L_tmp, add( exp, sub( 2, Qx ) ) ); /*Qx+16 */
1540 :
1541 7351 : return v;
1542 : }
1543 :
1544 3712 : Word32 var_fx_32in_32out( /* o: variance of vector Qx*/
1545 : const Word32 *x, /* i: input vector Qx*/
1546 : Word16 *Qx, /*i/o:Q for input/output */
1547 : const Word16 len, /* i: length of inputvector */
1548 : const Word16 gb )
1549 : {
1550 : Word16 i;
1551 : Word16 shift;
1552 : Word32 L_tmp1, L_tmp;
1553 : Word64 W_temp;
1554 :
1555 3712 : L_tmp = mean_no_sat_Word32_fx( x, len, gb ); /*Qx-gb */
1556 3712 : W_temp = 0;
1557 18560 : FOR( i = 0; i < len; i++ )
1558 : {
1559 14848 : L_tmp1 = L_sub( L_shr( x[i], gb ), L_tmp ); /*Qx-gb */
1560 14848 : W_temp = W_add( W_temp, W_mult0_32_32( L_tmp1, L_tmp1 ) ); /*Qx-gb +Qx-gb*/
1561 : }
1562 3712 : shift = W_norm( W_temp );
1563 3712 : L_tmp = Mult_32_16( W_extract_h( W_shl( W_temp, shift ) ), div_s( 1, len ) ); /*Q2*(Qx-gb)+shift -32 */
1564 :
1565 3712 : *Qx = sub( add( shl( sub( *Qx, gb ), 1 ), shift ), 32 );
1566 3712 : move16();
1567 3712 : return L_tmp;
1568 : }
1569 : /*-------------------------------------------------------------------*
1570 : * conv()
1571 : *
1572 : * Convolution between vectors x[] and h[] written to y[]
1573 : * All vectors are of length L. Only the first L samples of the
1574 : * convolution are considered.
1575 : *-------------------------------------------------------------------*/
1576 :
1577 1784491 : Flag conv_fx(
1578 : const Word16 x[], /* i : input vector Q_new*/
1579 : const Word16 h[], /* i : impulse response (or second input vector) Q(15)*/
1580 : Word16 y[], /* o : output vetor (result of convolution) 12 bits*/
1581 : const Word16 L /* i : vector size */
1582 : )
1583 : {
1584 :
1585 : Word16 i, n;
1586 : Word32 L_sum;
1587 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1588 1784491 : Flag Overflow = 0;
1589 1784491 : move32();
1590 : #endif
1591 1784491 : y[0] = mult_r( x[0], h[0] );
1592 1784491 : move16();
1593 117898112 : FOR( n = 1; n < L; n++ )
1594 : {
1595 116113621 : L_sum = L_mult( x[0], h[n] );
1596 4153655872 : FOR( i = 1; i < n; i++ )
1597 : {
1598 4037542251 : L_sum = L_mac_o( L_sum, x[i], h[n - i], &Overflow );
1599 : }
1600 116113621 : y[n] = mac_ro( L_sum, x[i], h[0], &Overflow );
1601 116113621 : move16();
1602 : }
1603 1784491 : return Overflow;
1604 : }
1605 :
1606 : /*-------------------------------------------------------------------*
1607 : * conv_fx_32()
1608 : *
1609 : * Convolution between vectors x[] and h[] written to y[]
1610 : * All vectors are of length L. Only the first L samples of the
1611 : * convolution are considered.
1612 : *-------------------------------------------------------------------*/
1613 2526 : Flag conv_fx_32(
1614 : const Word16 x[], /* i : input vector Q_new*/
1615 : const Word16 h[], /* i : impulse response (or second input vector) Q(15)*/
1616 : Word32 y[], /* o : output vetor (result of convolution) 12 bits*/
1617 : const Word16 L /* i : vector size */
1618 : )
1619 : {
1620 :
1621 : Word16 i, n;
1622 : Word32 L_sum;
1623 2526 : Flag Overflow = 0;
1624 2526 : y[0] = L_mult( x[0], h[0] );
1625 2526 : move32();
1626 45468 : FOR( n = 1; n < L; n++ )
1627 : {
1628 42942 : L_sum = L_mult( x[0], h[n] );
1629 386478 : FOR( i = 1; i < n; i++ )
1630 : {
1631 343536 : L_sum = L_mac_o( L_sum, x[i], h[n - i], &Overflow );
1632 : }
1633 42942 : y[n] = L_mac_o( L_sum, x[i], h[0], &Overflow );
1634 42942 : move32();
1635 : }
1636 2526 : return Overflow;
1637 : }
1638 579563 : Word16 var_fx( /* o: variance of vector Qx*/
1639 : const Word16 *x, /* i: input vector Qx*/
1640 : const Word16 Qx,
1641 : const Word16 len /* i: length of inputvector */
1642 : )
1643 : {
1644 : Word16 m;
1645 : Word32 v;
1646 : Word16 v_16;
1647 : Word16 i;
1648 : Word16 tmp, exp, inv_len;
1649 : Word32 L_tmp;
1650 :
1651 579563 : L_tmp = x[0];
1652 579563 : move32();
1653 4795662 : FOR( i = 1; i < len; i++ )
1654 : {
1655 4216099 : L_tmp = L_add( L_tmp, x[i] ); /*Qx */
1656 : }
1657 579563 : exp = norm_s( len );
1658 579563 : inv_len = div_s( shl( 1, sub( 14, exp ) ), len ); /*Q(29-exp) */
1659 579563 : L_tmp = Mult_32_16( L_tmp, inv_len ); /*Q(14-exp+Qx) */
1660 579563 : m = round_fx( L_shl( L_tmp, add( exp, 2 ) ) ); /*Qx */
1661 :
1662 579563 : v = L_deposit_l( 0 );
1663 5375225 : FOR( i = 0; i < len; i++ )
1664 : {
1665 4795662 : tmp = sub_sat( x[i], m ); /*Qx */
1666 4795662 : v = L_mac0_sat( v, tmp, tmp ); /*(Qx+Qx) */
1667 : }
1668 579563 : L_tmp = Mult_32_16( v, inv_len ); /*Q(14-exp+Qx+Qx) */
1669 579563 : v_16 = round_fx_sat( L_shl_sat( L_tmp, add( exp, sub( 2, Qx ) ) ) ); /*Qx */
1670 :
1671 579563 : return v_16;
1672 : }
1673 :
1674 : /*---------------------------------------------------------------------*
1675 : * std_fx()
1676 : *
1677 : * Calculate the standard deviation of a vector
1678 : *---------------------------------------------------------------------*/
1679 :
1680 6150 : Word16 std_fx( /* o: standard deviation */
1681 : const Word16 x[], /* i: input vector */
1682 : const Word16 len /* i: length of the input vector */
1683 : )
1684 : {
1685 : Word16 i;
1686 : Word32 L_tmp;
1687 : Word16 exp1, exp2, tmp;
1688 : Word32 stdev;
1689 :
1690 6150 : stdev = 0;
1691 6150 : move16();
1692 55350 : FOR( i = 0; i < len; i++ )
1693 : {
1694 49200 : L_tmp = L_mult( x[i], x[i] ); /*29 */
1695 49200 : stdev = L_add( stdev, L_shr( L_tmp, 3 ) ); /*26 */
1696 : }
1697 :
1698 6150 : IF( stdev != 0 )
1699 : {
1700 6150 : exp1 = norm_l( stdev );
1701 6150 : tmp = div_s( 16384, extract_h( L_shl( stdev, exp1 ) ) ); /*15 + 14 - (26 + exp1 - 16) */
1702 6150 : L_tmp = L_mult( tmp, len ); /*15 + 14 - (26 + exp1 - 16) + 1 */
1703 6150 : exp2 = norm_l( L_tmp );
1704 6150 : exp1 = add( sub( exp1, exp2 ), 11 );
1705 6150 : stdev = Isqrt_lc( L_shl( L_tmp, exp2 ), &exp1 ); /*31-exp1 */
1706 6150 : stdev = L_shl( stdev, sub( exp1, 1 ) ); /*30 */
1707 : }
1708 :
1709 :
1710 6150 : return extract_h( stdev );
1711 : }
1712 :
1713 55800 : Word32 dot_product_mat_fx( /* o : the dot product x'*A*x */
1714 : const Word16 *x, /* i : vector x Q15 */
1715 : const Word32 *A, /* i : matrix A Q0*/
1716 : const Word16 m /* i : vector & matrix size */
1717 :
1718 : )
1719 : {
1720 : Word16 i, j;
1721 : Word64 tmp_sum_64;
1722 : Word32 suma, tmp_sum;
1723 : const Word32 *pt_A;
1724 : const Word16 *pt_x;
1725 :
1726 55800 : pt_A = A;
1727 55800 : suma = L_deposit_l( 0 );
1728 :
1729 725400 : FOR( i = 0; i < m; i++ )
1730 : {
1731 669600 : tmp_sum_64 = 0;
1732 669600 : move64();
1733 669600 : pt_x = x;
1734 8704800 : FOR( j = 0; j < m; j++ )
1735 : {
1736 8035200 : tmp_sum_64 = W_mac_32_16( tmp_sum_64, *pt_A, *pt_x ); /*Q0 */
1737 8035200 : pt_A++;
1738 8035200 : pt_x++;
1739 : }
1740 669600 : tmp_sum = W_sat_m( tmp_sum_64 );
1741 669600 : suma = Madd_32_16( suma, tmp_sum, x[i] ); /*Q0 */
1742 : }
1743 55800 : return suma;
1744 : }
1745 : /*-------------------------------------------------------------------*
1746 : * Vr_subt
1747 : *
1748 : * Subtract two Word16 vectors integer by integer
1749 : *-------------------------------------------------------------------*/
1750 2623527 : void Vr_subt(
1751 : const Word16 x1[], /* i : Input vector 1 */
1752 : const Word16 x2[], /* i : Input vector 2 */
1753 : Word16 y[], /* o : Output vector that contains vector 1 - vector 2 */
1754 : Word16 N /* i : Vector lenght */
1755 : )
1756 : {
1757 : Word16 i;
1758 :
1759 44567803 : FOR( i = 0; i < N; i++ )
1760 : {
1761 41944276 : y[i] = sub_sat( x1[i], x2[i] );
1762 41944276 : move16();
1763 : }
1764 2623527 : }
1765 : /*-------------------------------------------------------------------*
1766 : * vquant()
1767 : *
1768 : * Vector quantizer according to MMSE criterion (nearest neighbour in Euclidean space)
1769 : *
1770 : * Searches a given codebook to find the nearest neighbour in Euclidean space.
1771 : * Index of the winning codevector and the winning vector itself are returned.
1772 : *-------------------------------------------------------------------*/
1773 1402 : Word16 vquant_ivas_fx( /* o: index of the winning codevector */
1774 : Word32 x[], /* i: vector to quantize Q25 */
1775 : const Word32 x_mean[], /* i: vector mean to subtract (0 if none) Q25 */
1776 : Word32 xq[], /* o: quantized vector Q25 */
1777 : const Word32 cb[], /* i: codebook Q25 */
1778 : const Word16 dim, /* i: dimension of codebook vectors */
1779 : const Word16 cbsize /* i: codebook size */
1780 : )
1781 : {
1782 : Word16 c, d, idx, j;
1783 : Word32 L_dist, L_tmp, L_mindist;
1784 :
1785 1402 : idx = 0;
1786 1402 : move16();
1787 1402 : L_mindist = MAX_32;
1788 1402 : move32();
1789 1402 : IF( x_mean != 0 )
1790 : {
1791 0 : FOR( d = 0; d < dim; d++ )
1792 : {
1793 : /*x[d] -= x_mean[d]; */
1794 0 : x[d] = L_sub( x[d], x_mean[d] );
1795 0 : move32(); /*Qx */
1796 : }
1797 : }
1798 1402 : j = 0;
1799 1402 : move16();
1800 19330 : FOR( c = 0; c < cbsize; c++ )
1801 : {
1802 17928 : L_dist = 0;
1803 17928 : move32();
1804 :
1805 89640 : FOR( d = 0; d < dim; d++ )
1806 : {
1807 : /*tmp = x[d] - cb[j++];*/
1808 71712 : L_tmp = L_sub( x[d], cb[j++] ); // Q25
1809 71712 : L_dist = L_add( L_dist, Mpy_32_32( L_tmp, L_tmp ) ); // (Q25, Q25) -> Q19
1810 : }
1811 17928 : if ( LT_32( L_dist, L_mindist ) ) // Q19
1812 : {
1813 3119 : idx = c;
1814 3119 : move16();
1815 : }
1816 17928 : L_mindist = L_min( L_mindist, L_dist ); // Q19
1817 : }
1818 1402 : IF( xq == 0 )
1819 : {
1820 0 : return idx;
1821 : }
1822 :
1823 : /*j = idx*dim;*/
1824 1402 : j = i_mult2( idx, dim );
1825 7010 : FOR( d = 0; d < dim; d++ )
1826 : {
1827 5608 : xq[d] = cb[j++]; // Q25
1828 5608 : move32();
1829 : }
1830 1402 : IF( x_mean != 0 )
1831 : {
1832 0 : FOR( d = 0; d < dim; d++ )
1833 : {
1834 : /*xq[d] += x_mean[d]; */
1835 0 : xq[d] = L_add( xq[d], x_mean[d] ); // Q25
1836 0 : move32();
1837 : }
1838 : }
1839 :
1840 1402 : return idx;
1841 : }
1842 :
1843 240726 : Word16 vquant_fx( /* o: index of the winning codevector */
1844 : Word16 x[], /* i: vector to quantize Q13 */
1845 : const Word16 x_mean[], /* i: vector mean to subtract (0 if none) Q13 */
1846 : Word16 xq[], /* o: quantized vector Q13 */
1847 : const Word16 cb[], /* i: codebook Q13 */
1848 : const Word16 dim, /* i: dimension of codebook vectors */
1849 : const Word16 cbsize /* i: codebook size */
1850 : )
1851 : {
1852 : Word16 tmp;
1853 : Word16 c, d, idx, j;
1854 : Word32 L_dist, /*L_tmp,*/ L_mindist;
1855 :
1856 240726 : idx = 0;
1857 240726 : move16();
1858 240726 : L_mindist = MAX_32;
1859 240726 : move32();
1860 240726 : IF( x_mean != 0 )
1861 : {
1862 478367 : FOR( d = 0; d < dim; d++ )
1863 : {
1864 : /*x[d] -= x_mean[d]; */
1865 354738 : x[d] = sub( x[d], x_mean[d] );
1866 354738 : move16(); /*Qx */
1867 : }
1868 : }
1869 240726 : j = 0;
1870 240726 : move16();
1871 8863310 : FOR( c = 0; c < cbsize; c++ )
1872 : {
1873 8622584 : L_dist = 0;
1874 8622584 : move32();
1875 :
1876 37613976 : FOR( d = 0; d < dim; d++ )
1877 : {
1878 : /*tmp = x[d] - cb[j++];*/
1879 28991392 : tmp = sub( x[d], cb[j++] ); /*Qx */
1880 28991392 : L_dist = L_mac0( L_dist, tmp, tmp );
1881 : }
1882 8622584 : if ( LT_32( L_dist, L_mindist ) )
1883 : {
1884 941730 : idx = c;
1885 941730 : move16();
1886 : }
1887 8622584 : L_mindist = L_min( L_mindist, L_dist );
1888 : }
1889 240726 : IF( xq == 0 )
1890 : {
1891 0 : return idx;
1892 : }
1893 :
1894 : /*j = idx*dim;*/
1895 240726 : j = i_mult2( idx, dim );
1896 1063852 : FOR( d = 0; d < dim; d++ )
1897 : {
1898 823126 : xq[d] = cb[j++];
1899 823126 : move16();
1900 : }
1901 240726 : IF( x_mean != 0 )
1902 : {
1903 478367 : FOR( d = 0; d < dim; d++ )
1904 : {
1905 : /*xq[d] += x_mean[d]; */
1906 354738 : xq[d] = add( xq[d], x_mean[d] );
1907 354738 : move16();
1908 : }
1909 : }
1910 :
1911 240726 : return idx;
1912 : }
1913 :
1914 : /*-------------------------------------------------------------------*
1915 : * w_vquant_fx()
1916 : *
1917 : * Vector quantizer according to MMSE criterion (nearest neighbour in Euclidean space)
1918 : *
1919 : * Searches a given codebook to find the nearest neighbour in Euclidean space.
1920 : * Weights are put on the error for each vector element.
1921 : * Index of the winning codevector and the winning vector itself are returned.
1922 : *-------------------------------------------------------------------*/
1923 50070 : Word16 w_vquant_fx(
1924 : Word16 x[], /* i: vector to quantize in Q10 */
1925 : Word16 Qx,
1926 : const Word16 weights[], /* i: error weights in Q0 */
1927 : Word16 xq[], /* o: quantized vector in Q15 */
1928 : const Word16 cb[], /* i: codebook in Q15 */
1929 : const Word16 cbsize, /* i: codebook size */
1930 : const Word16 rev_vect /* i: reverse codebook vectors */
1931 : )
1932 : {
1933 : Word16 tmp;
1934 : Word16 c, idx, j;
1935 : Word32 dist, minDist;
1936 : #ifndef ISSUE_1836_replace_overflow_libcom
1937 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1938 : Flag Overflow = 0;
1939 : move32();
1940 : #endif
1941 : #endif
1942 :
1943 :
1944 50070 : idx = 0;
1945 50070 : move16();
1946 50070 : minDist = 0x7fffffffL;
1947 50070 : move32();
1948 50070 : Qx = sub( 15, Qx );
1949 :
1950 50070 : j = 0;
1951 50070 : move16();
1952 50070 : IF( rev_vect )
1953 : {
1954 1838488 : FOR( c = 0; c < cbsize; c++ )
1955 : {
1956 1826207 : dist = L_deposit_l( 0 );
1957 :
1958 : #ifdef ISSUE_1836_replace_overflow_libcom
1959 1826207 : tmp = sub_sat( x[3], shr( cb[j++], Qx ) );
1960 1826207 : if ( weights[3] != 0 )
1961 : {
1962 1652193 : dist = L_mac0_sat( dist, tmp, tmp );
1963 : }
1964 1826207 : tmp = sub_sat( x[2], shr( cb[j++], Qx ) );
1965 1826207 : if ( weights[2] != 0 )
1966 : {
1967 1694444 : dist = L_mac0_sat( dist, tmp, tmp );
1968 : }
1969 1826207 : tmp = sub_sat( x[1], shr( cb[j++], Qx ) );
1970 1826207 : if ( weights[1] != 0 )
1971 : {
1972 1788879 : dist = L_mac0_sat( dist, tmp, tmp );
1973 : }
1974 1826207 : tmp = sub_sat( x[0], shr( cb[j++], Qx ) );
1975 1826207 : if ( weights[0] != 0 )
1976 : {
1977 1738514 : dist = L_mac0_sat( dist, tmp, tmp );
1978 : }
1979 : #else
1980 : tmp = sub_o( x[3], shr( cb[j++], Qx ), &Overflow );
1981 : if ( weights[3] != 0 )
1982 : {
1983 : dist = L_mac0_o( dist, tmp, tmp, &Overflow );
1984 : }
1985 : tmp = sub_o( x[2], shr( cb[j++], Qx ), &Overflow );
1986 : if ( weights[2] != 0 )
1987 : {
1988 : dist = L_mac0_o( dist, tmp, tmp, &Overflow );
1989 : }
1990 : tmp = sub_o( x[1], shr( cb[j++], Qx ), &Overflow );
1991 : if ( weights[1] != 0 )
1992 : {
1993 : dist = L_mac0_o( dist, tmp, tmp, &Overflow );
1994 : }
1995 : tmp = sub_o( x[0], shr( cb[j++], Qx ), &Overflow );
1996 : if ( weights[0] != 0 )
1997 : {
1998 : dist = L_mac0_o( dist, tmp, tmp, &Overflow );
1999 : }
2000 : #endif
2001 1826207 : if ( LT_32( dist, minDist ) )
2002 : {
2003 131688 : idx = c;
2004 131688 : move16();
2005 : }
2006 1826207 : minDist = L_min( minDist, dist );
2007 : }
2008 :
2009 12281 : IF( xq == 0 )
2010 : {
2011 0 : return idx;
2012 : }
2013 :
2014 12281 : j = shl( idx, 2 );
2015 12281 : xq[3] = cb[j++];
2016 12281 : move16(); /* in Q15 */
2017 12281 : xq[2] = cb[j++];
2018 12281 : move16(); /* in Q15 */
2019 12281 : xq[1] = cb[j++];
2020 12281 : move16(); /* in Q15 */
2021 12281 : xq[0] = cb[j++];
2022 12281 : move16(); /* in Q15 */
2023 : }
2024 : ELSE
2025 : {
2026 2038426 : FOR( c = 0; c < cbsize; c++ )
2027 : {
2028 2000637 : dist = L_deposit_l( 0 );
2029 :
2030 : #ifdef ISSUE_1836_replace_overflow_libcom
2031 2000637 : tmp = sub_sat( x[0], shr( cb[j++], Qx ) );
2032 2000637 : if ( weights[0] != 0 )
2033 : {
2034 1839764 : dist = L_mac0_sat( dist, tmp, tmp );
2035 : }
2036 2000637 : tmp = sub_sat( x[1], shr( cb[j++], Qx ) );
2037 2000637 : if ( weights[1] != 0 )
2038 : {
2039 1893642 : dist = L_mac0_sat( dist, tmp, tmp );
2040 : }
2041 2000637 : tmp = sub_sat( x[2], shr( cb[j++], Qx ) );
2042 2000637 : if ( weights[2] != 0 )
2043 : {
2044 1911124 : dist = L_mac0_sat( dist, tmp, tmp );
2045 : }
2046 2000637 : tmp = sub_sat( x[3], shr( cb[j++], Qx ) );
2047 2000637 : if ( weights[3] != 0 )
2048 : {
2049 1865818 : dist = L_mac0_sat( dist, tmp, tmp );
2050 : }
2051 : #else
2052 : tmp = sub_o( x[0], shr( cb[j++], Qx ), &Overflow );
2053 : if ( weights[0] != 0 )
2054 : {
2055 : dist = L_mac0_o( dist, tmp, tmp, &Overflow );
2056 : }
2057 : tmp = sub_o( x[1], shr( cb[j++], Qx ), &Overflow );
2058 : if ( weights[1] != 0 )
2059 : {
2060 : dist = L_mac0_o( dist, tmp, tmp, &Overflow );
2061 : }
2062 : tmp = sub_o( x[2], shr( cb[j++], Qx ), &Overflow );
2063 : if ( weights[2] != 0 )
2064 : {
2065 : dist = L_mac0_o( dist, tmp, tmp, &Overflow );
2066 : }
2067 : tmp = sub_o( x[3], shr( cb[j++], Qx ), &Overflow );
2068 : if ( weights[3] != 0 )
2069 : {
2070 : dist = L_mac0_o( dist, tmp, tmp, &Overflow );
2071 : }
2072 : #endif
2073 2000637 : if ( LT_32( dist, minDist ) )
2074 : {
2075 196137 : idx = c;
2076 196137 : move16();
2077 : }
2078 2000637 : minDist = L_min( minDist, dist );
2079 : }
2080 :
2081 37789 : IF( xq == 0 )
2082 : {
2083 25035 : return idx;
2084 : }
2085 :
2086 12754 : j = shl( idx, 2 );
2087 12754 : xq[0] = cb[j++];
2088 12754 : move16(); /* in Q15 */
2089 12754 : xq[1] = cb[j++];
2090 12754 : move16(); /* in Q15 */
2091 12754 : xq[2] = cb[j++];
2092 12754 : move16(); /* in Q15 */
2093 12754 : xq[3] = cb[j++];
2094 12754 : move16(); /* in Q15 */
2095 : }
2096 :
2097 25035 : return idx;
2098 : }
2099 : /*-------------------------------------------------------------------*
2100 : * Emaximum:
2101 : *
2102 : * Find index of a maximum energy in a vector
2103 : *-------------------------------------------------------------------*/
2104 20573221 : Word16 emaximum_fx( /* o : return index with max energy value in vector Q0 */
2105 : const Word16 Qvec, /* i : Q of input vector Q0 */
2106 : const Word16 *vec, /* i : input vector Qx */
2107 : const Word16 lvec, /* i : length of input vector Q0 */
2108 : Word32 *ener_max /* o : maximum energy value Q0 */
2109 : )
2110 : {
2111 : Word16 j, ind;
2112 : Word32 L_tmp, L_tmp1;
2113 : Word32 emax;
2114 :
2115 20573221 : emax = L_mult0( vec[0], vec[0] );
2116 20573221 : ind = 0;
2117 20573221 : move16();
2118 :
2119 665839907 : FOR( j = 1; j < lvec; j++ )
2120 : {
2121 645266686 : L_tmp = L_mult0( vec[j], vec[j] );
2122 645266686 : L_tmp1 = L_sub( L_tmp, emax );
2123 645266686 : if ( L_tmp1 > 0 )
2124 : {
2125 82206944 : ind = j;
2126 82206944 : move16();
2127 : }
2128 645266686 : emax = L_max( emax, L_tmp );
2129 : }
2130 :
2131 20573221 : *ener_max = L_shr_sat( emax, add( Qvec, Qvec ) );
2132 20573221 : move32();
2133 :
2134 20573221 : return ind;
2135 : }
2136 :
2137 33899 : Word16 emaximum_32fx( /* o : return index with max energy value in vector Q0 */
2138 : const Word16 Qvec, /* i : Q of input vector Q0 */
2139 : const Word32 *vec, /* i : input vector Qx */
2140 : const Word16 lvec, /* i : length of input vector Q0 */
2141 : Word32 *ener_max /* o : maximum energy value Q0 */
2142 : )
2143 : {
2144 : Word16 j, ind;
2145 : Word64 W_tmp, W_tmp1;
2146 : Word64 emax;
2147 :
2148 33899 : emax = W_mult0_32_32( vec[0], vec[0] );
2149 33899 : ind = 0;
2150 33899 : move16();
2151 :
2152 3239136 : FOR( j = 1; j < lvec; j++ )
2153 : {
2154 3205237 : W_tmp = W_mult0_32_32( vec[j], vec[j] );
2155 3205237 : W_tmp1 = W_sub( W_tmp, emax );
2156 3205237 : if ( W_tmp1 > 0 )
2157 : {
2158 262832 : ind = j;
2159 262832 : move16();
2160 : }
2161 3205237 : if ( LE_64( emax, W_tmp ) )
2162 : {
2163 265524 : emax = W_tmp;
2164 265524 : move64();
2165 : }
2166 : }
2167 :
2168 33899 : *ener_max = W_extract_l( W_shr( emax, add( Qvec, Qvec ) ) );
2169 33899 : move32();
2170 :
2171 33899 : return ind;
2172 : }
2173 :
2174 : /*-------------------------------------------------------------------*
2175 : * mean32:
2176 : *
2177 : * Find the mean of a 32 bits vector
2178 : *-------------------------------------------------------------------*/
2179 4852 : Word32 Mean32( /* o : mean of the elements of the vector */
2180 : const Word32 in[], /* i : input vector */
2181 : const Word16 L /* i : length of input vector */
2182 : )
2183 : {
2184 : Word32 Ltmp;
2185 : Word16 inv_L;
2186 :
2187 4852 : inv_L = INV_BANDS9;
2188 4852 : move16();
2189 4852 : if ( EQ_16( L, 10 ) )
2190 : {
2191 4852 : inv_L = INV_BANDS10;
2192 4852 : move16();
2193 : }
2194 :
2195 4852 : Ltmp = sum32_fx( in, L );
2196 :
2197 4852 : Ltmp = Mult_32_16( Ltmp, inv_L );
2198 :
2199 4852 : return Ltmp;
2200 : }
2201 187973 : Word32 sum32_fx( /* o : sum of all vector elements Qx*/
2202 : const Word32 *vec, /* i : input vector Qx*/
2203 : const Word16 lvec /* i : length of input vector */
2204 : )
2205 : {
2206 : Word16 i;
2207 : Word32 tmp;
2208 :
2209 187973 : tmp = L_deposit_l( 0 );
2210 7055764 : FOR( i = 0; i < lvec; i++ )
2211 : {
2212 6867791 : tmp = L_add_sat( tmp, vec[i] ); /*Qx */
2213 : }
2214 :
2215 187973 : return tmp;
2216 : }
2217 1152954 : Word16 sum16_fx( /* o : sum of all vector elements Qx*/
2218 : const Word16 *vec, /* i : input vector Qx*/
2219 : const Word16 lvec /* i : length of input vector */
2220 : )
2221 : {
2222 : Word16 i;
2223 : Word16 tmp;
2224 1152954 : tmp = 0;
2225 1152954 : move16();
2226 8414302 : FOR( i = 0; i < lvec; i++ )
2227 : {
2228 7261348 : tmp = add_sat( tmp, vec[i] ); /*Qx */
2229 : }
2230 :
2231 1152954 : return tmp;
2232 : }
2233 : /*------------------------------------------------------------------*
2234 : * function Random
2235 : *
2236 : * Signed 16 bits random generator.
2237 : *------------------------------------------------------------------*/
2238 676840939 : Word16 Random( /* o : output random value */
2239 : Word16 *seed /* i/o: random seed */
2240 : )
2241 : {
2242 676840939 : *seed = extract_l( L_mac0( 13849L, *seed, 31821 ) );
2243 676840939 : move16();
2244 676840939 : return *seed;
2245 : }
2246 :
2247 115272 : Word16 own_random2_fx( Word16 seed )
2248 : {
2249 115272 : return extract_l( L_mac0( 13849, seed, 31821 ) );
2250 : }
2251 :
2252 : /*---------------------------------------------------------------------
2253 : * sign_fx()
2254 : *
2255 : *---------------------------------------------------------------------*/
2256 :
2257 : /*! r: sign of x (+1/-1) */
2258 2102172 : Word16 sign_fx(
2259 : const Word32 x /* i : input value of x */
2260 : )
2261 : {
2262 2102172 : IF( LT_32( x, 0 ) )
2263 : {
2264 697824 : return -1;
2265 : }
2266 : ELSE
2267 : {
2268 1404348 : return 1;
2269 : }
2270 : }
2271 :
2272 0 : Word16 sign16_fx(
2273 : const Word16 x /* i : input value of x */
2274 : )
2275 : {
2276 0 : IF( LT_16( x, 0 ) )
2277 : {
2278 0 : return -1;
2279 : }
2280 : ELSE
2281 : {
2282 0 : return 1;
2283 : }
2284 : }
2285 :
2286 : /*------------------------------------------------------------------*
2287 : * function Div_32_optmz
2288 : *
2289 : * Performs 32 bits interger division
2290 : *------------------------------------------------------------------*/
2291 3987877 : static Word32 Div_32_optmz( Word32 L_num, Word16 denom_hi )
2292 : {
2293 : Word16 approx, hi, lo, n_hi, n_lo;
2294 : Word32 L_32;
2295 :
2296 : /* First approximation: 1 / L_denom = 1/denom_hi */
2297 :
2298 3987877 : approx = div_s( (Word16) 0x3fff, denom_hi );
2299 :
2300 : /* 1/L_denom = approx * (2.0 - L_denom * approx) */
2301 :
2302 3987877 : L_32 = L_msu( (Word32) 0x7fffffffL, denom_hi, approx );
2303 :
2304 3987877 : lo = L_Extract_lc( L_32, &hi );
2305 3987877 : L_32 = Mpy_32_16( hi, lo, approx );
2306 :
2307 : /* L_num * (1/L_denom) */
2308 :
2309 3987877 : lo = L_Extract_lc( L_32, &hi );
2310 3987877 : n_lo = L_Extract_lc( L_num, &n_hi );
2311 3987877 : L_32 = Mpy_32( n_hi, n_lo, hi, lo );
2312 :
2313 3987877 : return ( L_32 );
2314 : }
2315 : /*------------------------------------------------------------------*
2316 : * function iDiv_and_mod_32
2317 : *
2318 : * return the quotient and the modulo 32 bits numerator divided by a 16 bit denominator
2319 : * The denominator might be right shifted by 1
2320 : *------------------------------------------------------------------*/
2321 3987877 : void iDiv_and_mod_32(
2322 : const Word32 Numer, /* i : 32 bits numerator */
2323 : const Word16 Denom, /* i : 16 bits denominator */
2324 : Word32 *Int_quotient, /* o : integer result of the division (int)(num/den) */
2325 : Word32 *Int_mod, /* o : modulo result of the division num-((int)(num/den)*den)*/
2326 : const Word16 rshift /* i : 0 if no right shift / 1 if the denom is right shifted by 1 */
2327 : )
2328 : {
2329 : Word32 Quotient;
2330 : Word16 expA, expB;
2331 : Word32 N, TEMP;
2332 : Word16 D;
2333 :
2334 : /* Normalize 'Numer' & 'Denom' */
2335 : /* Use Temporary to Preserve the Original Value */
2336 3987877 : expA = norm_l( Numer );
2337 3987877 : N = L_shl( Numer, expA );
2338 3987877 : expB = norm_s( Denom );
2339 3987877 : D = shl( Denom, expB );
2340 :
2341 : /* Need to shift right 'Numer' by 1? */
2342 3987877 : if ( L_mac( N, D, -32768L ) >= 0 )
2343 : {
2344 2220026 : expA = sub( expA, 1 );
2345 : }
2346 3987877 : N = L_shl( Numer, expA );
2347 :
2348 : /* Perform Approximation of the Division
2349 : * Since 'lo' part is '0' AND 'denom' is supposed to be constant in the targeted usage
2350 : * one could import the Div32 code and pre-calc the div_s and eliminate all calcs
2351 : * with 'lo' to save some complexity */
2352 :
2353 3987877 : Quotient = Div_32_optmz( N, D ); /* takes 36 clocks */
2354 : /* Bring Back to Q0 (minus 2 because we removed the left shift by 2 in the Div32_optmz) */
2355 3987877 : IF( rshift )
2356 : {
2357 0 : Quotient = L_shr( Quotient, add( 15 - 2, sub( expA, sub( expB, 1 ) ) ) );
2358 : }
2359 : ELSE
2360 : {
2361 3987877 : Quotient = L_shr( Quotient, add( 15 - 2, sub( expA, expB ) ) );
2362 : }
2363 :
2364 : /* Cross Check (do Quotient x Divisor)
2365 : * The Quotient is unsigned but we cannot just use extract_h because
2366 : * extract_l on the low part will get the sign of the bit #15.
2367 : * In a 32 bits value, what is in bits 0-15 is un unsigned 16 bits value.
2368 : * So, we shift left by 1, extract the hi part and mult it by 32768 (hence the L_shl by 16-1.
2369 : * Then we take 15 bits left (mask the others) and multiply by Denom.
2370 : * Technically this could overflow. But since we are mutiplying to get
2371 : * back to the Numer value that fitted in a 32 bits, doing Divisor x Quotient
2372 : * must necessarily fit in a 32 bits
2373 : * It is assumed that all are positive values. If not, one could
2374 : * check the sign of the numer and denom, turn them into abs values
2375 : * and restore the sign after*/
2376 3987877 : TEMP = L_shl( L_mult0( extract_h( L_shl( Quotient, 1 ) ), Denom ), 16 - 1 );
2377 3987877 : TEMP = L_mac0( TEMP, extract_l( L_and( 0x7FFF, Quotient ) ), Denom );
2378 :
2379 :
2380 : /* Here we test to see if the previous "Quotient x Divisor" (or TEMP) is too small
2381 : * that is the "Numer" minus TEMP is bigger or Equal to the Divisor.
2382 : * If it is then the quotient is too small. We need to increase it by 1.
2383 : * That is caused by our Div32 fractionnal division that can be off by 1
2384 : * sometimes.
2385 : * In some cases, when the divisor is very small (like 10 or something)
2386 : * the quotient could be off by more than 1 and we would need a loop
2387 : * to check again. That is not the case here with the current divisor */
2388 3987877 : IF( rshift )
2389 : {
2390 0 : TEMP = L_shl( TEMP, 1 );
2391 0 : WHILE( L_msu0( L_sub( Numer, TEMP ), 2, Denom ) >= 0 )
2392 : {
2393 0 : Quotient = L_add( Quotient, 1 );
2394 0 : TEMP = L_shl( L_mult0( extract_h( L_shl( Quotient, 1 ) ), Denom ), 16 - 1 );
2395 0 : TEMP = L_mac0( TEMP, extract_l( L_and( 0x7FFF, Quotient ) ), Denom );
2396 0 : TEMP = L_shl( TEMP, 1 );
2397 : }
2398 : }
2399 : ELSE{
2400 6624423 : WHILE( L_msu0( L_sub( Numer, TEMP ), 1, Denom ) >= 0 ){
2401 2636546 : Quotient = L_add( Quotient, 1 );
2402 2636546 : TEMP = L_shl( L_mult0( extract_h( L_shl( Quotient, 1 ) ), Denom ), 16 - 1 );
2403 2636546 : TEMP = L_mac0( TEMP, extract_l( L_and( 0x7FFF, Quotient ) ), Denom );
2404 : }
2405 : }
2406 3987877 : *Int_quotient = Quotient;
2407 3987877 : move32();
2408 3987877 : IF( L_msu0( L_sub( Numer, TEMP ), 1, Denom ) == 0 )
2409 : {
2410 0 : *Int_mod = 0L;
2411 0 : move32();
2412 : }
2413 : ELSE
2414 : {
2415 3987877 : *Int_mod = L_sub( Numer, TEMP );
2416 3987877 : move32();
2417 : }
2418 3987877 : }
2419 :
2420 : /*===================================================================*/
2421 : /* FUNCTION : pz_filter_sp_fx () */
2422 : /*-------------------------------------------------------------------*/
2423 : /* PURPOSE : Generic pole-zero filter routine, with single */
2424 : /* precision memory */
2425 : /*-------------------------------------------------------------------*/
2426 : /* INPUT ARGUMENTS : */
2427 : /* */
2428 : /* _ (Word16 []) b : zero filter coefficients (Qc). */
2429 : /* _ (Word16 []) a : pole filter coefficients (Qc), a(0)=1 in Qc */
2430 : /* _ (Word16 []) x : input signal (Qn). */
2431 : /* _ (Word16) PNR : NR filter order */
2432 : /* _ (Word16) PDR : DR filter order */
2433 : /* _ (Word16) N : number of input samples. */
2434 : /* _ (Word16) Qa : Q factor compensation (Qa=16-Qc) */
2435 : /*-------------------------------------------------------------------*/
2436 : /* OUTPUT ARGUMENTS : */
2437 : /* */
2438 : /* _ (Word16 []) y : output signal (Qn) */
2439 : /*-------------------------------------------------------------------*/
2440 : /* INPUT/OUTPUT ARGUMENTS : */
2441 : /* */
2442 : /* _ (Word16 []) buf : filter memory (Qn-Qa). */
2443 : /*-------------------------------------------------------------------*/
2444 : /* RETURN ARGUMENTS : _ None. */
2445 : /*===================================================================*/
2446 :
2447 0 : void pz_filter_sp_fx(
2448 : const Word16 b[],
2449 : const Word16 a[],
2450 : Word16 x[],
2451 : Word16 y[],
2452 : Word16 buf[],
2453 : Word16 PNR,
2454 : Word16 PDR,
2455 : Word16 N,
2456 : Word16 Qa )
2457 : {
2458 : Word16 i, j;
2459 : Word16 s;
2460 : Word16 s_mem;
2461 : Word32 Ltemp1;
2462 : Word32 Lacc;
2463 0 : s = negate( Qa );
2464 0 : s = add( s, s ); /* s=-2Qa*/
2465 0 : s = add( s, 1 );
2466 0 : FOR( i = 0; i < N; i++ )
2467 : {
2468 0 : Lacc = L_deposit_h( x[i] ); /* Lacc in Q(16+Qn)*/
2469 0 : Lacc = L_shl( Lacc, s ); /* Lacc=x[i] in Q(16+Qn-2Qa+1)*/
2470 0 : FOR( j = PDR - 1; j >= 0; j-- )
2471 0 : Lacc = L_msu_sat( Lacc, buf[j], a[j + 1] ); /*Q(16+Qn-2Qa+1)*/
2472 :
2473 :
2474 0 : Lacc = L_shr( Lacc, 1 );
2475 0 : Ltemp1 = L_add_sat( L_shl_sat( Lacc, Qa ), 0x08000 );
2476 0 : s_mem = extract_h( Ltemp1 );
2477 :
2478 0 : Lacc = L_deposit_l( 0 );
2479 0 : FOR( j = PNR - 1; j >= 0; j-- )
2480 0 : Lacc = L_mac_sat( Lacc, buf[j], b[j + 1] );
2481 0 : Lacc = L_mac_sat( Lacc, s_mem, b[0] );
2482 : /* Lacc in Q(1+Qc+Qn-Qa)*/
2483 :
2484 0 : FOR( j = s_max( PDR, PNR ) - 1; j > 0; j-- )
2485 : {
2486 : /* Update filter memory */
2487 0 : buf[j] = buf[j - 1];
2488 0 : move16();
2489 : }
2490 0 : buf[0] = s_mem;
2491 0 : move16();
2492 :
2493 0 : Ltemp1 = L_add_sat( L_shr_sat( Lacc, s ), 0x08000 ); /* Ltemp1 in Qc+Qa+Qn=Q(Qn) */
2494 0 : y[i] = extract_h( Ltemp1 ); /* y[i] in Qn */
2495 0 : move16();
2496 : }
2497 0 : }
2498 :
2499 :
2500 208234 : Word32 root_a_fx(
2501 : Word32 a,
2502 : Word16 Q_a,
2503 : Word16 *exp_out )
2504 : {
2505 : Word16 exp, tmp;
2506 : Word32 L_tmp;
2507 :
2508 208234 : IF( a <= 0 )
2509 : {
2510 2794 : *exp_out = 0;
2511 2794 : move16();
2512 2794 : return 0;
2513 : }
2514 :
2515 205440 : exp = norm_l( a );
2516 205440 : tmp = extract_h( L_shl( a, exp ) );
2517 205440 : exp = sub( exp, sub( 30, Q_a ) );
2518 205440 : tmp = div_s( 16384, tmp );
2519 205440 : L_tmp = L_deposit_h( tmp );
2520 205440 : L_tmp = Isqrt_lc( L_tmp, &exp );
2521 :
2522 205440 : *exp_out = exp;
2523 205440 : move16();
2524 :
2525 205440 : return L_tmp;
2526 : }
2527 :
2528 :
2529 1932983 : Word32 root_a_over_b_fx(
2530 : Word32 a, /* Q(Q_a) */
2531 : Word16 Q_a,
2532 : Word32 b, /* Q(Q_b) */
2533 : Word16 Q_b,
2534 : Word16 *exp_out )
2535 : {
2536 : Word16 tmp, num, den, scale;
2537 : Word16 exp, exp_num, exp_den;
2538 : Word32 L_tmp;
2539 : #ifndef ISSUE_1836_replace_overflow_libcom
2540 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
2541 : Flag Overflow = 0;
2542 : move32();
2543 : #endif
2544 : #endif
2545 1932983 : test();
2546 1932983 : IF( ( a <= 0 ) || ( b <= 0 ) )
2547 : {
2548 10103 : *exp_out = 0;
2549 10103 : move16();
2550 10103 : return 0;
2551 : }
2552 :
2553 1922880 : exp_num = norm_l( b );
2554 : #ifdef ISSUE_1836_replace_overflow_libcom
2555 1922880 : num = round_fx_sat( L_shl_sat( b, exp_num ) );
2556 : #else
2557 : num = round_fx_o( L_shl_o( b, exp_num, &Overflow ), &Overflow );
2558 : #endif
2559 1922880 : exp_num = sub( sub( 30, exp_num ), Q_b );
2560 :
2561 1922880 : exp_den = norm_l( a );
2562 : #ifdef ISSUE_1836_replace_overflow_libcom
2563 1922880 : den = round_fx_sat( L_shl_sat( a, exp_den ) );
2564 : #else
2565 : den = round_fx_o( L_shl_o( a, exp_den, &Overflow ), &Overflow );
2566 : #endif
2567 1922880 : exp_den = sub( sub( 30, exp_den ), Q_a );
2568 :
2569 1922880 : scale = shr( sub( den, num ), 15 );
2570 : #ifdef ISSUE_1836_replace_overflow_libcom
2571 1922880 : num = shl_sat( num, scale );
2572 : #else
2573 : num = shl_o( num, scale, &Overflow );
2574 : #endif
2575 1922880 : exp_num = sub( exp_num, scale );
2576 :
2577 1922880 : tmp = div_s( num, den );
2578 1922880 : exp = sub( exp_num, exp_den );
2579 :
2580 1922880 : L_tmp = L_deposit_h( tmp );
2581 1922880 : L_tmp = Isqrt_lc( L_tmp, &exp );
2582 :
2583 1922880 : *exp_out = exp;
2584 1922880 : move16();
2585 :
2586 1922880 : return L_tmp;
2587 : }
2588 :
2589 332590 : Word32 root_a_over_b_ivas_fx(
2590 : Word32 a, /* Q(Q_a) */
2591 : Word16 Q_a,
2592 : Word32 b, /* Q(Q_b) */
2593 : Word16 Q_b,
2594 : Word16 *q_out )
2595 : {
2596 : Word16 shift_a, shift_b, shift;
2597 : Word32 mod_a, mod_b, one_in_Q_a, one_in_Q_b, half_in_Q_a, half_in_Q_b;
2598 : Word32 a_sqr, b_sqr, p0, p1, p2, approx;
2599 : Word16 exp;
2600 :
2601 332590 : test();
2602 332590 : IF( ( a <= 0 ) || ( b <= 0 ) )
2603 : {
2604 0 : *q_out = 0;
2605 0 : move16();
2606 0 : return 0;
2607 : }
2608 :
2609 332590 : one_in_Q_a = L_shl( 1, Q_a ); // 1.0f in Q_a
2610 332590 : one_in_Q_b = L_shl( 1, Q_b ); // 1.0f in Q_b
2611 332590 : half_in_Q_a = L_shr( one_in_Q_a, 1 ); // 0.5f in Q_a
2612 332590 : half_in_Q_b = L_shr( one_in_Q_b, 1 ); // 0.5f in Q_b
2613 :
2614 332590 : a = L_add( a, one_in_Q_a );
2615 332590 : b = L_add( b, one_in_Q_b );
2616 :
2617 : /* This next piece of code implements a "norm" function */
2618 : /* and returns the shift needed to scale "a" to have a */
2619 : /* 1 in the (MSB-1) position. This is equivalent to */
2620 : /* giving a value between 0.5 & 1.0. */
2621 :
2622 332590 : mod_a = a;
2623 332590 : move32();
2624 :
2625 332590 : shift_a = 0;
2626 332590 : move16();
2627 665180 : WHILE( GT_32( mod_a, one_in_Q_a ) )
2628 : {
2629 332590 : mod_a = L_shr( mod_a, 1 );
2630 332590 : shift_a = sub( shift_a, 1 );
2631 : }
2632 :
2633 332590 : WHILE( LT_32( mod_a, half_in_Q_a ) )
2634 : {
2635 0 : mod_a = L_shl( mod_a, 1 );
2636 0 : shift_a = add( shift_a, 1 );
2637 : }
2638 :
2639 332590 : shift_a = s_and( shift_a, -2 );
2640 332590 : mod_a = L_shl( a, shift_a ); // Q_a
2641 :
2642 : /* This next piece of code implements a "norm" function */
2643 : /* and returns the shift needed to scale "b" to have a */
2644 : /* 1 in the (MSB-1) position. This is equivalent to */
2645 : /* giving a value between 0.5 & 1.0. */
2646 332590 : mod_b = b;
2647 332590 : move32();
2648 :
2649 332590 : shift_b = 0;
2650 332590 : move16();
2651 665180 : WHILE( GT_32( mod_b, one_in_Q_b ) )
2652 : {
2653 332590 : mod_b = L_shr( mod_b, 1 );
2654 332590 : shift_b = sub( shift_b, 1 );
2655 : }
2656 :
2657 332590 : WHILE( LT_32( mod_b, half_in_Q_b ) )
2658 : {
2659 0 : mod_b = L_shl( mod_b, 1 );
2660 0 : shift_b = add( shift_b, 1 );
2661 : }
2662 :
2663 332590 : shift_b = s_and( shift_b, -2 );
2664 332590 : mod_b = L_shl( b, shift_b ); // Q_b
2665 :
2666 332590 : shift = shr( sub( shift_b, shift_a ), 1 );
2667 :
2668 332590 : a_sqr = W_extract_h( W_shl( W_mult0_32_32( mod_a, mod_a ), sub( 32, Q_a ) ) ); // Q_a
2669 332590 : b_sqr = W_extract_h( W_shl( W_mult0_32_32( mod_b, mod_b ), sub( 32, Q_b ) ) ); // Q_b
2670 :
2671 332590 : p2 = L_shl( -408505077 /* -0.7609f in Q29 */, sub( Q_b, 31 ) ); // Qb-2
2672 332590 : p1 = L_shl( 1444612250 /* 2.6908f in Q29 */, sub( Q_b, 31 ) ); // Qb-2
2673 332590 : p0 = L_shl( 385258566 /* 0.7176f in Q29 */, sub( Q_b, 31 ) ); // Qb-2
2674 :
2675 332590 : p2 = Madd_32_32( Madd_32_32( p2, 501759554 /* 0.9346f in Q29*/, mod_b ), -252060893 /* -0.4695f in Q29 */, b_sqr ); // Q_b-2
2676 332590 : p1 = Madd_32_32( Madd_32_32( p1, -1774680487 /* -3.3056f in Q29 */, mod_b ), 891635211 /* 1.6608f in Q29 */, b_sqr ); // Q_b-2
2677 332590 : p0 = Madd_32_32( Madd_32_32( p0, -473251709 /* -0.8815f in Q29 */, mod_b ), 237780127 /* 0.4429f in Q29 */, b_sqr ); // Q_b-2
2678 :
2679 : /* approx = p0 + p1 * mod_a + p2 * mod_a * mod_a; */
2680 332590 : approx = Madd_32_32( Mpy_32_32( p1, mod_a ), p2, a_sqr ); // Q_a+Q_b-33
2681 332590 : approx = L_add( approx, L_shl( p0, sub( Q_a, 31 ) ) ); // Q_a+Q_b-33
2682 :
2683 332590 : exp = sub( norm_l( approx ), 1 );
2684 332590 : approx = L_shl( approx, exp ); // // Q_a+Q_b-33+exp
2685 :
2686 332590 : *q_out = sub( add( sub( add( Q_a, Q_b ), 33 ), exp ), shift );
2687 332590 : move16();
2688 :
2689 332590 : return approx;
2690 : }
2691 :
2692 : /*===================================================================*/
2693 : /* FUNCTION : fir_fx () */
2694 : /*-------------------------------------------------------------------*/
2695 : /* PURPOSE : Generic FIR filter routine */
2696 : /*-------------------------------------------------------------------*/
2697 : /* INPUT ARGUMENTS : */
2698 : /* */
2699 : /* _ (Word16 []) b : filter coefficients (Qc). */
2700 : /* _ (Word16 []) x : input signal (Qn). */
2701 : /* _ (Word16) P : filter order. */
2702 : /* _ (Word16) N : number of input samples. */
2703 : /* _ (Word16) Qa : Q factor compensation (Qa=16-Qc) */
2704 : /*-------------------------------------------------------------------*/
2705 : /* OUTPUT ARGUMENTS : */
2706 : /* */
2707 : /* _ (Word16 []) y : output signal (Qn) */
2708 : /*-------------------------------------------------------------------*/
2709 : /* INPUT/OUTPUT ARGUMENTS : */
2710 : /* */
2711 : /* _ : None */
2712 : /*-------------------------------------------------------------------*/
2713 : /* RETURN ARGUMENTS : _ None. */
2714 : /*===================================================================*/
2715 252993 : void fir_fx( const Word16 x[], /* i : input vector Qx*/
2716 : const Word16 h[], /* i : impulse response of the FIR filter Q12*/
2717 : Word16 y[], /* o : output vector (result of filtering) Qx*/
2718 : Word16 mem[], /* i/o: memory of the input signal (L samples) Qx*/
2719 : const Word16 L, /* i : input vector size */
2720 : const Word16 K, /* i : order of the FIR filter (K+1 coefs.) */
2721 : const Word16 upd /* i : 1 = update the memory, 0 = not */
2722 : ,
2723 : Word16 shift /* i : difference between Q15 and scaling of h[] */
2724 : )
2725 : {
2726 :
2727 : Word16 buf_in[L_FRAME32k + L_FILT_MAX];
2728 : Word16 i, j;
2729 : Word32 s;
2730 : #ifndef ISSUE_1836_replace_overflow_libcom
2731 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
2732 : Flag Overflow = 0;
2733 : move32();
2734 : #endif
2735 : #endif
2736 : /* prepare the input buffer (copy and update memory) */
2737 252993 : Copy( mem, buf_in, K );
2738 252993 : Copy( x, buf_in + K, L );
2739 252993 : IF( upd )
2740 : {
2741 153 : Copy( buf_in + L, mem, K );
2742 : }
2743 :
2744 : /* do the filtering */
2745 77872261 : FOR( i = 0; i < L; i++ )
2746 : {
2747 : #ifdef ISSUE_1836_replace_overflow_libcom
2748 77619268 : s = L_mult_sat( buf_in[K + i], h[0] );
2749 : #else
2750 : s = L_mult_o( buf_in[K + i], h[0], &Overflow );
2751 : #endif
2752 :
2753 417451572 : FOR( j = 1; j <= K; j++ )
2754 : {
2755 : #ifdef ISSUE_1836_replace_overflow_libcom
2756 339832304 : s = L_mac_sat( s, h[j], buf_in[K + i - j] );
2757 : #else
2758 : s = L_mac_o( s, h[j], buf_in[K + i - j], &Overflow );
2759 : #endif
2760 : }
2761 : #ifdef ISSUE_1836_replace_overflow_libcom
2762 77619268 : s = L_shl_sat( s, shift );
2763 77619268 : y[i] = round_fx_sat( s ); /*Qx */
2764 : #else
2765 : s = L_shl_o( s, shift, &Overflow );
2766 : y[i] = round_fx_o( s, &Overflow ); /*Qx */
2767 : #endif
2768 77619268 : move16();
2769 : }
2770 252993 : }
2771 :
2772 : /*-------------------------------------------------------------------*
2773 : * v_add_32()
2774 : *
2775 : * Addition of two vectors sample by sample
2776 : *-------------------------------------------------------------------*/
2777 :
2778 5738932 : void v_add_32(
2779 : const Word32 x1[], /* i : Input vector 1 */
2780 : const Word32 x2[], /* i : Input vector 2 */
2781 : Word32 y[], /* o : Output vector that contains vector 1 + vector 2 */
2782 : const Word16 N /* i : Vector length */
2783 : )
2784 : {
2785 : Word16 i;
2786 :
2787 1046488077 : FOR( i = 0; i < N; i++ )
2788 : {
2789 1040749145 : y[i] = L_add( x1[i], x2[i] );
2790 1040749145 : move32();
2791 : }
2792 :
2793 5738932 : return;
2794 : }
2795 :
2796 408560 : void v_shr_32(
2797 : Word32 x1[], /* i : Input vector 1 */
2798 : Word32 y[], /* o : Output vector that contains vector 1 + vector 2 */
2799 : const Word16 N, /* i : Vector length */
2800 : Word16 shift /*shift value*/
2801 : )
2802 : {
2803 : Word16 i;
2804 :
2805 295466498 : FOR( i = 0; i < N; i++ )
2806 : {
2807 295057938 : y[i] = L_shr( x1[i], shift );
2808 295057938 : move32();
2809 : }
2810 :
2811 408560 : return;
2812 : }
2813 :
2814 :
2815 : /*-------------------------------------------------------------------*
2816 : * v_sub_32()
2817 : *
2818 : * Subtraction of two vectors sample by sample
2819 : *-------------------------------------------------------------------*/
2820 :
2821 2511171 : void v_sub_32(
2822 : const Word32 x1[], /* i : Input vector 1 */
2823 : const Word32 x2[], /* i : Input vector 2 */
2824 : Word32 y[], /* o : Output vector that contains vector 1 - vector 2 */
2825 : const Word16 N /* i : Vector length */
2826 : )
2827 : {
2828 : Word16 i;
2829 :
2830 205304386 : FOR( i = 0; i < N; i++ )
2831 : {
2832 202793215 : y[i] = L_sub( x1[i], x2[i] );
2833 202793215 : move32();
2834 : }
2835 :
2836 2511171 : return;
2837 : }
2838 :
2839 :
2840 : /*-------------------------------------------------------------------*
2841 : * v_add_16()
2842 : *
2843 : * Addition of two vectors sample by sample
2844 : *-------------------------------------------------------------------*/
2845 :
2846 79763 : void v_add_16(
2847 : const Word16 x1[], /* i : Input vector 1 */
2848 : const Word16 x2[], /* i : Input vector 2 */
2849 : Word16 y[], /* o : Output vector that contains vector 1 + vector 2 */
2850 : const Word16 N /* i : Vector length */
2851 : )
2852 : {
2853 : Word16 i;
2854 :
2855 4988809 : FOR( i = 0; i < N; i++ )
2856 : {
2857 4909046 : y[i] = add_sat( x1[i], x2[i] );
2858 4909046 : move16();
2859 : }
2860 :
2861 79763 : return;
2862 : }
2863 :
2864 :
2865 : /*-------------------------------------------------------------------*
2866 : * v_sub_16()
2867 : *
2868 : * Subtraction of two vectors sample by sample
2869 : *-------------------------------------------------------------------*/
2870 :
2871 236921 : void v_sub_16(
2872 : const Word16 x1[], /* i : Input vector 1 */
2873 : const Word16 x2[], /* i : Input vector 2 */
2874 : Word16 y[], /* o : Output vector that contains vector 1 - vector 2 */
2875 : const Word16 N /* i : Vector length */
2876 : )
2877 : {
2878 : Word16 i;
2879 :
2880 6802047 : FOR( i = 0; i < N; i++ )
2881 : {
2882 6565126 : y[i] = sub_sat( x1[i], x2[i] );
2883 6565126 : move16();
2884 : }
2885 :
2886 236921 : return;
2887 : }
2888 :
2889 :
2890 : /*--------------------------------------------------------------------------------*/
2891 : /* squant_fx() */
2892 : /*--------------------------------------------------------------------------------*/
2893 5072060 : Word16 squant_fx( /* o: index of the winning codeword */
2894 : const Word16 x, /* i: scalar value to quantize */
2895 : Word16 *xq, /* o: quantized value */
2896 : const Word16 cb[], /* i: codebook */
2897 : const Word16 cbsize /* i: codebook size */
2898 : )
2899 : {
2900 : Word16 tmp;
2901 : Word16 c, idx;
2902 : Word32 L_mindist, L_dist;
2903 : #ifndef ISSUE_1836_replace_overflow_libcom
2904 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
2905 : Flag Overflow = 0;
2906 : #endif
2907 : #endif
2908 :
2909 5072060 : idx = 0;
2910 5072060 : move16();
2911 5072060 : L_mindist = MAX_32;
2912 5072060 : move32();
2913 :
2914 25280351 : FOR( c = 0; c < cbsize; c++ )
2915 : {
2916 20208291 : L_dist = L_deposit_l( 0 );
2917 : #ifdef ISSUE_1836_replace_overflow_libcom
2918 20208291 : tmp = sub_sat( x, cb[c] );
2919 : #else
2920 : tmp = sub_o( x, cb[c], &Overflow );
2921 : #endif
2922 :
2923 : /*dist += tmp*tmp; */
2924 : #ifdef ISSUE_1836_replace_overflow_libcom
2925 20208291 : L_dist = L_mac_sat( L_dist, tmp, tmp );
2926 : #else
2927 : L_dist = L_mac_o( L_dist, tmp, tmp, &Overflow );
2928 : #endif
2929 :
2930 20208291 : if ( LT_32( L_dist, L_mindist ) )
2931 : {
2932 11583176 : idx = c;
2933 11583176 : move16();
2934 : }
2935 20208291 : L_mindist = L_min( L_mindist, L_dist );
2936 : }
2937 :
2938 5072060 : *xq = cb[idx];
2939 5072060 : move16();
2940 :
2941 5072060 : return idx;
2942 : }
2943 :
2944 : /*! r: index of the winning codeword */
2945 401128 : Word16 squant_int_fx(
2946 : UWord8 x, /* i : scalar value to quantize */
2947 : UWord8 *xq, /* o : quantized value */
2948 : const UWord8 *cb, /* i : codebook */
2949 : const Word16 cbsize /* i : codebook size */
2950 : )
2951 : {
2952 : Word16 i, idx;
2953 : Word32 mindist, d;
2954 :
2955 401128 : idx = 0;
2956 401128 : move16();
2957 401128 : mindist = 10000000; // Q0
2958 401128 : move32();
2959 3348042 : FOR( i = 0; i < cbsize; i++ )
2960 : {
2961 2946914 : d = L_mult0( sub( x, cb[i] ), sub( x, cb[i] ) );
2962 2946914 : IF( LT_32( d, mindist ) )
2963 : {
2964 723360 : mindist = d;
2965 723360 : move32();
2966 723360 : idx = i;
2967 723360 : move16();
2968 : }
2969 : }
2970 401128 : *xq = cb[idx];
2971 401128 : move16();
2972 :
2973 401128 : return idx;
2974 : }
2975 :
2976 : /*===================================================================*/
2977 : /* FUNCTION : pz_filter_dp_fx () */
2978 : /*-------------------------------------------------------------------*/
2979 : /* PURPOSE : Generic pole-zero filter routine, with double */
2980 : /* precision memory, transposed direct form II */
2981 : /*-------------------------------------------------------------------*/
2982 : /* INPUT ARGUMENTS : */
2983 : /* */
2984 : /* _ (Word16 []) b : zero filter coefficients (Qc). */
2985 : /* _ (Word16 []) a : pole filter coefficients (Qc), a(0)=1 */
2986 : /* _ (Word16 []) x : input signal (Qx). */
2987 : /* _ (Word16) P : filter order. */
2988 : /* _ (Word16) N : number of input samples. */
2989 : /* _ (Word16) Qa : Q factor compensation (Qa=16-Qc) */
2990 : /*-------------------------------------------------------------------*/
2991 : /* OUTPUT ARGUMENTS : */
2992 : /* */
2993 : /* _ (Word16 []) y : output signal (Qx) */
2994 : /*-------------------------------------------------------------------*/
2995 : /* INPUT/OUTPUT ARGUMENTS : */
2996 : /* */
2997 : /* _ (Word32 []) buf : filter memory (Qx+Qc) */
2998 : /*-------------------------------------------------------------------*/
2999 : /* RETURN ARGUMENTS : _ None. */
3000 : /*===================================================================*/
3001 :
3002 0 : void pz_filter_dp_fx(
3003 : const Word16 b[],
3004 : const Word16 a[],
3005 : Word16 x[],
3006 : Word16 y[],
3007 : Word32 buf[],
3008 : Word16 PNR,
3009 : Word16 PDR,
3010 : Word16 N,
3011 : Word16 Qa )
3012 : {
3013 : Word16 i, j;
3014 : Word16 s;
3015 : Word32 s_mem;
3016 : Word32 Ltemp1;
3017 : Word32 Lacc;
3018 :
3019 0 : s = negate( Qa );
3020 0 : s = add( s, s ); /* s=-2Qa */
3021 0 : s = add( s, 1 );
3022 0 : FOR( i = 0; i < N; i++ )
3023 : {
3024 0 : Lacc = L_deposit_h( x[i] ); /* Lacc in Q(16+Qn)*/
3025 0 : Lacc = L_shl( Lacc, s ); /* Lacc=x[i] in Q(16+Qn-2Qa+1)*/
3026 0 : FOR( j = PDR - 1; j >= 0; j-- )
3027 0 : Lacc = Msub_32_16( Lacc, buf[j], a[j + 1] ); /*Q(16+Qn-2Qa+1)*/
3028 :
3029 0 : s_mem = L_shl_sat( Lacc, sub( Qa, 1 ) ); /*Qn-Qa+16=Qn+Qc*/
3030 0 : Lacc = L_deposit_l( 0 );
3031 0 : FOR( j = PNR - 1; j >= 0; j-- )
3032 0 : Lacc = Madd_32_16( Lacc, buf[j], b[j + 1] );
3033 0 : Lacc = Madd_32_16( Lacc, s_mem, b[0] );
3034 : /* Lacc in Q(1+Qc+Qn-Qa) */
3035 :
3036 0 : FOR( j = s_max( PDR, PNR ) - 1; j > 0; j-- )
3037 : {
3038 : /* Update filter memory */
3039 0 : buf[j] = buf[j - 1];
3040 0 : move16();
3041 : }
3042 0 : buf[0] = s_mem;
3043 0 : move16();
3044 :
3045 0 : Ltemp1 = L_shr_sat( Lacc, s ); /* Ltemp1 in Qc+Qa+Qn=Q(16+Qn) */
3046 0 : y[i] = extract_h( Ltemp1 ); /* y[i] in Qn */
3047 0 : move16();
3048 : }
3049 0 : }
3050 :
3051 : /*-------------------------------------------------------------------*
3052 : * Copy_Scale_sig
3053 : *
3054 : * Up/down scale a 16 bits vector x and move it into y
3055 : *-------------------------------------------------------------------*/
3056 8469923 : void Copy_Scale_sig32(
3057 : const Word32 x[], /* i : signal to scale input Qx */
3058 : Word32 y[], /* o : scaled signal output Qx */
3059 : const Word16 lg, /* i : size of x[] Q0 */
3060 : const Word16 exp0 /* i : exponent: x = round(x << exp) Qx ?exp */
3061 : )
3062 : {
3063 : Word16 i;
3064 : Word32 L_tmp;
3065 8469923 : Word16 tmp = exp0;
3066 : #ifndef ISSUE_1836_replace_overflow_libcom
3067 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
3068 : Flag Overflow = 0;
3069 : move32();
3070 : #endif
3071 : #endif
3072 8469923 : IF( exp0 == 0 )
3073 : {
3074 987166654 : FOR( i = 0; i < lg; i++ )
3075 : {
3076 985693757 : y[i] = x[i];
3077 985693757 : move32();
3078 : }
3079 1472897 : return;
3080 : }
3081 6997026 : IF( exp0 < 0 )
3082 : {
3083 531914343 : FOR( i = 0; i < lg; i++ )
3084 : {
3085 : #ifdef ISSUE_1836_replace_overflow_libcom
3086 527239721 : y[i] = L_shl_sat( x[i], tmp );
3087 : #else
3088 : y[i] = L_shl_o( x[i], tmp, &Overflow );
3089 : #endif
3090 527239721 : move16();
3091 : }
3092 4674622 : return;
3093 : }
3094 : #ifdef ISSUE_1836_replace_overflow_libcom
3095 2322404 : L_tmp = L_shl_sat( 1, exp0 - 1 );
3096 : #else
3097 : L_tmp = L_shl_o( 1, exp0 - 1, &Overflow );
3098 : #endif
3099 304473914 : FOR( i = 0; i < lg; i++ )
3100 : {
3101 302151510 : y[i] = W_extract_l( W_mult_32_32( L_tmp, x[i] ) );
3102 302151510 : move32(); /* saturation can occur here */
3103 : }
3104 : }
3105 :
3106 :
3107 : /*-------------------------------------------------------------------*
3108 : * Copy_Scale_sig32_16
3109 : *
3110 : * Up/down scale a 32 bits vector and round to 16 bits vector
3111 : *-------------------------------------------------------------------*/
3112 11748360 : void Copy_Scale_sig32_16(
3113 : const Word32 *src, /* i : signal to scale Qx */
3114 : Word16 *dst, /* o : scaled signal Qx */
3115 : Word16 len, /* i : size of x[] Q0 */
3116 : Word16 exp0 ) /* i : exponent: x = round(x << exp) Qx ?exp */
3117 : {
3118 : Word16 i;
3119 : Word32 L_temp;
3120 :
3121 11748360 : IF( exp0 == 0 )
3122 : {
3123 196342222 : FOR( i = 0; i < len; i++ )
3124 : {
3125 192043747 : *dst++ = round_fx_sat( *src++ );
3126 192043747 : move16();
3127 : }
3128 4298475 : return;
3129 : }
3130 :
3131 4171681508 : FOR( i = 0; i < len; i++ )
3132 : {
3133 4164231623 : L_temp = L_shl_sat( *src++, exp0 );
3134 :
3135 4164231623 : *dst++ = round_fx_sat( L_temp );
3136 4164231623 : move16();
3137 : }
3138 : }
3139 :
3140 : /*-------------------------------------------------------------------*
3141 : * v_multc_att()
3142 : *
3143 : * Attenuation of a vector,, attenuation factor in Q15
3144 : *-------------------------------------------------------------------*/
3145 :
3146 1423 : void v_multc_att(
3147 : const Word16 x[], /* i : Input vector Qx */
3148 : const Word16 att, /* i : Constant Q15, <= MAX_16 */
3149 : Word16 y[], /* o : Output vector that contains att*x */
3150 : const Word16 N /* i : Vector length */
3151 : )
3152 : {
3153 : Word16 i;
3154 1423 : IF( LT_16( att, 32767 ) )
3155 : {
3156 0 : FOR( i = 0; i < N; i++ )
3157 : {
3158 0 : y[i] = mult_r( x[i], att );
3159 0 : move16();
3160 : }
3161 : }
3162 1423 : } /*-------------------------------------------------------------------*
3163 : * v_multc_att32()
3164 : *
3165 : * Attenuation of a vector,, attenuation factor in Q15
3166 : *-------------------------------------------------------------------*/
3167 :
3168 860 : void v_multc_att32(
3169 : const Word32 x[], /* i : Input vector Qx */
3170 : const Word16 att, /* i : Constant Q15, <= MAX_16 */
3171 : Word32 y[], /* o : Output vector that contains att*x */
3172 : const Word16 N /* i : Vector length */
3173 : )
3174 : {
3175 : Word16 i;
3176 860 : IF( LT_16( att, 32767 ) )
3177 : {
3178 0 : FOR( i = 0; i < N; i++ )
3179 : {
3180 0 : y[i] = Mpy_32_16_r( x[i], att );
3181 0 : move32();
3182 : }
3183 : }
3184 860 : }
3185 :
3186 : /*-------------------------------------------------------------------*
3187 : * v_multc_att3232()
3188 : *
3189 : * Attenuation of a vector, attenuation factor in Q31
3190 : *-------------------------------------------------------------------*/
3191 :
3192 0 : void v_multc_att3232(
3193 : const Word32 x[], /* i : Input vector Qx */
3194 : const Word32 att, /* i : Constant Q32, <= MAX_32 */
3195 : Word32 y[], /* o : Output vector that contains att*x */
3196 : const Word16 N /* i : Vector length */
3197 : )
3198 : {
3199 : Word16 i;
3200 0 : IF( LE_32( att, MAX_32 ) )
3201 : {
3202 0 : FOR( i = 0; i < N; i++ )
3203 : {
3204 0 : y[i] = Mpy_32_32_r( x[i], att );
3205 0 : move32();
3206 : }
3207 : }
3208 0 : }
3209 :
3210 : /*-------------------------------------------------------------------*
3211 : * v_L_mult_1616()
3212 : *
3213 : * Multiplication of two vectors, Output in Word32
3214 : *-------------------------------------------------------------------*/
3215 :
3216 0 : void v_L_mult_1616(
3217 : const Word16 x1[], /* i : Input vector 1 */
3218 : const Word16 x2[], /* i : Input vector 2 */
3219 : Word32 y[], /* o : Output vector that contains vector 1 .* vector 2 */
3220 : const Word16 N /* i : Vector length */
3221 : )
3222 : {
3223 : Word16 i;
3224 :
3225 0 : for ( i = 0; i < N; i++ )
3226 : {
3227 0 : y[i] = L_mult( x1[i], x2[i] );
3228 0 : move32();
3229 : }
3230 :
3231 0 : return;
3232 : }
3233 :
3234 : /*-------------------------------------------------------------------*
3235 : * v_L_mult_3216()
3236 : *
3237 : * Multiplication of two vectors, Output in Word32
3238 : *-------------------------------------------------------------------*/
3239 :
3240 92161 : void v_L_mult_3216(
3241 : const Word32 x1[], /* i : Input vector 1 */
3242 : const Word16 x2[], /* i : Input vector 2 */
3243 : Word32 y[], /* o : Output vector that contains vector 1 .* vector 2 */
3244 : const Word16 N /* i : Vector length */
3245 : )
3246 : {
3247 : Word16 i;
3248 :
3249 53648257 : for ( i = 0; i < N; i++ )
3250 : {
3251 53556096 : y[i] = Mpy_32_16_1( x1[i], x2[i] );
3252 53556096 : move32();
3253 : }
3254 :
3255 92161 : return;
3256 : }
3257 :
3258 : /*-------------------------------------------------------------------*
3259 : * add_vec()
3260 : *
3261 : * Addition of two vectors sample by sample
3262 : *-------------------------------------------------------------------*/
3263 :
3264 2058 : void add_vec_fx(
3265 : const Word16 x1[], /* i : Input vector 1 */
3266 : const Word16 Qx1, /* i : SCaling of input 1 */
3267 : const Word16 x2[], /* i : Input vector 2 */
3268 : const Word16 Qx2, /* i : SCaling of input 1 */
3269 : Word16 y[], /* o : Output vector that contains vector 1 + vector 2 */
3270 : const Word16 Qy, /* i : SCaling of output 1 */
3271 : const Word16 N /* i : Vector lenght */
3272 : )
3273 : {
3274 : Word16 i, Qyx1, Qyx2;
3275 : #ifndef ISSUE_1836_replace_overflow_libcom
3276 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
3277 : Flag Overflow = 0;
3278 : move32();
3279 : #endif
3280 : #endif
3281 2058 : Qyx1 = sub( Qx1, Qy );
3282 2058 : Qyx2 = sub( Qx2, Qy );
3283 2058 : IF( Qyx1 == 0 )
3284 : {
3285 1738058 : FOR( i = 0; i < N; i++ )
3286 : {
3287 : #ifdef ISSUE_1836_replace_overflow_libcom
3288 1736000 : y[i] = add_sat( x1[i], shr_r_sat( x2[i], Qyx2 ) );
3289 : #else
3290 : y[i] = add_o( x1[i], shr_r_sat( x2[i], Qyx2 ), &Overflow );
3291 : #endif
3292 1736000 : move16();
3293 : }
3294 : }
3295 : ELSE
3296 : {
3297 0 : FOR( i = 0; i < N; i++ )
3298 : {
3299 : #ifdef ISSUE_1836_replace_overflow_libcom
3300 0 : y[i] = add_sat( shr_r_sat( x1[i], Qyx1 ), shr_r_sat( x2[i], Qyx2 ) ); //!!sat //!!sat
3301 : #else
3302 : y[i] = add_o( shr_r_sat( x1[i], Qyx1 ), shr_r_sat( x2[i], Qyx2 ), &Overflow );
3303 : #endif
3304 0 : move16();
3305 : }
3306 : }
3307 2058 : return;
3308 : }
3309 :
3310 : /*-------------------------------------------------------------------*
3311 : * Add_flt32_flt32
3312 : *
3313 : * Add two Pseudo Float Value that are 32 Bits Mantisa and 16 Bits Exp
3314 : *-------------------------------------------------------------------*/
3315 5392 : Word32 Add_flt32_flt32( /* o: Result (Normalized) */
3316 : Word32 a, /* i: 1st Value */
3317 : Word16 exp_a, /* i: Exponent of 1st Value (Q of Value) */
3318 : Word32 b, /* i: 2nd Value */
3319 : Word16 exp_b, /* i: Exponent of 2nd Value (Q of Value) */
3320 : Word16 *exp_out /* o: Exponent of Result */
3321 : )
3322 : {
3323 : Word16 temp, temp2;
3324 : Word32 L_temp;
3325 :
3326 : /* Subract 1 to further divide by 2 to avoid overflow on L_add */
3327 5392 : temp = sub( s_min( exp_a, exp_b ), 1 );
3328 :
3329 : /* Put both to same exponent */
3330 5392 : exp_a = sub( exp_a, temp );
3331 5392 : a = L_shr( a, exp_a );
3332 5392 : exp_b = sub( exp_b, temp );
3333 5392 : b = L_shr( b, exp_b );
3334 :
3335 : /* add them together */
3336 5392 : L_temp = L_add( a, b );
3337 5392 : temp2 = norm_l( L_temp );
3338 :
3339 5392 : *exp_out = add( temp, temp2 );
3340 5392 : move16();
3341 :
3342 5392 : return L_shl( L_temp, temp2 );
3343 : }
3344 :
3345 : /*-------------------------------------------------------------------*
3346 : * Mul_flt32_Q15
3347 : *
3348 : * Multiply one Pseudo Float Value (32 Bits Mantisa and 16 Bits Exp)
3349 : * with a Q15 value
3350 : *-------------------------------------------------------------------*/
3351 0 : Word32 Mul_flt32_Q15( /* o: Result (Normalized) */
3352 : Word32 value, /* i: Pseudo_float Value */
3353 : Word16 *exp_v, /*i/o: Exponent of Value (Q of Value) */
3354 : Word16 frac /* i: Q15 value */
3355 : )
3356 : {
3357 : Word16 temp;
3358 : Word32 L_temp;
3359 :
3360 0 : L_temp = Mult_32_16( value, frac );
3361 0 : temp = norm_l( L_temp );
3362 :
3363 0 : *exp_v = add( temp, *exp_v );
3364 0 : move16();
3365 :
3366 0 : return L_shl( L_temp, temp );
3367 : }
3368 :
3369 : /*-------------------------------------------------------------------*
3370 : * Div_flt32_flt32
3371 : *
3372 : * Divide one Pseudo Float Value (32 Bits Mantisa and 16 Bits Exp)
3373 : * by another one
3374 : *-------------------------------------------------------------------*/
3375 3 : Word32 Div_flt32_flt32( /* o: Result (Normalized) */
3376 : Word32 a, /* i: 1st Value */
3377 : Word16 exp_a, /* i: Exponent of 1st Value (Q of Value) */
3378 : Word32 b, /* i: 2nd Value */
3379 : Word16 exp_b, /* i: Exponent of 2nd Value (Q of Value) */
3380 : Word16 *exp_out /* o: Exponent of Result */
3381 : )
3382 : {
3383 : Word16 temp, temp2;
3384 : Word32 L_temp;
3385 :
3386 3 : temp = div_s( 16384, round_fx( b ) );
3387 3 : L_temp = Mult_32_16( a, temp );
3388 3 : temp2 = sub( 31 - 1, exp_b );
3389 3 : temp2 = add( temp2, exp_a );
3390 :
3391 3 : temp = norm_l( L_temp );
3392 :
3393 3 : *exp_out = add( temp, temp2 );
3394 3 : move16();
3395 :
3396 3 : return L_shl( L_temp, temp );
3397 : }
3398 :
3399 :
3400 : /*-------------------------------------------------------------------*
3401 : * Calc_Energy_Autoscaled
3402 : *
3403 : * Calculate Energy with overflow protection
3404 : *-------------------------------------------------------------------*/
3405 3528830 : Word32 Calc_Energy_Autoscaled( /* o: Result (Energy) */
3406 : const Word16 *signal, /* i: Signal */
3407 : Word16 signal_exp, /* i: Exponent of Signal (Q of Signal) */
3408 : Word16 len, /* i: Frame Length */
3409 : Word16 *energy_exp /* o: Exponent of Energy (Q of Energy) */
3410 : )
3411 : {
3412 : Word16 temp, temp2;
3413 : Word32 L_temp, L_Energy;
3414 : Word16 i, j;
3415 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
3416 3528830 : Flag Overflow = 0;
3417 3528830 : move32();
3418 : #endif
3419 :
3420 3528830 : Overflow = 0;
3421 3528830 : move16();
3422 :
3423 3528830 : temp2 = 0;
3424 3528830 : move16();
3425 3528830 : L_Energy = L_deposit_l( 1 );
3426 3528830 : j = s_and( 7, len );
3427 3540670 : FOR( i = 0; i < j; i++ )
3428 : {
3429 : /* divide by 2 so energy will be divided by 4 */
3430 : #ifdef ISSUE_1836_replace_overflow_libcom
3431 11840 : temp = mult_r( *signal++, 16384 );
3432 : #else
3433 : temp = mult_ro( *signal++, 16384, &Overflow );
3434 : #endif
3435 11840 : L_Energy = L_mac0_o( L_Energy, temp, temp, &Overflow );
3436 : }
3437 11676104 : FOR( i = j; i < len; i += 8 ) /* Process 8 Samples at a time */
3438 : {
3439 : /* divide by 2 so energy will be divided by 4 */
3440 8147274 : temp = mult_ro( *signal++, 16384, &Overflow );
3441 8147274 : L_temp = L_mult0( temp, temp );
3442 65178192 : FOR( j = 1; j < 8; j++ )
3443 : {
3444 : #ifdef ISSUE_1836_replace_overflow_libcom
3445 57030918 : temp = mult_r( *signal++, 16384 );
3446 : #else
3447 : temp = mult_ro( *signal++, 16384, &Overflow );
3448 : #endif
3449 57030918 : L_temp = L_mac0_o( L_temp, temp, temp, &Overflow );
3450 : }
3451 : /*Overfloe will never happen because temp2 is always positive*/
3452 8147274 : L_temp = L_shr( L_temp, temp2 );
3453 : /* Here we try the addition just to check if we can sum
3454 : the energy of the small (8 Iterations) loop with the
3455 : total energy calculated so far without an overflow.
3456 : The result is discarded. If there is an overflow both
3457 : energies are div by 2. Otherwise, nothing is done.
3458 : After the 'IF', the sum is done again and will always
3459 : be without an overflow. */
3460 8147274 : L_add_o( L_Energy, L_temp, &Overflow );
3461 8147274 : IF( Overflow != 0 )
3462 : {
3463 41 : L_Energy = L_shr( L_Energy, 1 );
3464 41 : L_temp = L_shr( L_temp, 1 );
3465 41 : temp2 = add( temp2, 1 );
3466 41 : Overflow = 0;
3467 41 : move16();
3468 : }
3469 8147274 : L_Energy = L_add_o( L_Energy, L_temp, &Overflow );
3470 : }
3471 : /* Calc Final Exponent (sub 2 because of the mult_r by 16384 that already divs the ener by 4) */
3472 3528830 : temp2 = sub( sub( shl( signal_exp, 1 ), temp2 ), 2 );
3473 :
3474 3528830 : *energy_exp = temp2;
3475 3528830 : move16();
3476 :
3477 3528830 : return L_Energy;
3478 : }
3479 :
3480 4200525 : Word16 Find_Max_Norm16( const Word16 *src, Word16 len )
3481 : {
3482 : Word16 i;
3483 : Word16 max16;
3484 :
3485 : /* it starts at '0' and not '1' like in Find_Max_Norm32() */
3486 : /* and that is necessary. */
3487 4200525 : max16 = 0;
3488 4200525 : move16();
3489 :
3490 2495825613 : FOR( i = 0; i < len; i++ )
3491 : {
3492 2491625088 : max16 = s_max( max16, abs_s( *src++ ) );
3493 : }
3494 :
3495 4200525 : return norm_s( max16 );
3496 : }
3497 :
3498 4111487 : Word16 Find_Max_Norm32( const Word32 *src, Word16 len )
3499 : {
3500 : Word16 i;
3501 : Word32 max32;
3502 :
3503 4111487 : max32 = L_deposit_l( 1 );
3504 :
3505 3173935596 : FOR( i = 0; i < len; i++ )
3506 : {
3507 3169824109 : max32 = L_max( max32, L_abs( *src++ ) );
3508 : }
3509 :
3510 4111487 : return norm_l( max32 );
3511 : }
3512 :
3513 : /*-------------------------------------------------------------------*
3514 : * Sqrt_Ratio32
3515 : *
3516 : * Calculate Sqrt of Val1/Val2
3517 : *-------------------------------------------------------------------*/
3518 5529 : Word32 Sqrt_Ratio32( /* o: Result in Q31 */
3519 : Word32 L_val1, /* i: Mantisa of Val1 */
3520 : Word16 exp1, /* i: Exp of Val1 (>0: Val was Left Shifted, <0:Right Shifted) */
3521 : Word32 L_val2, /* i: Mantisa of Val2 */
3522 : Word16 exp2, /* i: Exp of Val2 (same as exp1) */
3523 : Word16 *exp /* o: Exp of Result (# of 'L_shl' Req to get to Final Value) */
3524 : )
3525 : {
3526 : Word16 temp;
3527 :
3528 : /* Normalize Energy #1 */
3529 5529 : temp = norm_l( L_val1 );
3530 5529 : L_val1 = L_shl( L_val1, temp );
3531 : /* Adjust Exponent of Energy #1 */
3532 5529 : exp1 = add( exp1, temp );
3533 :
3534 : /* Normalize Energy #2 */
3535 5529 : temp = norm_l( L_val2 );
3536 5529 : L_val2 = L_shl( L_val2, temp );
3537 : /* Adjust Exponent of Energy #1 */
3538 5529 : exp2 = add( exp2, temp );
3539 :
3540 : /* Prepare for Inverse */
3541 5529 : temp = round_fx_sat( L_val1 );
3542 5529 : temp = div_s( 16384, temp );
3543 : /* Mult Now */
3544 5529 : L_val2 = Mult_32_16( L_val2, temp );
3545 5529 : exp1 = add( sub( exp2, exp1 ), 15 * 2 );
3546 :
3547 : /* Here Result of ('L_val2' / 2^'exp2') / ('L_val1' / 2^'exp1') is */
3548 : /* 'L_val2' / 2^'exp1' */
3549 : /* Which is val2/val1 instead of val1/val2 because we will use Inverted Square Root */
3550 : /* Normalize before Square Root */
3551 5529 : temp = norm_l( L_val2 );
3552 5529 : L_val2 = L_shl( L_val2, temp );
3553 5529 : exp1 = add( temp, exp1 );
3554 : /* Do Sqrt */
3555 5529 : temp = sub( 31, exp1 );
3556 5529 : L_val1 = Isqrt_lc( L_val2, &temp );
3557 :
3558 5529 : *exp = temp;
3559 5529 : move16();
3560 :
3561 5529 : return L_val1;
3562 : }
3563 :
3564 4430 : Word16 Invert16( /* result in Q'15 + 'exp' */
3565 : Word16 val,
3566 : Word16 *exp )
3567 : {
3568 : Word16 temp;
3569 :
3570 : /* prevent 0 input */
3571 4430 : val = s_max( val, 1 );
3572 : /* Normalize Value */
3573 4430 : temp = norm_s( val );
3574 4430 : val = shl( val, temp );
3575 :
3576 4430 : *exp = sub( sub( 15 - 1, *exp ), temp );
3577 4430 : move16(); /* -1 because of 0x4000 is 1.0 in Q14 (and not Q15) */
3578 :
3579 4430 : temp = div_s( 0x4000, val );
3580 :
3581 4430 : return temp;
3582 : }
3583 :
3584 0 : Word16 find_rem( Word16 n, Word16 m, Word16 *r )
3585 : {
3586 : Word16 i, q1, q2, qd;
3587 : Word32 Ltemp2;
3588 : Word32 Lacc;
3589 :
3590 0 : test();
3591 0 : test();
3592 0 : IF( n <= 0 || m <= 0 || n < m )
3593 : {
3594 0 : *r = n;
3595 0 : move16();
3596 0 : return ( 0 );
3597 : }
3598 :
3599 0 : q1 = norm_s( n );
3600 0 : q1 = sub( q1, 1 );
3601 0 : Lacc = L_deposit_h( shl( n, q1 ) );
3602 0 : qd = sub( q1, 1 );
3603 0 : q2 = norm_s( m );
3604 0 : q2 = sub( q2, 1 );
3605 0 : Ltemp2 = L_deposit_h( shl( m, q2 ) );
3606 0 : qd = sub( q2, qd );
3607 0 : q2 = add( q2, 1 );
3608 :
3609 0 : FOR( i = 0; i < qd; i++ )
3610 : {
3611 0 : Lacc = L_sub( Lacc, Ltemp2 );
3612 0 : IF( Lacc >= 0 )
3613 : {
3614 0 : Lacc = L_add( L_shl( Lacc, 1 ), 1 );
3615 : }
3616 : ELSE
3617 : {
3618 0 : Lacc = L_add( Lacc, Ltemp2 );
3619 0 : Lacc = L_shl( Lacc, 1 );
3620 : }
3621 : }
3622 0 : q1 = extract_l( Lacc );
3623 0 : Ltemp2 = L_shr( Lacc, q2 );
3624 0 : *r = extract_h( Ltemp2 );
3625 0 : move16();
3626 0 : return ( q1 );
3627 : }
3628 :
3629 :
3630 0 : Word32 find_remd( Word32 n, Word32 m, Word32 *r )
3631 : {
3632 : Word16 i, q1, q2, qd;
3633 : Word32 Ltemp2, qo;
3634 : Word32 Lacc;
3635 :
3636 0 : test();
3637 0 : test();
3638 0 : IF( n <= 0 || m <= 0 || n < m )
3639 : {
3640 0 : *r = n;
3641 0 : move16();
3642 0 : return ( 0 );
3643 : }
3644 :
3645 0 : q1 = norm_l( n );
3646 0 : q1 = sub( q1, 1 );
3647 0 : Lacc = L_shl( n, q1 );
3648 0 : qd = sub( q1, 1 );
3649 0 : q2 = norm_l( m );
3650 0 : q2 = sub( q2, 1 );
3651 0 : Ltemp2 = L_shl( m, q2 );
3652 0 : qd = sub( q2, qd );
3653 0 : q2 = add( q2, 1 );
3654 0 : qo = 0;
3655 0 : move16();
3656 :
3657 0 : FOR( i = 0; i < qd; i++ )
3658 : {
3659 0 : Lacc = L_sub( Lacc, Ltemp2 );
3660 0 : qo = L_shl( qo, 1 );
3661 0 : IF( Lacc >= 0 )
3662 : {
3663 0 : Lacc = L_shl( Lacc, 1 );
3664 0 : qo = L_add( qo, 1 );
3665 : }
3666 : ELSE
3667 : {
3668 0 : Lacc = L_add( Lacc, Ltemp2 );
3669 0 : Lacc = L_shl( Lacc, 1 );
3670 : }
3671 : }
3672 0 : *r = L_shr( Lacc, q2 );
3673 0 : move16();
3674 0 : return ( qo );
3675 : }
3676 :
3677 30442 : Word16 rint_new_fx(
3678 : Word32 x /*Q16 */
3679 : )
3680 : {
3681 : Word16 a;
3682 : Word32 L_tmp;
3683 : Word16 frac, tmp;
3684 :
3685 : /* middle value point test */
3686 30442 : frac = lshr( extract_l( x ), 1 ); /*Q15 */
3687 30442 : tmp = sub( frac, 0x4000 );
3688 :
3689 30442 : IF( !tmp )
3690 : {
3691 0 : a = add( extract_h( x ), 1 );
3692 :
3693 0 : IF( s_and( a, 1 ) == 0 )
3694 : {
3695 0 : return a;
3696 : }
3697 0 : IF( s_and( a, 1 ) != 0 )
3698 : {
3699 0 : return extract_h( x );
3700 : }
3701 0 : return extract_h( x );
3702 : }
3703 : ELSE
3704 : {
3705 30442 : L_tmp = L_add( x, 32768 ); /*Q16 */
3706 30442 : return extract_h( L_tmp );
3707 : }
3708 : }
3709 :
3710 :
3711 : /*===================================================================*/
3712 : /* FUNCTION : erb_diff_search_fx () */
3713 : /*-------------------------------------------------------------------*/
3714 : /* PURPOSE : erb amplitude VQ search for QPPP */
3715 : /*-------------------------------------------------------------------*/
3716 : /* INPUT ARGUMENTS : */
3717 : /* _ (Word16 []) prev_erb : Previous erb amplitude, Q13 */
3718 : /* _ (Word16 []) curr_erb : Current erb amplitude, Q13 */
3719 : /* _ (Word16 []) dif_erb: erb differential, Q13 */
3720 : /* _ (Word16 []) pow_spec : LPC power spectrum, Q7 */
3721 : /* _ (Word16 [][]) cb_fx : differential erb codebook, Q13 */
3722 : /* _ (Word16) cb_size : codebook size */
3723 : /* _ (Word16) cb_dim : codebook dimension */
3724 : /* _ (Word16) offset : index to current segment of erb array */
3725 : /* for quantization */
3726 : /*-------------------------------------------------------------------*/
3727 : /* OUTPUT ARGUMENTS : */
3728 : /* _ None */
3729 : /*-------------------------------------------------------------------*/
3730 : /* INPUT/OUTPUT ARGUMENTS : */
3731 : /* _ None */
3732 : /*-------------------------------------------------------------------*/
3733 : /* RETURN ARGUMENTS : */
3734 : /* _ (Word16) index: best codebook index */
3735 : /*-------------------------------------------------------------------*/
3736 : /* CALLED FROM : TX */
3737 : /*===================================================================*/
3738 :
3739 0 : Word16 erb_diff_search_fx( Word16 *prev_erb, const Word16 *curr_erb, Word16 *dif_erb, Word16 *pow_spec, const Word16 *cb_fx, Word16 cb_size, Word16 cb_dim, Word16 offset )
3740 : {
3741 : Word16 i, j, mmseindex;
3742 : Word16 dh, dl;
3743 : Word32 mmse;
3744 : Word32 Ltemp1;
3745 : Word32 Lacc;
3746 :
3747 0 : mmse = EVS_LW_MAX;
3748 0 : move32();
3749 0 : mmseindex = -1;
3750 0 : move16();
3751 0 : FOR( j = 0; j < cb_size; j++ )
3752 : {
3753 :
3754 0 : Lacc = L_deposit_l( 0 );
3755 0 : FOR( i = 0; i < cb_dim; i++ )
3756 : {
3757 0 : IF( add_sat( cb_fx[j * cb_dim + i], prev_erb[i + offset] ) < 0 )
3758 : {
3759 0 : Ltemp1 = L_mult( curr_erb[i + offset], curr_erb[i + offset] ); /* Q27 */
3760 0 : dh = extract_h( Ltemp1 );
3761 0 : dl = extract_l( Ltemp1 );
3762 0 : IF( dl < 0 )
3763 : {
3764 0 : Ltemp1 = L_shl( L_add( 65536, dl ), 14 ); /* */
3765 0 : Ltemp1 = Mult_32_16( Ltemp1, pow_spec[i + offset] );
3766 0 : Ltemp1 = L_shl( Ltemp1, 1 );
3767 : }
3768 : ELSE
3769 : {
3770 0 : Ltemp1 = (Word32) L_mult0( pow_spec[i + offset], dl );
3771 : }
3772 0 : Ltemp1 = L_add( L_shr( Ltemp1, 15 ), L_mult( pow_spec[i + offset], dh ) );
3773 : }
3774 : ELSE
3775 : {
3776 0 : dh = sub_sat( dif_erb[i + offset], cb_fx[j * cb_dim + i] ); /* Q13 */
3777 0 : Ltemp1 = L_mult_sat( dh, dh ); /* Q27 */
3778 0 : dh = extract_h( Ltemp1 );
3779 0 : dl = extract_l( Ltemp1 );
3780 :
3781 0 : IF( dl < 0 )
3782 : {
3783 0 : Ltemp1 = L_shl( L_add( 65536, dl ), 14 ); /* */
3784 0 : Ltemp1 = Mult_32_16( Ltemp1, pow_spec[i + offset] );
3785 0 : Ltemp1 = L_shl( Ltemp1, 1 );
3786 : }
3787 : ELSE
3788 : {
3789 0 : Ltemp1 = (Word32) L_mult0( pow_spec[i + offset], dl ); /* Q33 */
3790 : }
3791 :
3792 0 : Ltemp1 = L_add( L_shr( Ltemp1, 15 ), L_mult( pow_spec[i + offset], dh ) ); /* Q18 */
3793 : }
3794 :
3795 0 : IF( LT_16( cb_fx[j * cb_dim + i], dif_erb[i + offset] ) )
3796 : {
3797 0 : dh = extract_h( Ltemp1 );
3798 0 : dl = extract_l( Ltemp1 );
3799 0 : IF( dl < 0 )
3800 : {
3801 0 : Ltemp1 = L_shl( L_add( 65536, dl ), 14 ); /* */
3802 0 : Ltemp1 = Mult_32_16( Ltemp1, 29491 );
3803 0 : Ltemp1 = L_shl( Ltemp1, 1 );
3804 : }
3805 : ELSE
3806 : {
3807 0 : Ltemp1 = (Word32) L_mult0( 29491, dl ); /* 29491=0.9 in Q15 */
3808 : }
3809 0 : Ltemp1 = L_add( L_shr( Ltemp1, 15 ), L_mult( dh, 29491 ) );
3810 : }
3811 0 : Lacc = L_add( Lacc, Ltemp1 ); /* Q18 */
3812 : }
3813 :
3814 0 : IF( LT_32( Lacc, mmse ) )
3815 : {
3816 0 : mmse = L_add( Lacc, 0 );
3817 0 : mmseindex = j;
3818 0 : move16();
3819 : }
3820 : }
3821 :
3822 0 : return ( mmseindex );
3823 : }
3824 492617 : void Acelp_dec_total_exc(
3825 : Word16 *exc_fx, /* i/o: adapt. excitation exc */
3826 : Word16 *exc2_fx, /* i/o: adapt. excitation/total exc */
3827 : const Word16 gain_code16, /* i : Gain code Q0 */
3828 : const Word16 gain_pit_fx, /* i ; Pitch gain in Q14 */
3829 : const Word16 i_subfr, /* i ; subfr */
3830 : const Word16 *code_fx, /* i : code in Q9 */
3831 : const Word16 L_subfr /* i : Subframne lenght */
3832 : )
3833 : {
3834 : Word16 i;
3835 : Word32 L_tmp;
3836 :
3837 32020745 : FOR( i = 0; i < L_subfr; i++ )
3838 : {
3839 31528128 : L_tmp = L_shl_sat( L_mult( gain_pit_fx, exc_fx[i + i_subfr] ), 1 ); /*Q16+Q_exc*/
3840 31528128 : exc2_fx[i + i_subfr] = round_fx_sat( L_tmp ); /*Q_exc*/
3841 31528128 : L_tmp = L_add_sat( L_tmp, L_shl_sat( L_mult( gain_code16, code_fx[i] ), 6 ) ); /*Q16+Q_exc*/
3842 31528128 : exc_fx[i + i_subfr] = round_fx_sat( L_tmp ); /*Q_exc*/
3843 31528128 : move16();
3844 31528128 : move16();
3845 : }
3846 492617 : }
3847 :
3848 : /*-------------------------------------------------------------------*
3849 : * UL_inverse
3850 : *
3851 : * Calculate inverse of UL_val. Output in Q_exp.
3852 : *-------------------------------------------------------------------*/
3853 623874 : UWord32 UL_inverse( const UWord32 UL_val, Word16 *exp )
3854 : {
3855 : UWord32 UL_tmp;
3856 :
3857 623874 : *exp = norm_ul( UL_val );
3858 623874 : move16();
3859 623874 : UL_tmp = UL_lshl( UL_val, *exp ); /* Q32 */
3860 :
3861 623874 : *exp = add( 32, sub( 31, *exp ) );
3862 623874 : move16();
3863 :
3864 623874 : return UL_div( 0x80000000, UL_tmp );
3865 : }
3866 :
3867 : /*-------------------------------------------------------------------*
3868 : * UL_div
3869 : *
3870 : * Calculate UL_num/UL_den. UL_num assumed to be Q31, UL_den assumed
3871 : * to be Q32, then result is in Q32.
3872 : *-------------------------------------------------------------------*/
3873 923204 : UWord32 UL_div( const UWord32 UL_num, const UWord32 UL_den )
3874 : {
3875 : UWord32 UL_e, UL_Q;
3876 : UWord32 UL_msb, UL_lsb;
3877 : Word16 i;
3878 :
3879 923204 : UL_e = UL_subNsD( 0xffffffff, UL_den );
3880 923204 : UL_Q = UL_num;
3881 923204 : move32();
3882 :
3883 5539224 : FOR( i = 0; i < 5; i++ )
3884 : {
3885 4616020 : Mpy_32_32_uu( UL_Q, UL_e, &UL_msb, &UL_lsb ); /*31+32-32=31 */
3886 4616020 : UL_Q = UL_addNsD( UL_Q, UL_msb );
3887 4616020 : Mpy_32_32_uu( UL_e, UL_e, &UL_e, &UL_lsb ); /*32+32-32=32 */
3888 : }
3889 :
3890 923204 : return UL_Q;
3891 : }
3892 :
3893 : /*-----------------------------------------------------------------------------
3894 : * ratio()
3895 : *
3896 : * Divide the numerator by the denominator.
3897 : *----------------------------------------------------------------------------*/
3898 7184138 : Word16 ratio( const Word32 numer, const Word32 denom, Word16 *expo )
3899 : {
3900 : Word16 expNumer, expDenom;
3901 : Word16 manNumer, manDenom;
3902 : Word16 quotient;
3903 :
3904 7184138 : expDenom = norm_l( denom ); /* exponent */
3905 7184138 : manDenom = extract_h( L_shl( denom, expDenom ) ); /* mantissa */
3906 7184138 : expNumer = norm_l( numer ); /* exponent */
3907 7184138 : manNumer = extract_h( L_shl( numer, expNumer ) ); /* mantissa */
3908 7184138 : manNumer = shr( manNumer, 1 ); /* Ensure the numerator < the denominator */
3909 7184138 : quotient = div_s( manNumer, manDenom ); /* in Q14 */
3910 :
3911 7184138 : *expo = sub( expNumer, expDenom );
3912 7184138 : move16();
3913 7184138 : return quotient; /* Q14 */
3914 : }
3915 :
3916 : /*-----------------------------------------------------------------------*
3917 : * Function hp400_12k8() *
3918 : * *
3919 : * 2nd order Cheb2 high pass filter with cut off frequency at 400 Hz. *
3920 : * Optimized for fixed-point to get the following frequency response : *
3921 : * *
3922 : * frequency : 0Hz 100Hz 200Hz 300Hz 400Hz 630Hz 1.5kHz 3kHz *
3923 : * dB loss : -infdB -30dB -20dB -10dB -3dB +6dB +1dB 0dB *
3924 : * *
3925 : * Algorithm : *
3926 : * *
3927 : * y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2] *
3928 : * + a[1]*y[i-1] + a[2]*y[i-2]; *
3929 : * *
3930 : * short b[3] = {3660, -7320, 3660}; in Q12 *
3931 : * short a[3] = {4096, 7320, -3540}; in Q12 *
3932 : * *
3933 : * float --> b[3] = {0.893554687, -1.787109375, 0.893554687}; *
3934 : * a[3] = {1.000000000, 1.787109375, -0.864257812}; *
3935 : *-----------------------------------------------------------------------*/
3936 0 : void hp400_12k8_fx(
3937 : Word16 signal[], /* i/o: input signal / output is divided by 16 */
3938 : const Word16 lg, /* i : lenght of signal */
3939 : Word16 mem[] /* i/o: filter memory [6] */
3940 : )
3941 : {
3942 : Word16 i;
3943 : Word16 y1_hi, y1_lo;
3944 : Word32 L_tmp, L_tmp2, L_tmp3;
3945 :
3946 0 : y1_hi = mem[2];
3947 0 : move16();
3948 0 : y1_lo = mem[3];
3949 0 : move16();
3950 :
3951 0 : L_tmp3 = L_mac( 16384L, mem[1], a_hp400_fx[2] ); /* rounding to maximize precision */
3952 0 : L_tmp3 = L_mac( L_tmp3, y1_lo, a_hp400_fx[1] );
3953 0 : L_tmp3 = L_shr( L_tmp3, 15 );
3954 0 : L_tmp2 = L_mac( L_tmp3, mem[0], a_hp400_fx[2] );
3955 0 : L_tmp2 = L_mac( L_tmp2, mem[5], b_hp400_fx[2] );
3956 0 : L_tmp2 = L_mac( L_tmp2, mem[4], b_hp400_fx[1] );
3957 0 : L_tmp3 = L_mult( mem[4], b_hp400_fx[2] );
3958 :
3959 0 : mem[5] = signal[lg - 2];
3960 0 : move16();
3961 0 : FOR( i = 1; i < lg; i++ )
3962 : {
3963 : /* y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2] */
3964 : /* + a[1]*y[i-1] + a[2] * y[i-2] */
3965 :
3966 0 : L_tmp = L_mac( L_tmp2, y1_hi, a_hp400_fx[1] );
3967 0 : L_tmp = L_mac( L_tmp, *signal, b_hp400_fx[0] );
3968 :
3969 0 : L_tmp = L_shl( L_tmp, 1 ); /* coeff Q12 --> Q13 */
3970 :
3971 0 : L_tmp2 = L_mac( L_tmp3, y1_hi, a_hp400_fx[2] );
3972 0 : L_tmp2 = L_mac( L_tmp2, *signal, b_hp400_fx[1] );
3973 0 : L_tmp3 = L_mac( 16384L, y1_lo, a_hp400_fx[2] ); /* rounding to maximize precision */
3974 :
3975 0 : y1_lo = L_Extract_lc( L_tmp, &y1_hi );
3976 :
3977 0 : L_tmp3 = L_mac( L_tmp3, y1_lo, a_hp400_fx[1] );
3978 0 : L_tmp3 = L_shr( L_tmp3, 15 );
3979 :
3980 0 : L_tmp2 = L_add( L_tmp3, L_tmp2 );
3981 :
3982 0 : L_tmp3 = L_mult( *signal, b_hp400_fx[2] );
3983 :
3984 : /* signal is divided by 16 to avoid overflow in energy computation */
3985 0 : *signal++ = round_fx( L_tmp );
3986 0 : move16();
3987 : }
3988 :
3989 : /* y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2] */
3990 : /* + a[1]*y[i-1] + a[2] * y[i-2] */
3991 :
3992 0 : L_tmp = L_mac( L_tmp2, y1_hi, a_hp400_fx[1] );
3993 :
3994 0 : mem[4] = *signal;
3995 0 : move16();
3996 0 : L_tmp = L_mac( L_tmp, mem[4], b_hp400_fx[0] );
3997 :
3998 0 : L_tmp = L_shl( L_tmp, 1 ); /* coeff Q12 --> Q13 */
3999 :
4000 0 : mem[0] = y1_hi;
4001 0 : move16();
4002 0 : mem[1] = y1_lo;
4003 0 : move16();
4004 0 : L_Extract( L_tmp, &mem[2], &mem[3] );
4005 :
4006 : /* signal is divided by 16 to avoid overflow in energy computation */
4007 0 : *signal++ = round_fx( L_tmp );
4008 0 : move16();
4009 :
4010 0 : return;
4011 : }
4012 :
4013 59076 : void hp400_12k8_ivas_fx(
4014 : Word16 signal[], /* i/o: input signal / output is divided by 16 */
4015 : const Word16 lg, /* i : lenght of signal */
4016 : Word16 mem[] /* i/o: filter memory [6] */
4017 : )
4018 : {
4019 : Word16 i;
4020 : Word16 x0, x1, x2;
4021 : Word32 L_tmp, yy1, y2;
4022 :
4023 59076 : yy1 = L_Comp( mem[2], mem[3] ); /* Q_syn + 13 */
4024 59076 : y2 = L_Comp( mem[0], mem[1] ); /* Q_syn + 13 */
4025 59076 : x0 = mem[4]; /* Q_syn */
4026 59076 : move16();
4027 59076 : x1 = mem[5]; /* Q_syn */
4028 59076 : move16();
4029 :
4030 3839940 : FOR( i = 0; i < lg; i++ )
4031 : {
4032 3780864 : x2 = x1; /* Q_syn */
4033 3780864 : move16();
4034 3780864 : x1 = x0; /* Q_syn */
4035 3780864 : move16();
4036 3780864 : x0 = signal[i]; /* Q_syn */
4037 3780864 : move16();
4038 :
4039 3780864 : L_tmp = Mpy_32_16_1( yy1, a_hp400_ivas_fx[1] ); /*yy1 * a_hp400[1]*/ /* Qx(Q_of_yy1) + 10 ---->( (Q_syn+13) + 12 - 15)*/
4040 3780864 : L_tmp = Madd_32_16( L_tmp, y2, a_hp400_ivas_fx[2] ); /*y2 * a_hp400[2]*/ /* Qx + 10 ---->( (Q_syn+13) + 12 - 15)*/
4041 3780864 : L_tmp = L_shl( L_tmp, 3 ); /* shifting by 3 to maintain same Q (Q_syn+13) */
4042 :
4043 3780864 : L_tmp = L_mac( L_tmp, x0, b_hp400_fx[0] ); /* Q_syn + 13 */
4044 3780864 : L_tmp = L_mac( L_tmp, x1, b_hp400_fx[1] ); /* Q_syn + 13 */
4045 3780864 : L_tmp = L_mac( L_tmp, x2, b_hp400_fx[2] ); /* Q_syn + 13 */
4046 :
4047 3780864 : y2 = yy1; /* Q_syn + 13 */
4048 3780864 : move32();
4049 3780864 : yy1 = L_tmp; /* Q_syn + 13 */
4050 3780864 : move32();
4051 :
4052 3780864 : signal[i] = round_fx( L_tmp ); /* Q_syn - 3 */
4053 3780864 : move16();
4054 : }
4055 :
4056 59076 : L_Extract( yy1, &mem[2], &mem[3] );
4057 59076 : L_Extract( y2, &mem[0], &mem[1] );
4058 59076 : mem[4] = x0; /* Q_syn */
4059 59076 : mem[5] = x1; /* Q_syn */
4060 59076 : move16();
4061 59076 : move16();
4062 59076 : return;
4063 : }
4064 :
4065 0 : Word16 dot_prod_satcontr( const Word16 *x, const Word16 *y, Word16 qx, Word16 qy, Word16 *qo, Word16 len )
4066 : {
4067 : Word16 tmp_tab_x[L_FRAME16k];
4068 : Word16 tmp_tab_y[L_FRAME16k];
4069 : Word16 shift, q, ener, i;
4070 : Word32 L_tmp;
4071 : Word16 *pt1, *pt2;
4072 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
4073 0 : Flag Overflow = 0;
4074 0 : move32();
4075 : #endif
4076 :
4077 :
4078 0 : Copy( x, tmp_tab_x, len ); /* OPTIMIZE !!!!! the copy into local table is not necessary */
4079 0 : Copy( y, tmp_tab_y, len ); /* could be reworked to do a 1st iteration with the original x[] and y[] */
4080 : /* then check if there is an overflow and do a more complex 2nd, 3rd, ... processing */
4081 0 : shift = 0;
4082 0 : move16();
4083 : BASOP_SATURATE_WARNING_OFF_EVS
4084 : DO
4085 : {
4086 0 : Overflow = 0;
4087 0 : move16();
4088 0 : L_tmp = L_shl_o( 1, s_max( sub( add( add( qx, qy ), 7 ), shift ), 0 ), &Overflow );
4089 0 : pt1 = tmp_tab_x;
4090 0 : pt2 = tmp_tab_y;
4091 0 : FOR( i = 0; i < len; i++ )
4092 : {
4093 0 : L_tmp = L_mac0_o( L_tmp, *pt1++, *pt2++, &Overflow ); /*Q(qx+qy-shift) */
4094 : }
4095 :
4096 0 : IF( Overflow != 0 )
4097 : {
4098 0 : Scale_sig( tmp_tab_x, len, -2 );
4099 0 : Scale_sig( tmp_tab_y, len, -2 );
4100 0 : shift = add( shift, 4 );
4101 : }
4102 : }
4103 0 : WHILE( Overflow != 0 );
4104 : BASOP_SATURATE_WARNING_ON_EVS
4105 :
4106 0 : q = norm_l( L_tmp );
4107 0 : L_tmp = L_shl( L_tmp, q ); /*Q(qx+qy-shift+q) */
4108 0 : ener = extract_h( L_tmp ); /*Q(qx+qy-shift+q-16) */
4109 0 : q = add( q, add( qx, qy ) );
4110 0 : *qo = sub( q, add( shift, 16 ) );
4111 0 : move16();
4112 0 : return ener;
4113 : }
4114 :
4115 :
4116 : /*
4117 : * E_UTIL_f_convolve
4118 : *
4119 : * Parameters:
4120 : * x I: input vector <14bits
4121 : * h I: impulse response (or second input vector) (1Q14)
4122 : * y O: output vetor (result of convolution)
4123 : *
4124 : * Function:
4125 : * Perform the convolution between two vectors x[] and h[] and
4126 : * write the result in the vector y[]. All vectors are of length L.
4127 : * Only the first L samples of the convolution are considered.
4128 : * Vector size = L_SUBFR
4129 : *
4130 : * Returns:
4131 : * void
4132 : */
4133 15530 : void E_UTIL_f_convolve( const Word16 x[], const Word16 h[], Word16 y[], const Word16 size )
4134 : {
4135 : Word16 i, n;
4136 : Word32 L_sum;
4137 : Word64 L64_sum;
4138 :
4139 1009450 : FOR( n = 0; n < size; n++ )
4140 : {
4141 993920 : L64_sum = 0;
4142 993920 : move64();
4143 32302400 : FOR( i = 0; i < n; i++ )
4144 : {
4145 31308480 : L64_sum = W_mac_16_16( L64_sum, x[i], h[n - i] );
4146 : }
4147 993920 : L_sum = W_sat_l( L64_sum );
4148 993920 : y[n] = mac_r( L_sum, x[i], h[0] );
4149 993920 : move16();
4150 : }
4151 15530 : return;
4152 : }
4153 :
4154 : /*-----------------------------------------------------------------------------
4155 : * floating_point_add:
4156 : *
4157 : * Add two floating point numbers: x <- x + y.
4158 : *----------------------------------------------------------------------------*/
4159 23313244 : void floating_point_add(
4160 : Word32 *mx, /* io: mantissa of the addend Q31 */
4161 : Word16 *ex, /* io: exponent of the addend Q0 */
4162 : const Word32 my, /* i: mantissa of the adder Q31 */
4163 : const Word16 ey /* i: exponent of the adder Q0 */
4164 : )
4165 : {
4166 : Word32 accX, accY;
4167 : Word16 align, expo;
4168 : /* NB: This function will not work properly if the mantissa is zero and the exponent is not 32.
4169 : It is up to the caller function to avoid this condition. */
4170 : /* Ensure 1 bit headroom before addition. */
4171 23313244 : accX = L_shr( *mx, 1 );
4172 23313244 : accY = L_shr( my, 1 );
4173 : /* First, align the Q-points of the two operands. Then, add. */
4174 23313244 : align = sub( *ex, ey );
4175 :
4176 23313244 : IF( align < 0 )
4177 : {
4178 22396531 : accX = L_add( accX, L_shl( accY, align ) );
4179 : }
4180 : ELSE
4181 : {
4182 916713 : accX = L_add( accY, L_shr( accX, align ) );
4183 916713 : *ex = ey;
4184 916713 : move16();
4185 : }
4186 : /* Normalize the result and update the mantissa and exponent. */
4187 23313244 : expo = norm_l( accX );
4188 23313244 : *mx = L_shl( accX, expo );
4189 23313244 : *ex = sub( add( *ex, expo ), 1 ); /* Subtract 1 due to 1-bit down-shift above ensuring 1 bit headroom before addition. */
4190 23313244 : move32();
4191 23313244 : move16();
4192 23313244 : return;
4193 : }
4194 :
4195 : /*-------------------------------------------------------------------*
4196 : * delay_signal_fx()
4197 : *
4198 : * Delay buffer by defined number of samples
4199 : *-------------------------------------------------------------------*/
4200 :
4201 960120 : void delay_signal_fx(
4202 : Word16 x[], /* i/o: signal to be delayed */
4203 : const Word16 len, /* i : length of the input signal */
4204 : Word16 mem[], /* i/o: synchronization memory */
4205 : const Word16 delay /* i : delay in samples */
4206 : )
4207 : {
4208 : Word16 tmp_buffer[L_FRAME48k];
4209 :
4210 960120 : Copy( mem, tmp_buffer, delay );
4211 960120 : Copy( x + sub( len, delay ), mem, delay );
4212 960120 : Copy( x, x + delay, sub( len, delay ) );
4213 960120 : Copy( tmp_buffer, x, delay );
4214 :
4215 960120 : return;
4216 : }
4217 :
4218 2522209 : void delay_signal32_fx(
4219 : Word32 x[], /* i/o: signal to be delayed */
4220 : const Word16 len, /* i : length of the input signal */
4221 : Word32 mem[], /* i/o: synchronization memory */
4222 : const Word16 delay /* i : delay in samples */
4223 : )
4224 : {
4225 : Word32 tmp_buffer[L_FRAME48k];
4226 :
4227 2522209 : Copy32( mem, tmp_buffer, delay );
4228 2522209 : Copy32( x + sub( len, delay ), mem, delay );
4229 2522209 : Copy32( x, x + delay, sub( len, delay ) );
4230 2522209 : Copy32( tmp_buffer, x, delay );
4231 :
4232 2522209 : return;
4233 : }
4234 :
4235 54098 : void delay_signal_q_adj_fx(
4236 : Word32 x[], /* i/o: signal to be delayed */
4237 : const Word16 len, /* i : length of the input signal */
4238 : Word32 mem[], /* i/o: synchronization memory */
4239 : const Word16 delay, /* i : delay in samples */
4240 : const Word16 q_x,
4241 : const Word16 q_mem )
4242 : {
4243 :
4244 : Word32 tmp_buffer[L_FRAME48k];
4245 :
4246 54098 : Copy32( mem, tmp_buffer, delay );
4247 54098 : Copy32( x + sub( len, delay ), mem, delay );
4248 54098 : Copy32( x, x + delay, sub( len, delay ) );
4249 :
4250 :
4251 54098 : IF( EQ_16( q_x, q_mem ) )
4252 : {
4253 46120 : Copy32( tmp_buffer, x, delay );
4254 : }
4255 : ELSE
4256 : {
4257 7978 : v_shr( tmp_buffer, sub( q_mem, q_x ), x, delay );
4258 : }
4259 :
4260 54098 : return;
4261 : }
4262 :
4263 24671177 : void v_add_fx(
4264 : const Word32 x1[], /* i : Input vector 1 */
4265 : const Word32 x2[], /* i : Input vector 2 */
4266 : Word32 y[], /* o : Output vector that contains vector 1 + vector 2 */
4267 : const Word16 N /* i : Vector length */
4268 : )
4269 : {
4270 : Word16 i;
4271 :
4272 2999102455 : FOR( i = 0; i < N; i++ )
4273 : {
4274 2974431278 : y[i] = L_add_sat( x1[i], x2[i] );
4275 2974431278 : move32();
4276 : }
4277 :
4278 24671177 : return;
4279 : }
4280 3779 : Word16 floor_log_2( Word32 num )
4281 : {
4282 :
4283 3779 : IF( num == 0 )
4284 : {
4285 0 : return 0;
4286 : }
4287 :
4288 3779 : return ( sub( 30, norm_l( num ) ) );
4289 : }
4290 :
4291 3577012 : void v_shr(
4292 : const Word32 x[], /* i : Input vector */
4293 : const Word16 shift, /* i : Constant */
4294 : Word32 y[], /* o : Output vector that contains x >> shift */
4295 : const Word16 N /* i : Vector length */
4296 : )
4297 : {
4298 : Word16 i;
4299 :
4300 635659260 : FOR( i = 0; i < N; i++ )
4301 : {
4302 632082248 : y[i] = L_shr( x[i], shift );
4303 632082248 : move32();
4304 : }
4305 :
4306 3577012 : return;
4307 : }
4308 :
4309 0 : void v_shr_16(
4310 : const Word16 x[], /* i : Input vector */
4311 : const Word16 shift, /* i : Constant */
4312 : Word16 y[], /* o : Output vector that contains x >> shift */
4313 : const Word16 N /* i : Vector length */
4314 : )
4315 : {
4316 : Word16 i;
4317 :
4318 0 : FOR( i = 0; i < N; i++ )
4319 : {
4320 0 : y[i] = shr( x[i], shift );
4321 0 : move16();
4322 : }
4323 :
4324 0 : return;
4325 : }
4326 :
4327 : /*---------------------------------------------------------------------*
4328 : * lin_interp_fx()
4329 : *
4330 : * Linearly maps x from source range <x1, x2> to the target range <y1, y2>
4331 : *---------------------------------------------------------------------*/
4332 :
4333 : /*! r: mapped output value */
4334 705 : Word16 lin_interp_fx(
4335 : const Word16 x, /* i : Q15 the value to be mapped */
4336 : const Word16 x1, /* i : Q15 source range interval: low end */
4337 : const Word16 y1, /* i : Q15 source range interval: high end */
4338 : const Word16 x2, /* i : Q15 target range interval: low */
4339 : const Word16 y2, /* i : Q15 target range interval: high */
4340 : const Word16 flag_sat /* i : flag to indicate whether to apply saturation */
4341 : )
4342 : {
4343 705 : IF( sub( x2, x1 ) == 0 )
4344 : {
4345 0 : return y1;
4346 : }
4347 705 : ELSE IF( flag_sat )
4348 : {
4349 705 : IF( GE_16( x, s_max( x1, x2 ) ) )
4350 : {
4351 0 : IF( GT_16( x1, x2 ) )
4352 : {
4353 0 : return y1;
4354 : }
4355 : ELSE
4356 : {
4357 0 : return y2;
4358 : }
4359 : }
4360 705 : ELSE IF( LE_16( x, s_min( x1, x2 ) ) )
4361 : {
4362 8 : IF( LT_16( x1, x2 ) )
4363 : {
4364 8 : return y1;
4365 : }
4366 : ELSE
4367 : {
4368 0 : return y2;
4369 : }
4370 : }
4371 : }
4372 :
4373 697 : return add_sat( y1, mult( sub( x, x1 ), div_s( sub( y2, y1 ), sub( x2, x1 ) ) ) );
4374 : }
4375 :
4376 :
4377 164897 : Word16 lin_interp_ivas_fx(
4378 : const Word16 x, /* i : Q15 the value to be mapped */
4379 : const Word16 x1, /* i : Q15 source range interval: low end */
4380 : const Word16 y1, /* i : Q15 source range interval: high end */
4381 : const Word16 x2, /* i : Q15 target range interval: low */
4382 : const Word16 y2, /* i : Q15 target range interval: high */
4383 : const Word16 flag_sat /* i : flag to indicate whether to apply saturation */
4384 : )
4385 : {
4386 164897 : IF( EQ_16( sub( x2, x1 ), 0 ) )
4387 : {
4388 0 : return y1;
4389 : }
4390 164897 : ELSE IF( flag_sat )
4391 : {
4392 162102 : IF( GE_16( x, s_max( x1, x2 ) ) )
4393 : {
4394 776 : return GT_16( x1, x2 ) ? y1 : y2;
4395 : }
4396 161326 : ELSE IF( LE_16( x, s_min( x1, x2 ) ) )
4397 : {
4398 124430 : return LT_16( x1, x2 ) ? y1 : y2;
4399 : }
4400 : }
4401 : Word16 div_res_e;
4402 39691 : Word16 div_res = BASOP_Util_Divide1616_Scale( sub( y2, y1 ), sub( x2, x1 ), &div_res_e );
4403 : // div_res = shl( div_res, div_res_e );
4404 39691 : return add_sat( y1, round_fx( L_shl( L_mult( sub( x, x1 ), div_res ), div_res_e ) ) );
4405 : }
4406 :
4407 : /*---------------------------------------------------------------------
4408 : * sign_l()
4409 : *
4410 : *---------------------------------------------------------------------*/
4411 :
4412 : /*! r: sign of x (+1/-1) */
4413 56280 : Word32 sign_l(
4414 : const Word32 x /* i : input value of x */
4415 : )
4416 : {
4417 56280 : IF( x < 0 )
4418 : {
4419 25127 : return MIN_32;
4420 : }
4421 : ELSE
4422 : {
4423 31153 : return MAX_32;
4424 : }
4425 : }
4426 :
4427 132 : void v_mult16_fixed(
4428 : const Word16 x1[], /* i : Input vector 1 */
4429 : const Word16 x2[], /* i : Input vector 2 */
4430 : Word16 y[], /* o : Output vector that contains vector 1 .* vector 2 */
4431 : const Word16 N /* i : Vector length */
4432 : )
4433 : {
4434 : Word16 i;
4435 :
4436 9674 : FOR( i = 0; i < N; i++ )
4437 : {
4438 9542 : y[i] = mult_r( x1[i], x2[i] );
4439 9542 : move16();
4440 : }
4441 :
4442 132 : return;
4443 : }
4444 :
4445 : /*---------------------------------------------------------------------*
4446 : * set_zero_fx()
4447 : *
4448 : * Set a vector vec[] of dimension lvec to zero
4449 : *---------------------------------------------------------------------*/
4450 :
4451 227593674 : void set_zero_fx(
4452 : Word32 *vec, /* o : input vector */
4453 : const Word16 lvec /* i : length of the vector */
4454 : )
4455 : {
4456 : Word16 i;
4457 :
4458 20422129366 : FOR( i = 0; i < lvec; i++ )
4459 : {
4460 20194535692 : *vec++ = 0;
4461 20194535692 : move32();
4462 : }
4463 :
4464 227593674 : return;
4465 : }
4466 9059 : void set_zero2_fx(
4467 : Word32 *vec, /* o : input vector */
4468 : const Word32 lvec /* i : length of the vector */
4469 : )
4470 : {
4471 : Word32 i;
4472 :
4473 34153899 : FOR( i = 0; i < lvec; i++ )
4474 : {
4475 34144840 : *vec++ = 0;
4476 34144840 : move32();
4477 : }
4478 :
4479 9059 : return;
4480 : }
4481 :
4482 6560552 : void set16_zero_fx(
4483 : Word16 *vec, /* o : input vector */
4484 : const Word16 lvec /* i : length of the vector */
4485 : )
4486 : {
4487 : Word16 i;
4488 :
4489 2749717075 : FOR( i = 0; i < lvec; i++ )
4490 : {
4491 2743156523 : *vec++ = 0;
4492 2743156523 : move16();
4493 : }
4494 :
4495 6560552 : return;
4496 : }
4497 :
4498 1533492 : UWord32 mvl2s_r(
4499 : const Word32 x[], /* i : input vector */
4500 : const Word16 q_x,
4501 : Word16 y[], /* o : output vector */
4502 : const Word16 n /* i : vector size */
4503 : )
4504 : {
4505 : Word16 i;
4506 : Word32 temp;
4507 1533492 : UWord32 noClipping = 0;
4508 1533492 : move32();
4509 :
4510 1533492 : IF( n <= 0 )
4511 : {
4512 : /* cannot transfer vectors with size 0 */
4513 46 : return 0;
4514 : }
4515 :
4516 1533446 : IF( (void *) y <= (const void *) x )
4517 : {
4518 0 : Word32 tempd = L_shl( 1, sub( q_x, 1 ) );
4519 0 : FOR( i = 0; i < n; i++ )
4520 : {
4521 0 : temp = L_add( x[i], tempd );
4522 0 : temp = L_shr( temp, q_x );
4523 :
4524 0 : IF( GT_32( temp, MAX16B ) )
4525 : {
4526 0 : temp = MAX16B;
4527 0 : move32();
4528 0 : noClipping = L_add( (Word32) noClipping, 1 );
4529 : }
4530 0 : ELSE IF( LT_32( temp, MIN16B ) )
4531 : {
4532 0 : temp = MIN16B;
4533 0 : move32();
4534 0 : noClipping = L_add( (Word32) noClipping, 1 );
4535 : }
4536 :
4537 0 : y[i] = extract_l( temp );
4538 0 : move16();
4539 : }
4540 : }
4541 : ELSE
4542 : {
4543 1533446 : Word32 tempd = L_shl( 1, sub( q_x, 1 ) );
4544 1227495306 : FOR( i = n - 1; i >= 0; i-- )
4545 : {
4546 1225961860 : temp = L_add( x[i], tempd );
4547 1225961860 : temp = L_shr( temp, q_x );
4548 :
4549 1225961860 : IF( GT_32( temp, MAX16B ) )
4550 : {
4551 325 : temp = MAX16B;
4552 325 : move32();
4553 325 : noClipping = L_add( (Word32) noClipping, 1 );
4554 : }
4555 1225961535 : ELSE IF( LT_32( temp, MIN16B ) )
4556 : {
4557 414 : temp = MIN16B;
4558 414 : move32();
4559 414 : noClipping = L_add( (Word32) noClipping, 1 );
4560 : }
4561 :
4562 1225961860 : y[i] = extract_l( temp );
4563 1225961860 : move16();
4564 : }
4565 : }
4566 :
4567 1533446 : return noClipping;
4568 : }
4569 :
4570 46030160 : Word32 dotp_me_fx(
4571 : const Word32 x[], /* i : vector x[] */
4572 : const Word32 y[], /* i : vector y[] */
4573 : const Word16 n, /* i : vector length */
4574 : Word16 exp_x,
4575 : Word16 exp_y,
4576 : Word16 *exp_suma )
4577 : {
4578 : Word16 i;
4579 : Word32 suma;
4580 : Word32 mul;
4581 46030160 : Word16 mul_exp = add( exp_x, exp_y );
4582 46030160 : suma = Mpy_32_32( x[0], y[0] );
4583 46030160 : *exp_suma = mul_exp;
4584 283085484 : FOR( i = 1; i < n; i++ )
4585 : {
4586 237055324 : mul = Mpy_32_32( x[i], y[i] );
4587 237055324 : suma = BASOP_Util_Add_Mant32Exp( suma, *exp_suma, mul, mul_exp, exp_suma ); // exp_x+exp_A
4588 : }
4589 :
4590 46030160 : return suma;
4591 : }
4592 :
4593 17500 : Word32 dotp_fixed_guarded(
4594 : const Word32 x[], /* i : vector x[] */
4595 : const Word32 y[], /* i : vector y[] */
4596 : const Word16 n /* i : vector length */
4597 : )
4598 : {
4599 : Word16 i;
4600 : Word32 suma;
4601 17500 : Word16 guarded_bits = find_guarded_bits_fx( n );
4602 17500 : suma = L_shr( Mpy_32_32( x[0], y[0] ), guarded_bits );
4603 :
4604 280000 : FOR( i = 1; i < n; i++ )
4605 : {
4606 262500 : suma = L_add( suma, L_shr( Mpy_32_32( x[i], y[i] ), guarded_bits ) );
4607 : }
4608 :
4609 17500 : return suma;
4610 : }
4611 :
4612 :
4613 372 : Word32 dotp_fixed_ivas_fx(
4614 : const Word32 x[], /* i : vector x[] */
4615 : Word16 x_e,
4616 : const Word32 y[], /* i : vector y[] */
4617 : Word16 y_e,
4618 : const Word16 n, /* i : vector length */
4619 : Word16 *out_e )
4620 : {
4621 : Word16 i, exp;
4622 372 : Word32 suma = 0;
4623 :
4624 372 : exp = 31;
4625 372 : move16();
4626 :
4627 118544 : FOR( i = 0; i < n; i++ )
4628 : {
4629 118172 : suma = BASOP_Util_Add_Mant32Exp( suma, exp, Mpy_32_32( x[i], y[i] ), x_e + y_e, &exp );
4630 : }
4631 :
4632 372 : *out_e = exp;
4633 372 : move16();
4634 372 : return suma;
4635 : }
4636 :
4637 : /*-------------------------------------------------------------------*
4638 : * v_mult()
4639 : *
4640 : * Multiplication of two vectors
4641 : *-------------------------------------------------------------------*/
4642 :
4643 :
4644 14169980 : void v_mult_fixed(
4645 : const Word32 x1[], /* i : Input vector 1 */
4646 : const Word32 x2[], /* i : Input vector 2 */
4647 : Word32 y[], /* o : Output vector that contains vector 1 .* vector 2 */
4648 : const Word16 N /* i : Vector length */
4649 : )
4650 : {
4651 : Word16 i;
4652 :
4653 555201563 : FOR( i = 0; i < N; i++ )
4654 : {
4655 541031583 : y[i] = Mpy_32_32( x1[i], x2[i] );
4656 541031583 : move32();
4657 : }
4658 :
4659 14169980 : return;
4660 : }
4661 :
4662 : /*-------------------------------------------------------------------*
4663 : * anint_fixed()
4664 : *
4665 : * Round to the nearest integer.
4666 : *-------------------------------------------------------------------*/
4667 9400 : Word32 anint_fixed( Word32 x, Word16 exp )
4668 : {
4669 9400 : IF( x == 0 )
4670 : {
4671 856 : return 0;
4672 : }
4673 8544 : IF( x >= 0 )
4674 : {
4675 8544 : return L_add( x, L_shl( 1, sub( exp, 1 ) ) );
4676 : }
4677 : ELSE
4678 : {
4679 0 : return L_sub( x, L_shl( 1, sub( exp, 1 ) ) );
4680 : }
4681 : }
4682 :
4683 : /*-------------------------------------------------------------------*
4684 : * ceil_fixed()
4685 : *
4686 : * Ceil to the next multiple of (1 << exp).
4687 : *-------------------------------------------------------------------*/
4688 25515 : Word32 ceil_fixed( Word32 x, Word16 exp )
4689 : {
4690 : Word32 step;
4691 : // step = x / L_shl( 1, exp );
4692 25515 : step = L_shr( x, exp );
4693 25515 : IF( ( x % L_shl( 1, exp ) ) > 0 )
4694 : {
4695 15269 : step = L_add( step, 1 );
4696 : }
4697 25515 : return L_shl( step, exp );
4698 : }
4699 :
4700 783 : void sort_l(
4701 : Word32 *x, /* i/o: Vector to be sorted */
4702 : Word16 len /* i/o: vector length */
4703 : )
4704 : {
4705 : Word16 i, j;
4706 : Word32 tempr;
4707 :
4708 7133 : FOR( i = len - 2; i >= 0; i-- )
4709 : {
4710 6350 : tempr = x[i];
4711 6350 : move32();
4712 23195 : FOR( j = i + 1; ( j < len ) && ( tempr > x[j] ); j++ )
4713 : {
4714 16845 : x[j - 1] = x[j];
4715 16845 : move32();
4716 : }
4717 6350 : x[j - 1] = tempr;
4718 6350 : move32();
4719 : }
4720 :
4721 783 : return;
4722 : }
4723 :
4724 : /*-------------------------------------------------------------------*
4725 : * v_add_fixed()
4726 : *
4727 : * Subtraction of two vectors sample by sample
4728 : *-------------------------------------------------------------------*/
4729 :
4730 4623210 : void v_add_fixed(
4731 : const Word32 x1[], /* i : Input vector 1 */
4732 : const Word32 x2[], /* i : Input vector 2 */
4733 : Word32 y[], /* o : Output vector that contains vector 1 - vector 2 */
4734 : const Word16 N, /* i : Vector length */
4735 : const Word16 hdrm /* i : headroom for when subtraction result > 1 or < -1 */
4736 : )
4737 : {
4738 : Word16 i;
4739 :
4740 146553112 : FOR( i = 0; i < N; i++ )
4741 : {
4742 141929902 : y[i] = L_add( L_shr( x1[i], hdrm ), L_shr( x2[i], hdrm ) );
4743 141929902 : move32();
4744 : }
4745 :
4746 4623210 : return;
4747 : }
4748 :
4749 475646925 : void v_add_fixed_no_hdrm(
4750 : const Word32 x1[], /* i : Input vector 1 */
4751 : const Word32 x2[], /* i : Input vector 2 */
4752 : Word32 y[], /* o : Output vector that contains vector 1 + vector 2 */
4753 : const Word16 N /* i : Vector length */
4754 : )
4755 : {
4756 : Word16 i;
4757 :
4758 2600924948 : FOR( i = 0; i < N; i++ )
4759 : {
4760 2125278023 : y[i] = L_add( x1[i], x2[i] );
4761 2125278023 : move32();
4762 : }
4763 :
4764 475646925 : return;
4765 : }
4766 :
4767 8866906 : void v_add_fixed_me(
4768 : const Word32 x1[], /* i : Input vector 1 */
4769 : const Word16 x1_e, /* i : Exponent for input vector 1 */
4770 : const Word32 x2[], /* i : Input vector 2 */
4771 : const Word16 x2_e, /* i : Exponent for input vector 2 */
4772 : Word32 y[], /* o : Output vector that contains vector 1 - vector 2 */
4773 : Word16 *y_e, /* i : Exponent for output vector */
4774 : const Word16 N, /* i : Vector length */
4775 : const Word16 hdrm /* i : headroom for when subtraction result > 1 or < -1 */
4776 : )
4777 : {
4778 : Word16 i;
4779 8866906 : Word16 x1_shift = sub( s_max( x1_e, x2_e ), x1_e );
4780 8866906 : Word16 x2_shift = sub( s_max( x1_e, x2_e ), x2_e );
4781 :
4782 139144085 : FOR( i = 0; i < N; i++ )
4783 : {
4784 130277179 : y[i] = L_add( L_shr( x1[i], hdrm + x1_shift ), L_shr( x2[i], hdrm + x2_shift ) );
4785 130277179 : move32();
4786 : }
4787 :
4788 8866906 : *y_e = add( s_max( x1_e, x2_e ), hdrm );
4789 8866906 : move16();
4790 :
4791 8866906 : return;
4792 : }
4793 :
4794 73774555 : Word16 find_guarded_bits_fx( Word32 n )
4795 : {
4796 : // return n <= 1 ? 0 : n <= 2 ? 1
4797 : // : n <= 4 ? 2
4798 : // : n <= 8 ? 3
4799 : // : n <= 16 ? 4
4800 : // : n <= 32 ? 5
4801 : // : n <= 64 ? 6
4802 : // : n <= 128 ? 7
4803 : // : n <= 256 ? 8
4804 : // : n <= 512 ? 9
4805 : // : n <= 1024 ? 10
4806 : // : n <= 2048 ? 11
4807 : // : n <= 4096 ? 12
4808 : // : n <= 8192 ? 13
4809 : // : n <= 16384 ? 14
4810 : // : 15;
4811 : /*Word16 val = 0;
4812 : move32();
4813 : test();
4814 : WHILE( GT_32( n, L_shl( 1, val ) ) && LT_32( val, 16 ) )
4815 : {
4816 : val = add( val, 1 );
4817 : }*/
4818 73774555 : IF( LE_32( n, 1 ) )
4819 : {
4820 5457684 : return 0;
4821 : }
4822 : ELSE
4823 : {
4824 :
4825 68316871 : return sub( 31, norm_l( L_sub( n, 1 ) ) );
4826 : }
4827 : }
4828 :
4829 644880838 : Word16 L_norm_arr( const Word32 *arr, Word16 size )
4830 : {
4831 644880838 : Word16 q = 31;
4832 644880838 : move16();
4833 33420970820 : FOR( Word16 i = 0; i < size; i++ )
4834 : {
4835 : Word16 q_tst;
4836 :
4837 32776089982 : q_tst = norm_l( arr[i] );
4838 32776089982 : if ( arr[i] != 0 )
4839 : {
4840 26727089763 : q = s_min( q, q_tst );
4841 : }
4842 : }
4843 :
4844 644880838 : return q;
4845 : }
4846 :
4847 20375057 : Word16 norm_arr( Word16 *arr, Word16 size )
4848 : {
4849 20375057 : Word16 q = 15;
4850 20375057 : Word16 exp = 0;
4851 20375057 : move16();
4852 20375057 : move16();
4853 8060982785 : FOR( Word16 i = 0; i < size; i++ )
4854 : {
4855 8040607728 : if ( arr[i] != 0 )
4856 : {
4857 6726000404 : exp = norm_s( arr[i] );
4858 : }
4859 8040607728 : if ( arr[i] != 0 )
4860 : {
4861 6726000404 : q = s_min( q, exp );
4862 : }
4863 : }
4864 20375057 : return q;
4865 : }
4866 :
4867 3317060 : Word16 W_norm_arr( Word64 *arr, Word16 size )
4868 : {
4869 3317060 : Word16 q = 63;
4870 3317060 : Word16 exp = 0;
4871 3317060 : move16();
4872 3317060 : move16();
4873 1573168004 : FOR( Word16 i = 0; i < size; i++ )
4874 : {
4875 1569850944 : if ( arr[i] != 0 )
4876 : {
4877 1536395516 : exp = W_norm( arr[i] );
4878 : }
4879 1569850944 : if ( arr[i] != 0 )
4880 : {
4881 1536395516 : q = s_min( q, exp );
4882 : }
4883 : }
4884 3317060 : return q;
4885 : }
4886 :
4887 273754020 : Word16 get_min_scalefactor( Word32 x, Word32 y )
4888 : {
4889 : Word16 scf_y;
4890 273754020 : Word16 scf = Q31;
4891 273754020 : move16();
4892 :
4893 273754020 : test();
4894 273754020 : if ( x == 0 && y == 0 )
4895 : {
4896 20282128 : scf = 0;
4897 20282128 : move16();
4898 : }
4899 :
4900 273754020 : if ( x != 0 )
4901 : {
4902 253415908 : scf = norm_l( x );
4903 : }
4904 :
4905 273754020 : scf_y = norm_l( y );
4906 273754020 : if ( y != 0 )
4907 : {
4908 195216482 : scf = s_min( scf_y, scf );
4909 : }
4910 :
4911 273754020 : return scf;
4912 : }
4913 :
4914 :
4915 361055240 : Flag is_zero_arr( Word32 *arr, Word16 size )
4916 : {
4917 655666676 : FOR( Word16 i = 0; i < size; i++ )
4918 591756789 : IF( arr[i] != 0 )
4919 : {
4920 297145353 : return 0;
4921 : }
4922 :
4923 63909887 : return 1;
4924 : }
4925 :
4926 1924024 : Flag is_zero_arr16( Word16 *arr, Word16 size )
4927 : {
4928 251817508 : FOR( Word16 i = 0; i < size; i++ )
4929 251595179 : IF( arr[i] != 0 )
4930 : {
4931 1701695 : return 0;
4932 : }
4933 :
4934 222329 : return 1;
4935 : }
4936 :
4937 0 : Flag is_zero_arr64( Word64 *arr, Word16 size )
4938 : {
4939 0 : FOR( Word16 i = 0; i < size; i++ )
4940 : {
4941 0 : IF( arr[i] != 0 )
4942 : {
4943 0 : return 0;
4944 : }
4945 : }
4946 0 : return 1;
4947 : }
4948 :
4949 0 : void Scale_sig64(
4950 : Word64 x[], /* i/o: signal to scale Qx */
4951 : Word16 len, /* i : size of x[] Q0 */
4952 : Word16 exp /* i : exponent: x = round(x << exp) Qx exp */
4953 : )
4954 : {
4955 : Word16 i;
4956 0 : assert( exp <= 63 && exp >= -63 );
4957 0 : IF( exp == 0 )
4958 : {
4959 0 : return;
4960 : }
4961 :
4962 0 : FOR( i = 0; i < len; i++ )
4963 : {
4964 : /* saturation can occur here */
4965 0 : x[i] = W_shl( x[i], exp );
4966 0 : move64();
4967 : }
4968 : }
|