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 <stdint.h>
38 : #include <assert.h>
39 : #include "options.h" /* Compilation switches */
40 : #include "ivas_cnst.h" /* Common constants */
41 : #include "prot_fx.h" /* Function prototypes */
42 : #include "rom_com.h"
43 : #include "basop_util.h"
44 :
45 :
46 : /*-----------------------------------------------------------------*
47 : * Local constants
48 : *-----------------------------------------------------------------*/
49 : #define MAX_LEN_LP 960 /* maximum length in samples of the LP analysis window */
50 :
51 : /*-----------------------------------------------------------------*
52 : * Local functions
53 : *-----------------------------------------------------------------*/
54 :
55 :
56 : /*---------------------------------------------------------------------*
57 : * autocorr()
58 : *
59 : * Compute autocorrelations of input signal
60 : *---------------------------------------------------------------------*/
61 114963 : void autocorr_fx(
62 : const Word16 x[], /* i : Input signal */
63 : const Word16 m, /* i : LPC order Q0 */
64 : Word16 r_h[], /* o : Autocorrelations (msb) Q15(Q_r -16) */
65 : Word16 r_l[], /* o : Autocorrelations (lsb) Q(r)-1 */
66 : Word16 *Q_r, /* o : normalisation shift of r Q0 */
67 : const Word16 len, /* i : Frame lenght */
68 : const Word16 *wind, /* i : Window used */
69 : Word16 rev_flag,
70 : const Word16 sym_flag /* i : symmetric window flag */
71 : )
72 : {
73 : Word16 i, j, norm, shift, y[MAX_LEN_LP];
74 : Word16 fact;
75 : Word32 L_sum, L_tmp;
76 :
77 114963 : IF( EQ_16( rev_flag, 1 ) )
78 : {
79 : /* Windowing of signal */
80 0 : FOR( i = 0; i < len; i++ )
81 : {
82 0 : y[i] = mult_r( x[i], wind[len - i - 1] );
83 0 : move16();
84 : }
85 : }
86 114963 : ELSE IF( EQ_16( sym_flag, 1 ) )
87 : {
88 : /* symmetric window of even length */
89 17350403 : FOR( i = 0; i < len / 2; i++ )
90 : {
91 17237800 : y[i] = mult_r( x[i], wind[i] );
92 17237800 : move16();
93 : }
94 17350403 : FOR( ; i < len; i++ )
95 : {
96 17237800 : y[i] = mult_r( x[i], wind[len - i - 1] );
97 17237800 : move16();
98 : }
99 : }
100 : ELSE /* assymetric window */
101 : {
102 1712440 : FOR( i = 0; i < len; i++ )
103 : {
104 1710080 : y[i] = mult_r( x[i], wind[i] );
105 1710080 : move16();
106 : }
107 : }
108 :
109 :
110 : /* calculate energy of signal */
111 114963 : L_sum = L_deposit_h( 16 ); /* sqrt(256), avoid overflow after rounding */
112 18207803 : FOR( i = 0; i < len; i += 2 )
113 : {
114 18092840 : L_tmp = L_mult0( y[i], y[i] );
115 18092840 : L_tmp = L_and( L_tmp, ~( 128 - 1 ) );
116 18092840 : L_tmp = L_mac0( L_tmp, y[i + 1], y[i + 1] );
117 18092840 : L_tmp = L_shr( L_tmp, 7 );
118 18092840 : L_sum = L_add( L_sum, L_tmp );
119 : }
120 :
121 : /* scale signal to avoid overflow in autocorrelation */
122 114963 : norm = norm_l( L_sum );
123 114963 : shift = sub( 4, shr( norm, 1 ) );
124 :
125 114963 : IF( shift > 0 )
126 : {
127 1840 : fact = lshr( -32768, shift );
128 1397040 : FOR( i = 0; i < len; i++ )
129 : {
130 1395200 : y[i] = mult_r( y[i], fact );
131 1395200 : move16();
132 : }
133 : }
134 : ELSE
135 : {
136 113123 : shift = 0;
137 113123 : move16();
138 : }
139 :
140 : /* Compute and normalize r[0] */
141 114963 : L_sum = L_mac( 1, y[0], y[0] );
142 36185680 : FOR( i = 1; i < len; i++ )
143 : {
144 36070717 : L_sum = L_mac( L_sum, y[i], y[i] );
145 : }
146 114963 : norm = norm_l( L_sum );
147 114963 : L_sum = L_shl( L_sum, norm );
148 114963 : L_Extract( L_sum, &r_h[0], &r_l[0] ); /* Put in DPF format (see oper_32b) */
149 :
150 : /* Compute r[1] to r[m] */
151 702760 : FOR( i = 1; i <= m; i++ )
152 : {
153 587797 : L_sum = L_mult( y[0], y[i] );
154 196749436 : FOR( j = 1; j < len - i; j++ )
155 : {
156 196161639 : L_sum = L_mac( L_sum, y[j], y[j + i] );
157 : }
158 :
159 587797 : L_sum = L_shl( L_sum, norm );
160 587797 : L_Extract( L_sum, &r_h[i], &r_l[i] ); /* Put in DPF format (see oper_32b) */
161 : }
162 :
163 114963 : *Q_r = sub( norm, shl( shift, 1 ) );
164 114963 : move16();
165 114963 : }
166 :
167 0 : void autocorr_ivas_fx(
168 : const Word16 x[], /* i : Input signal Qx */
169 : const Word16 Qx, /* i : Q facor of Input signal Q0 */
170 : const Word16 m, /* i : LPC order Q0 */
171 : Word16 r_h[], /* o : Autocorrelations (msb) Q15(Q_r -16) */
172 : Word16 r_l[], /* o : Autocorrelations (lsb) Q(r)-1 */
173 : Word16 *Q_r, /* o : normalisation shift of r Q0 */
174 : const Word16 len, /* i : Frame lenght */
175 : const Word16 *wind, /* i : Window used */
176 : const Word16 rev_flag, /* i : flag to reverse window */
177 : const Word16 sym_flag, /* i : symmetric window flag */
178 : const Word16 no_thr /* i : flag to avoid thresholding */
179 : )
180 : {
181 : Word16 i, j, norm, y[MAX_LEN_LP];
182 : Word64 W_sum, W_temp;
183 :
184 0 : IF( EQ_16( rev_flag, 1 ) )
185 : {
186 : /* Windowing of signal */
187 0 : FOR( i = 0; i < len; i++ )
188 : {
189 0 : y[i] = mult_r( x[i], wind[len - i - 1] ); // Qx
190 0 : move16();
191 : }
192 : }
193 0 : ELSE IF( EQ_16( sym_flag, 1 ) )
194 : {
195 : /* symmetric window of even length */
196 0 : FOR( i = 0; i < len / 2; i++ )
197 : {
198 0 : y[i] = mult_r( x[i], wind[i] ); // Qx
199 0 : move16();
200 : }
201 0 : FOR( ; i < len; i++ )
202 : {
203 0 : y[i] = mult_r( x[i], wind[len - i - 1] ); // Qx
204 0 : move16();
205 : }
206 : }
207 : ELSE /* assymetric window */
208 : {
209 0 : FOR( i = 0; i < len; i++ )
210 : {
211 0 : y[i] = mult_r( x[i], wind[i] ); // Qx
212 0 : move16();
213 : }
214 : }
215 :
216 : /* calculate energy of signal */
217 : /* Compute and normalize r[0] */
218 0 : W_sum = W_mult0_16_16( y[0], y[0] );
219 0 : FOR( i = 1; i < len; i++ )
220 : {
221 0 : W_sum = W_mac0_16_16( W_sum, y[i], y[i] ); // 2*Qx
222 : }
223 : /*if (r[0] < 100.0f && no_thr == 0)
224 : {
225 : r[0] = 100.0f;
226 : }*/
227 0 : W_temp = W_shl( 1000, shl( Qx, 1 ) ); // 2*Qx
228 0 : IF( LE_64( W_sum, W_temp ) && no_thr == 0 )
229 : {
230 0 : W_sum = W_temp; // 1000.0f in 2*Qx
231 : }
232 :
233 0 : norm = W_norm( W_sum );
234 0 : W_sum = W_shl( W_sum, norm ); // 2*Qx+norm
235 :
236 0 : *Q_r = add( shl( Qx, 1 ), sub( norm, 32 ) ); // 2*Qx+norm-32
237 0 : move16();
238 :
239 0 : L_Extract( W_extract_h( W_sum ), &r_h[0], &r_l[0] ); /* Put in DPF format (see oper_32b) */ // *Q_r
240 :
241 : /* Compute r[1] to r[m] */
242 0 : FOR( i = 1; i <= m; i++ )
243 : {
244 0 : W_sum = W_mult0_16_16( y[0], y[i] );
245 0 : FOR( j = 1; j < len - i; j++ )
246 : {
247 0 : W_sum = W_mac0_16_16( W_sum, y[j], y[j + i] );
248 : }
249 :
250 0 : W_sum = W_shl( W_sum, norm ); // 2*Qx+norm-32
251 0 : L_Extract( W_extract_h( W_sum ), &r_h[i], &r_l[i] ); /* Put in DPF format (see oper_32b) */ // *Q_r
252 : }
253 :
254 0 : return;
255 : }
256 :
257 1320 : void autocorr_fx_32(
258 : const Word16 x[], /* i : Input signal Q(q_x) */
259 : const Word16 m, /* i : LPC order Q0 */
260 : Word32 r[], /* o : Autocorrelations Q_r */
261 : Word16 *Q_r, /* o : normalisation shift of r Q0 */
262 : const Word16 len, /* i : Frame lenght */
263 : const Word16 *wind, /* i : Window used Q15 */
264 : Word16 rev_flag,
265 : const Word16 sym_flag /* i : symmetric window flag */
266 : )
267 : {
268 : Word16 i, j, norm, shift, y[MAX_LEN_LP];
269 : Word16 fact;
270 : Word32 L_sum, L_tmp;
271 : Word16 tmp16;
272 :
273 1320 : IF( EQ_16( rev_flag, 1 ) )
274 : {
275 : /* Windowing of signal */
276 0 : FOR( i = 0; i < len; i++ )
277 : {
278 0 : y[i] = mult_r( x[i], wind[len - i - 1] ); // Q(x)
279 0 : move16();
280 : }
281 : }
282 1320 : ELSE IF( EQ_16( sym_flag, 1 ) )
283 : {
284 : /* symmetric window of even length */
285 0 : tmp16 = shr( len, 1 );
286 0 : FOR( i = 0; i < tmp16; i++ )
287 : {
288 0 : y[i] = mult_r( x[i], wind[i] ); // Q(x)
289 0 : move16();
290 : }
291 0 : FOR( ; i < len; i++ )
292 : {
293 0 : y[i] = mult_r( x[i], wind[len - i - 1] ); // Q(x)
294 0 : move16();
295 : }
296 : }
297 : ELSE /* assymetric window */
298 : {
299 179336 : FOR( i = 0; i < len; i++ )
300 : {
301 178016 : y[i] = mult_r( x[i], wind[i] ); // Q(x)
302 178016 : move16();
303 : }
304 : }
305 :
306 :
307 : /* calculate energy of signal */
308 1320 : L_sum = L_deposit_h( 16 ); /* sqrt(256), avoid overflow after rounding */
309 90328 : FOR( i = 0; i < len; i += 2 )
310 : {
311 89008 : L_tmp = L_mult0( y[i], y[i] ); // 2*Q(x)
312 89008 : L_tmp = L_and( L_tmp, ~( 128 - 1 ) );
313 89008 : L_tmp = L_mac0( L_tmp, y[i + 1], y[i + 1] ); // 2*Q(x)
314 89008 : L_tmp = L_shr( L_tmp, 7 );
315 89008 : L_sum = L_add( L_sum, L_tmp );
316 : }
317 :
318 : /* scale signal to avoid overflow in autocorrelation */
319 1320 : norm = norm_l( L_sum );
320 1320 : shift = sub( 4, shr( norm, 1 ) );
321 :
322 1320 : IF( shift > 0 )
323 : {
324 11 : fact = lshr( -32768, shift );
325 1515 : FOR( i = 0; i < len; i++ )
326 : {
327 1504 : y[i] = mult_r( y[i], fact ); // Q(x)
328 1504 : move16();
329 : }
330 : }
331 : ELSE
332 : {
333 1309 : shift = 0;
334 1309 : move16();
335 : }
336 :
337 : /* Compute and normalize r[0] */
338 1320 : L_sum = L_mac( 1, y[0], y[0] ); // 2*Q(x)
339 178016 : FOR( i = 1; i < len; i++ )
340 : {
341 176696 : L_sum = L_mac( L_sum, y[i], y[i] ); // 2*Q(x)
342 : }
343 1320 : norm = norm_l( L_sum );
344 1320 : L_sum = L_shl( L_sum, norm );
345 1320 : r[0] = L_sum;
346 1320 : move32();
347 :
348 : /* Compute r[1] to r[m] */
349 22440 : FOR( i = 1; i <= m; i++ )
350 : {
351 21120 : L_sum = L_mult( y[0], y[i] ); // 2*Q(x)+1
352 21120 : tmp16 = sub( len, i );
353 2668736 : FOR( j = 1; j < tmp16; j++ )
354 : {
355 2647616 : L_sum = L_mac( L_sum, y[j], y[j + i] ); // 2*Q(x)+1
356 : }
357 :
358 21120 : L_sum = L_shl( L_sum, norm ); // 2*Q(x)+1+norm
359 21120 : r[i] = L_sum;
360 21120 : move32();
361 : }
362 :
363 1320 : *Q_r = sub( norm, shl( shift, 1 ) );
364 1320 : move16();
365 1320 : }
366 :
367 : /*****************************************************************************
368 : * *
369 : * Function Name : Div_32_opt *
370 : * *
371 : * Purpose : *
372 : * Fractional integer division of two 32 bit numbers. *
373 : * L_num / L_denom. *
374 : * L_num and L_denom must be positive and L_num < L_denom. *
375 : * L_denom = denom_hi<<16 + denom_lo<<1 *
376 : * denom_hi is a normalize number. *
377 : * *
378 : * Inputs : *
379 : * *
380 : * L_num *
381 : * 32 bit long signed integer (Word32) whose value falls in the *
382 : * range : 0x0000 0000 < L_num < L_denom *
383 : * *
384 : * L_denom = denom_hi<<16 + denom_lo<<1 (DPF) *
385 : * *
386 : * denom_hi *
387 : * 16 bit positive normalized integer whose value falls in the *
388 : * range : 0x4000 < hi < 0x7fff *
389 : * denom_lo *
390 : * 16 bit positive integer whose value falls in the *
391 : * range : 0 < lo < 0x7fff *
392 : * *
393 : * Return Value : *
394 : * *
395 : * L_div *
396 : * 32 bit long signed integer (Word32) whose value falls in the *
397 : * range : 0x0000 0000 <= L_div <= 0x7fff ffff. *
398 : * *
399 : * Algorithm: *
400 : * *
401 : * - find = 1/L_denom. *
402 : * First approximation: approx = 1 / denom_hi *
403 : * 1/L_denom = approx * (2.0 - L_denom * approx ) *
404 : * *
405 : * - result = L_num * (1/L_denom) *
406 : *****************************************************************************
407 : */
408 595018 : static Word32 Div_32_opt( Word32 L_num /*Q31*/, Word16 denom_hi /*Qx -16*/, Word16 denom_lo /*Qx -1*/ )
409 : {
410 : Word16 approx /*, hi, lo, n_hi , n_lo*/;
411 : Word32 L_32;
412 : #ifndef ISSUE_1836_replace_overflow_libcom
413 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
414 : Flag Overflow = 0;
415 : #endif
416 : #endif
417 :
418 : /* First approximation: 1 / L_denom = 1/denom_hi */
419 :
420 595018 : approx = div_s( (Word16) 0x3fff, denom_hi );
421 :
422 : /* 1/L_denom = approx * (2.0 - L_denom * approx) */
423 :
424 595018 : L_32 = Msu_32_16( (Word32) 0x7fffffffL, denom_hi, denom_lo, approx );
425 :
426 595018 : L_32 = Mpy_32_16_1( L_32, approx );
427 :
428 : /* L_num * (1/L_denom) */
429 :
430 595018 : L_32 = Mpy_32_32( L_num, L_32 );
431 :
432 : #ifdef ISSUE_1836_replace_overflow_libcom
433 595018 : L_32 = L_shl_sat( L_32, 2 );
434 : #else
435 : L_32 = L_shl_o( L_32, 2, &Overflow );
436 : #endif
437 :
438 595018 : return ( L_32 );
439 : }
440 :
441 : /*
442 : * E_LPC_lev_dur
443 : *
444 : * Parameters:
445 : * Rh I: Rh[m+1] Vector of autocorrelations (msb)
446 : * Rl I: Rl[m+1] Vector of autocorrelations (lsb)
447 : * A O: A[m] LPC coefficients (m = 16) Qx (A[0] is always 1, so the format can be deduced in the caller with norm_s(A[0]))
448 : * epsP O: error vector, msb
449 : * order I: LPC order Q0
450 : *
451 : * Function:
452 : * Levinson-Durbin algorithm to compute
453 : * the LPC parameters from the autocorrelations of speech.
454 : *
455 : * Returns:
456 : * void
457 : */
458 120700 : Word16 E_LPC_lev_dur( const Word16 Rh[] /*QR -16*/, const Word16 Rl[] /*QR -1*/, Word16 A[] /*Qx*/, Word32 epsP[] /*QR*/, const Word16 order, Word16 *mem /*Qx*/ )
459 : {
460 120700 : return ( E_LPC_lev_dur_stab( Rh, Rl, A, epsP, order, mem, 32750 ) ); /* 0.99945 in Q15 */
461 : }
462 :
463 120700 : Word16 E_LPC_lev_dur_stab( const Word16 Rh[] /*QR -16*/, const Word16 Rl[] /*QR -1*/, Word16 A[] /*Qx*/, Word32 epsP[] /*QR*/, const Word16 order, Word16 *mem /*Qx*/, Word16 k_max /*Q15*/ )
464 : {
465 : Word16 i, j, k;
466 : Word16 hi, lo;
467 : Word16 Kh, Kl; /* reflection coefficient; hi and lo */
468 : Word16 alp_h, alp_l, alp_exp; /* Prediction gain; hi lo and exponent */
469 : Word32 t0, t1, t2; /* temporary variables */
470 : Word16 flag;
471 : Word16 Ah[TCXLTP_LTP_ORDER + 1], Al[TCXLTP_LTP_ORDER + 1]; /* LPC coef. in double prec. */
472 : #ifndef ISSUE_1836_replace_overflow_libcom
473 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
474 : Flag Overflow = 0;
475 : #endif
476 : #endif
477 :
478 :
479 : BASOP_SATURATE_WARNING_OFF_EVS
480 120700 : if ( epsP != NULL )
481 : {
482 115899 : epsP[0] = L_Comp( Rh[0], Rl[0] );
483 115899 : move32();
484 : }
485 :
486 120700 : flag = 0;
487 120700 : move16();
488 :
489 : /* K = A[1] = -R[1] / R[0] */
490 120700 : t1 = L_Comp( Rh[1], Rl[1] ); /* R[1] in Q31 */
491 120700 : t2 = L_abs( t1 ); /* abs R[1] */
492 120700 : t0 = L_deposit_l( 0 );
493 120700 : IF( Rh[0] != 0 )
494 : {
495 120698 : t0 = Div_32_opt( t2, Rh[0], Rl[0] ); /* R[1]/R[0] in Q31 */
496 : /* Cause a difference in MODE1 due to different implementation of div32*/
497 : }
498 120700 : if ( t1 > 0 )
499 : {
500 8101 : t0 = L_negate( t0 ); /* -R[1]/R[0] */
501 : }
502 120700 : Kl = L_Extract_lc( t0, &Kh ); /* K in DPF */
503 120700 : t0 = L_shr( t0, 4 ); /* A[1] in Q27 */
504 120700 : L_Extract( t0, &Ah[1], &Al[1] ); /* A[1] in DPF */
505 :
506 : /* Alpha = R[0] * (1-K**2) */
507 120700 : t0 = Sqr_32( Kh, Kl ); /* K*K in Q31 */
508 120700 : t0 = L_abs( t0 ); /* Some case <0 !! */
509 120700 : t0 = L_sub( (Word32) 0x7fffffffL, t0 ); /* 1 - K*K in Q31 */
510 120700 : lo = L_Extract_lc( t0, &hi ); /* DPF format */
511 120700 : t0 = Mpy_32( Rh[0], Rl[0], hi, lo ); /* Alpha in Q31 */
512 120700 : if ( epsP != NULL )
513 : {
514 115899 : epsP[1] = t0;
515 115899 : move32();
516 : }
517 :
518 : /* Normalize Alpha */
519 120700 : alp_exp = norm_l( t0 );
520 120700 : t0 = L_shl( t0, alp_exp );
521 120700 : alp_l = L_Extract_lc( t0, &alp_h );
522 : /* DPF format */
523 :
524 : /*--------------------------------------*
525 : * ITERATIONS I=2 to m
526 : *--------------------------------------*/
527 :
528 569082 : FOR( i = 2; i <= order; i++ )
529 : {
530 : /* t0 = SUM(R[j]*A[i-j], j=1, i-1) + R[i] */
531 448382 : t0 = L_deposit_l( 0 );
532 2104067 : FOR( j = 1; j < i; j++ )
533 : {
534 1655685 : t0 = Mac_32( t0, Rh[j], Rl[j], Ah[i - j], Al[i - j] );
535 : }
536 :
537 : #ifdef ISSUE_1836_replace_overflow_libcom
538 448382 : t0 = L_shl_sat( t0, 4 ); /* result in Q27 -> convert to Q31 */
539 : #else
540 : t0 = L_shl_o( t0, 4, &Overflow ); /* result in Q27 -> convert to Q31 */
541 : #endif
542 : /* No overflow possible */
543 :
544 : /* Compose and add R[i] in Q3 */
545 : #ifdef ISSUE_1836_replace_overflow_libcom
546 448382 : t0 = L_mac_sat( t0, Rl[i], 1 );
547 448382 : t0 = L_msu_sat( t0, Rh[i], -32768 );
548 : #else
549 : t0 = L_mac_o( t0, Rl[i], 1, &Overflow );
550 : t0 = L_msu_o( t0, Rh[i], -32768, &Overflow );
551 : #endif
552 :
553 : /* K = -t0 / Alpha */
554 448382 : t1 = L_abs( t0 );
555 448382 : t2 = L_deposit_l( 0 );
556 448382 : IF( alp_h != 0 )
557 : {
558 448352 : t2 = Div_32_opt( t1, alp_h, alp_l ); /* abs(t0)/Alpha */
559 : /* Cause a difference in MODE1 due to different implementation of div32*/
560 : }
561 :
562 448382 : if ( t0 > 0 )
563 : {
564 202401 : t2 = L_negate( t2 ); /* K =-t0/Alpha */
565 : }
566 : #ifdef ISSUE_1836_replace_overflow_libcom
567 448382 : t2 = L_shl_sat( t2, alp_exp ); /* denormalize; compare to Alpha */
568 : #else
569 : t2 = L_shl_o( t2, alp_exp, &Overflow ); /* denormalize; compare to Alpha */
570 : #endif
571 448382 : test();
572 448382 : if ( ( mem != NULL ) && ( ( GT_16( abs_s( extract_h( t2 ) ), k_max ) ) ) )
573 : {
574 0 : flag = 1;
575 0 : move16(); /* Test for unstable filter. If unstable keep old A(z) */
576 : }
577 448382 : test();
578 448382 : if ( ( mem != NULL ) && ( ( LT_32( L_abs( t2 ), 5 ) ) ) )
579 : {
580 0 : flag = 1;
581 0 : move16(); /*R matrix not reliable (R saturated for many coeff), keep old A(z) */
582 : }
583 448382 : Kl = L_Extract_lc( t2, &Kh ); /* K in DPF */
584 :
585 : /*------------------------------------------*
586 : * Compute new LPC coeff. -> An[i]
587 : * An[j]= A[j] + K*A[i-j] , j=1 to i-1
588 : * An[i]= K
589 : *------------------------------------------*/
590 :
591 448382 : k = mult_r( i, 16384 );
592 1133954 : FOR( j = 1; j < k; j++ )
593 : {
594 : /* Do two Iterations Together to Allow Direct Update of Ah & Al */
595 685572 : t0 = Mac_32( L_Comp( Ah[j], Al[j] ), Kh, Kl, Ah[i - j], Al[i - j] );
596 685572 : t1 = Mac_32( L_Comp( Ah[i - j], Al[i - j] ), Kh, Kl, Ah[j], Al[j] );
597 685572 : L_Extract( t0, &Ah[j], &Al[j] );
598 685572 : L_Extract( t1, &Ah[i - j], &Al[i - j] );
599 : }
600 448382 : IF( s_and( i, 1 ) == 0 )
601 : {
602 284541 : t0 = Mac_32( L_Comp( Ah[j], Al[j] ), Kh, Kl, Ah[i - j], Al[i - j] );
603 284541 : L_Extract( t0, &Ah[j], &Al[j] );
604 : }
605 448382 : t2 = L_shr( t2, 4 ); /* t2 = K in Q31 ->convert to Q27 */
606 448382 : L_Extract( t2, &Ah[i], &Al[i] ); /* An[i] in Q27 */
607 :
608 : /* Alpha = Alpha * (1-K**2) */
609 : #ifdef ISSUE_1836_replace_overflow_libcom
610 448382 : t1 = L_mult_sat( Kh, Kh ); /* K*K in Q31 */
611 : #else
612 : t1 = L_mult_o( Kh, Kh, &Overflow ); /* K*K in Q31 */
613 : #endif
614 448382 : t0 = L_mac( t1, mult( Kh, Kl ), 2 );
615 448382 : t0 = L_abs( t0 ); /* Some case <0 !! */
616 448382 : t0 = L_sub( (Word32) 0x7fffffffL, t0 ); /* 1 - K*K in Q31 */
617 448382 : lo = L_Extract_lc( t0, &hi ); /* DPF format */
618 448382 : t0 = Mpy_32( alp_h, alp_l, hi, lo ); /* Alpha in Q31 */
619 :
620 :
621 : /* store denormalized alpha in epsP */
622 448382 : t1 = L_shr( t0, alp_exp );
623 448382 : if ( epsP != NULL )
624 : {
625 374271 : epsP[i] = t1;
626 374271 : move32();
627 : }
628 :
629 : /* Normalize Alpha */
630 448382 : j = norm_l( t0 );
631 448382 : t0 = L_shl( t0, j );
632 448382 : alp_l = L_Extract_lc( t0, &alp_h ); /* DPF format */
633 448382 : alp_exp = add( alp_exp, j ); /* Add normalization to alp_exp */
634 : }
635 :
636 : /* Adaptive scaling */
637 120700 : t1 = L_deposit_l( 0 );
638 689782 : FOR( i = 1; i <= order; i++ )
639 : {
640 569082 : t0 = L_Comp( Ah[i], Al[i] );
641 569082 : t1 = L_max( t1, L_abs( t0 ) );
642 : }
643 120700 : k = s_min( norm_l( t1 ), 3 );
644 120700 : A[0] = shl( 2048, k );
645 120700 : move16();
646 689782 : FOR( i = 1; i <= order; i++ )
647 : {
648 569082 : t0 = L_Comp( Ah[i], Al[i] );
649 : #ifdef ISSUE_1836_replace_overflow_libcom
650 569082 : A[i] = round_fx_sat( L_shl_sat( t0, k ) );
651 : #else
652 : A[i] = round_fx_o( L_shl_o( t0, k, &Overflow ), &Overflow );
653 : #endif
654 569082 : move16();
655 : }
656 :
657 : BASOP_SATURATE_WARNING_ON_EVS
658 120700 : IF( mem != NULL )
659 : {
660 : /* Enforce stable LPC filter - parcorr[0] and parcorr[1] are not LPC coeffiecients */
661 3296 : IF( flag )
662 : {
663 0 : Copy( mem, A, add( order, 1 ) );
664 : }
665 : ELSE /* If stable LPC filter, store into memories */
666 : {
667 3296 : Copy( A, mem, add( order, 1 ) );
668 : }
669 : }
670 :
671 :
672 120700 : return ( flag );
673 : }
674 :
675 1623 : Word16 E_LPC_lev_dur_ivas_fx( const Word16 Rh[], const Word16 Rl[], Word16 A[], Word32 epsP[], const Word16 order, Word16 *mem )
676 : {
677 1623 : return ( E_LPC_lev_dur_stab_ivas_fx( Rh, Rl, A, epsP, order, mem, 32750 ) ); /* 0.99945 in Q15 */
678 : }
679 :
680 1623 : Word16 E_LPC_lev_dur_stab_ivas_fx( const Word16 Rh[], const Word16 Rl[], Word16 A[], Word32 epsP[], const Word16 order, Word16 *mem, Word16 k_max )
681 : {
682 : Word16 i, j, k;
683 : Word16 hi, lo;
684 : Word16 Kh, Kl; /* reflection coefficient; hi and lo */
685 : Word16 alp_h, alp_l, alp_exp; /* Prediction gain; hi lo and exponent */
686 : Word32 t0, t1, t2; /* temporary variables */
687 : Word16 flag;
688 : Word16 Ah[TCXLTP_LTP_ORDER + 1], Al[TCXLTP_LTP_ORDER + 1]; /* LPC coef. in double prec. */
689 : #ifndef ISSUE_1836_replace_overflow_libcom
690 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
691 : Flag Overflow = 0;
692 : #endif
693 : #endif
694 :
695 :
696 : BASOP_SATURATE_WARNING_OFF_EVS
697 1623 : if ( epsP != NULL )
698 : {
699 0 : epsP[0] = L_Comp( Rh[0], Rl[0] );
700 0 : move32();
701 : }
702 :
703 1623 : flag = 0;
704 1623 : move16();
705 :
706 : /* K = A[1] = -R[1] / R[0] */
707 1623 : t1 = L_Comp( Rh[1], Rl[1] ); /* R[1] in Q31 */
708 1623 : t2 = L_abs( t1 ); /* abs R[1] */
709 1623 : t0 = L_deposit_l( 0 );
710 1623 : IF( Rh[0] != 0 )
711 : {
712 1623 : t0 = Div_32_opt( t2, Rh[0], Rl[0] ); /* R[1]/R[0] in Q31 */
713 : /* Cause a difference in MODE1 due to different implementation of div32*/
714 : }
715 1623 : if ( t1 > 0 )
716 : {
717 1610 : t0 = L_negate( t0 ); /* -R[1]/R[0] */
718 : }
719 1623 : Kl = L_Extract_lc( t0, &Kh ); /* K in DPF */
720 1623 : t0 = L_shr( t0, 4 ); /* A[1] in Q27 */
721 1623 : L_Extract( t0, &Ah[1], &Al[1] ); /* A[1] in DPF */
722 :
723 : /* Alpha = R[0] * (1-K**2) */
724 1623 : t0 = Sqr_32( Kh, Kl ); /* K*K in Q31 */
725 1623 : t0 = L_abs( t0 ); /* Some case <0 !! */
726 1623 : t0 = L_sub( (Word32) 0x7fffffffL, t0 ); /* 1 - K*K in Q31 */
727 1623 : lo = L_Extract_lc( t0, &hi ); /* DPF format */
728 1623 : t0 = Mpy_32( Rh[0], Rl[0], hi, lo ); /* Alpha in Q31 */
729 1623 : if ( epsP != NULL )
730 : {
731 0 : epsP[1] = t0;
732 0 : move32();
733 : }
734 :
735 : /* Normalize Alpha */
736 1623 : alp_exp = norm_l( t0 );
737 1623 : t0 = L_shl( t0, alp_exp );
738 1623 : alp_l = L_Extract_lc( t0, &alp_h );
739 : /* DPF format */
740 :
741 : /*--------------------------------------*
742 : * ITERATIONS I=2 to m
743 : *--------------------------------------*/
744 :
745 25968 : FOR( i = 2; i <= order; i++ )
746 : {
747 : /* t0 = SUM(R[j]*A[i-j], j=1, i-1) + R[i] */
748 24345 : t0 = L_deposit_l( 0 );
749 219105 : FOR( j = 1; j < i; j++ )
750 : {
751 194760 : t0 = Mac_32( t0, Rh[j], Rl[j], Ah[i - j], Al[i - j] );
752 : }
753 :
754 : #ifdef ISSUE_1836_replace_overflow_libcom
755 24345 : t0 = L_shl_sat( t0, 4 ); /* result in Q27 -> convert to Q31 */
756 : #else
757 : t0 = L_shl_o( t0, 4, &Overflow ); /* result in Q27 -> convert to Q31 */
758 : #endif
759 : /* No overflow possible */
760 :
761 : /* Compose and add R[i] in Q3 */
762 : #ifdef ISSUE_1836_replace_overflow_libcom
763 24345 : t0 = L_mac_sat( t0, Rl[i], 1 );
764 24345 : t0 = L_msu_sat( t0, Rh[i], -32768 );
765 : #else
766 : t0 = L_mac_o( t0, Rl[i], 1, &Overflow );
767 : t0 = L_msu_o( t0, Rh[i], -32768, &Overflow );
768 : #endif
769 :
770 : /* K = -t0 / Alpha */
771 24345 : t1 = L_abs( t0 );
772 24345 : t2 = L_deposit_l( 0 );
773 24345 : IF( alp_h != 0 )
774 : {
775 24345 : t2 = Div_32_opt( t1, alp_h, alp_l ); /* abs(t0)/Alpha */
776 : /* Cause a difference in MODE1 due to different implementation of div32*/
777 : }
778 :
779 24345 : if ( t0 > 0 )
780 : {
781 10692 : t2 = L_negate( t2 ); /* K =-t0/Alpha */
782 : }
783 : #ifdef ISSUE_1836_replace_overflow_libcom
784 24345 : t2 = L_shl_sat( t2, alp_exp ); /* denormalize; compare to Alpha */
785 : #else
786 : t2 = L_shl_o( t2, alp_exp, &Overflow ); /* denormalize; compare to Alpha */
787 : #endif
788 24345 : test();
789 24345 : if ( ( mem != NULL ) && ( ( GT_16( abs_s( extract_h( t2 ) ), k_max ) ) ) )
790 : {
791 0 : flag = 1;
792 0 : move16(); /* Test for unstable filter. If unstable keep old A(z) */
793 : }
794 24345 : test();
795 24345 : if ( ( mem != NULL ) && ( ( LT_32( L_abs( t2 ), 5 ) ) ) )
796 : {
797 0 : flag = 1;
798 0 : move16(); /*R matrix not reliable (R saturated for many coeff), keep old A(z) */
799 : }
800 24345 : Kl = L_Extract_lc( t2, &Kh ); /* K in DPF */
801 :
802 : /*------------------------------------------*
803 : * Compute new LPC coeff. -> An[i]
804 : * An[j]= A[j] + K*A[i-j] , j=1 to i-1
805 : * An[i]= K
806 : *------------------------------------------*/
807 :
808 24345 : k = mult_r( i, 16384 );
809 115233 : FOR( j = 1; j < k; j++ )
810 : {
811 : /* Do two Iterations Together to Allow Direct Update of Ah & Al */
812 90888 : t0 = Mac_32( L_Comp( Ah[j], Al[j] ), Kh, Kl, Ah[i - j], Al[i - j] );
813 90888 : t1 = Mac_32( L_Comp( Ah[i - j], Al[i - j] ), Kh, Kl, Ah[j], Al[j] );
814 90888 : L_Extract( t0, &Ah[j], &Al[j] );
815 90888 : L_Extract( t1, &Ah[i - j], &Al[i - j] );
816 : }
817 24345 : IF( s_and( i, 1 ) == 0 )
818 : {
819 12984 : t0 = Mac_32( L_Comp( Ah[j], Al[j] ), Kh, Kl, Ah[i - j], Al[i - j] );
820 12984 : L_Extract( t0, &Ah[j], &Al[j] );
821 : }
822 24345 : t2 = L_shr( t2, 4 ); /* t2 = K in Q31 ->convert to Q27 */
823 24345 : L_Extract( t2, &Ah[i], &Al[i] ); /* An[i] in Q27 */
824 :
825 : /* Alpha = Alpha * (1-K**2) */
826 : #ifdef ISSUE_1836_replace_overflow_libcom
827 24345 : t1 = L_mult_sat( Kh, Kh ); /* K*K in Q31 */
828 : #else
829 : t1 = L_mult_o( Kh, Kh, &Overflow ); /* K*K in Q31 */
830 : #endif
831 24345 : t0 = L_mac( t1, mult( Kh, Kl ), 2 );
832 24345 : t0 = L_abs( t0 ); /* Some case <0 !! */
833 24345 : t0 = L_sub( (Word32) 0x7fffffffL, t0 ); /* 1 - K*K in Q31 */
834 24345 : lo = L_Extract_lc( t0, &hi ); /* DPF format */
835 24345 : t0 = Mpy_32( alp_h, alp_l, hi, lo ); /* Alpha in Q31 */
836 :
837 :
838 : /* store denormalized alpha in epsP */
839 24345 : t1 = L_shr( t0, alp_exp );
840 24345 : if ( epsP != NULL )
841 : {
842 0 : epsP[i] = t1;
843 0 : move32();
844 : }
845 :
846 : /* Normalize Alpha */
847 24345 : j = norm_l( t0 );
848 24345 : t0 = L_shl( t0, j );
849 24345 : alp_l = L_Extract_lc( t0, &alp_h ); /* DPF format */
850 24345 : alp_exp = add( alp_exp, j ); /* Add normalization to alp_exp */
851 : }
852 :
853 : /* Adaptive scaling */
854 1623 : t1 = L_deposit_l( 0 );
855 27591 : FOR( i = 1; i <= order; i++ )
856 : {
857 25968 : t0 = L_Comp( Ah[i], Al[i] );
858 25968 : t1 = L_max( t1, L_abs( t0 ) );
859 : }
860 1623 : k = s_min( sub( norm_l( t1 ), 1 ), 3 );
861 1623 : A[0] = shl( 2048, k );
862 1623 : move16();
863 27591 : FOR( i = 1; i <= order; i++ )
864 : {
865 25968 : t0 = L_Comp( Ah[i], Al[i] );
866 : #ifdef ISSUE_1836_replace_overflow_libcom
867 25968 : A[i] = round_fx_sat( L_shl_sat( t0, k ) );
868 : #else
869 : A[i] = round_fx_o( L_shl_o( t0, k, &Overflow ), &Overflow );
870 : #endif
871 25968 : move16();
872 : }
873 :
874 : BASOP_SATURATE_WARNING_ON_EVS
875 1623 : IF( mem != NULL )
876 : {
877 : /* Enforce stable LPC filter - parcorr[0] and parcorr[1] are not LPC coeffiecients */
878 0 : IF( flag )
879 : {
880 0 : Copy( mem, A, add( order, 1 ) );
881 : }
882 : ELSE /* If stable LPC filter, store into memories */
883 : {
884 0 : Copy( A, mem, add( order, 1 ) );
885 : }
886 : }
887 :
888 :
889 1623 : return ( flag );
890 : }
891 :
892 0 : Word16 E_LPC_lev_dur_fx( const Word16 Rh[] /*QR -16*/, const Word16 Rl[] /*QR -1*/, Word32 A[] /*QA*/, Word32 epsP[] /*QR*/, const Word16 order, Word32 *mem /*QA*/ )
893 : {
894 0 : return ( E_LPC_lev_dur_stab_fx( Rh, Rl, A, epsP, order, mem, 32750 ) ); /* 0.99945 in Q15 */
895 : }
896 :
897 0 : Word16 E_LPC_lev_dur_stab_fx( const Word16 Rh[] /*QR -16*/, const Word16 Rl[] /*QR -1*/, Word32 A[] /*QA*/, Word32 epsP[] /*QR*/, const Word16 order, Word32 *mem /*QA*/, Word16 k_max /*Q15*/ )
898 : {
899 : Word16 i, j, k;
900 : Word16 hi, lo;
901 : Word16 Kh, Kl; /* reflection coefficient; hi and lo */
902 : Word16 alp_h, alp_l, alp_exp; /* Prediction gain; hi lo and exponent */
903 : Word32 t0, t1, t2; /* temporary variables */
904 : Word16 flag;
905 : Word16 Ah[TCXLTP_LTP_ORDER + 1], Al[TCXLTP_LTP_ORDER + 1]; /* LPC coef. in double prec. */
906 : #ifndef ISSUE_1836_replace_overflow_libcom
907 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
908 : Flag Overflow = 0;
909 : move32();
910 : #endif
911 : #endif
912 :
913 :
914 : BASOP_SATURATE_WARNING_OFF_EVS
915 0 : if ( epsP != NULL )
916 : {
917 0 : epsP[0] = L_Comp( Rh[0], Rl[0] );
918 0 : move32();
919 : }
920 :
921 0 : flag = 0;
922 0 : move16();
923 :
924 : /* K = A[1] = -R[1] / R[0] */
925 0 : t1 = L_Comp( Rh[1], Rl[1] ); /* R[1] in Q31 */
926 0 : t2 = L_abs( t1 ); /* abs R[1] */
927 0 : t0 = L_deposit_l( 0 );
928 0 : IF( Rh[0] != 0 )
929 : {
930 0 : t0 = Div_32_opt( t2, Rh[0], Rl[0] ); /* R[1]/R[0] in Q31 */
931 : /* Cause a difference in MODE1 due to different implementation of div32*/
932 : }
933 0 : if ( t1 > 0 )
934 : {
935 0 : t0 = L_negate( t0 ); /* -R[1]/R[0] */
936 : }
937 0 : Kl = L_Extract_lc( t0, &Kh ); /* K in DPF */
938 0 : t0 = L_shr( t0, 4 ); /* A[1] in Q27 */
939 0 : L_Extract( t0, &Ah[1], &Al[1] ); /* A[1] in DPF */
940 :
941 : /* Alpha = R[0] * (1-K**2) */
942 0 : t0 = Sqr_32( Kh, Kl ); /* K*K in Q31 */
943 0 : t0 = L_abs( t0 ); /* Some case <0 !! */
944 0 : t0 = L_sub( (Word32) 0x7fffffffL, t0 ); /* 1 - K*K in Q31 */
945 0 : lo = L_Extract_lc( t0, &hi ); /* DPF format */
946 0 : t0 = Mpy_32( Rh[0], Rl[0], hi, lo ); /* Alpha in Q31 */
947 0 : if ( epsP != NULL )
948 : {
949 0 : epsP[1] = t0;
950 0 : move32();
951 : }
952 :
953 : /* Normalize Alpha */
954 0 : alp_exp = norm_l( t0 );
955 0 : t0 = L_shl( t0, alp_exp );
956 0 : alp_l = L_Extract_lc( t0, &alp_h );
957 : /* DPF format */
958 :
959 : /*--------------------------------------*
960 : * ITERATIONS I=2 to m
961 : *--------------------------------------*/
962 :
963 0 : FOR( i = 2; i <= order; i++ )
964 : {
965 : /* t0 = SUM(R[j]*A[i-j], j=1, i-1) + R[i] */
966 0 : t0 = L_deposit_l( 0 );
967 0 : FOR( j = 1; j < i; j++ )
968 : {
969 0 : t0 = Mac_32( t0, Rh[j], Rl[j], Ah[i - j], Al[i - j] );
970 : }
971 :
972 : #ifdef ISSUE_1836_replace_overflow_libcom
973 0 : t0 = L_shl_sat( t0, 4 ); /* result in Q27 -> convert to Q31 */
974 : #else
975 : t0 = L_shl_o( t0, 4, &Overflow ); /* result in Q27 -> convert to Q31 */
976 : #endif
977 : /* No overflow possible */
978 :
979 : /* Compose and add R[i] in Q3 */
980 : #ifdef ISSUE_1836_replace_overflow_libcom
981 0 : t0 = L_mac_sat( t0, Rl[i], 1 );
982 0 : t0 = L_msu_sat( t0, Rh[i], -32768 );
983 : #else
984 : t0 = L_mac_o( t0, Rl[i], 1, &Overflow );
985 : t0 = L_msu_o( t0, Rh[i], -32768, &Overflow );
986 : #endif
987 :
988 : /* K = -t0 / Alpha */
989 0 : t1 = L_abs( t0 );
990 0 : t2 = L_deposit_l( 0 );
991 0 : IF( alp_h != 0 )
992 : {
993 0 : t2 = Div_32_opt( t1, alp_h, alp_l ); /* abs(t0)/Alpha */
994 : /* Cause a difference in MODE1 due to different implementation of div32*/
995 : }
996 :
997 0 : if ( t0 > 0 )
998 : {
999 0 : t2 = L_negate( t2 ); /* K =-t0/Alpha */
1000 : }
1001 : #ifdef ISSUE_1836_replace_overflow_libcom
1002 0 : t2 = L_shl_sat( t2, alp_exp ); /* denormalize; compare to Alpha */
1003 : #else
1004 : t2 = L_shl_o( t2, alp_exp, &Overflow ); /* denormalize; compare to Alpha */
1005 : #endif
1006 0 : test();
1007 0 : if ( ( mem != NULL ) && ( ( GT_16( abs_s( extract_h( t2 ) ), k_max ) ) ) )
1008 : {
1009 0 : flag = 1;
1010 0 : move16(); /* Test for unstable filter. If unstable keep old A(z) */
1011 : }
1012 0 : test();
1013 0 : if ( ( mem != NULL ) && ( ( LT_32( L_abs( t2 ), 5 ) ) ) )
1014 : {
1015 0 : flag = 1;
1016 0 : move16(); /*R matrix not reliable (R saturated for many coeff), keep old A(z) */
1017 : }
1018 0 : Kl = L_Extract_lc( t2, &Kh ); /* K in DPF */
1019 :
1020 : /*------------------------------------------*
1021 : * Compute new LPC coeff. -> An[i]
1022 : * An[j]= A[j] + K*A[i-j] , j=1 to i-1
1023 : * An[i]= K
1024 : *------------------------------------------*/
1025 :
1026 0 : k = mult_r( i, 16384 );
1027 0 : FOR( j = 1; j < k; j++ )
1028 : {
1029 : /* Do two Iterations Together to Allow Direct Update of Ah & Al */
1030 0 : t0 = Mac_32( L_Comp( Ah[j], Al[j] ), Kh, Kl, Ah[i - j], Al[i - j] );
1031 0 : t1 = Mac_32( L_Comp( Ah[i - j], Al[i - j] ), Kh, Kl, Ah[j], Al[j] );
1032 0 : L_Extract( t0, &Ah[j], &Al[j] );
1033 0 : L_Extract( t1, &Ah[i - j], &Al[i - j] );
1034 : }
1035 0 : IF( s_and( i, 1 ) == 0 )
1036 : {
1037 0 : t0 = Mac_32( L_Comp( Ah[j], Al[j] ), Kh, Kl, Ah[i - j], Al[i - j] );
1038 0 : L_Extract( t0, &Ah[j], &Al[j] );
1039 : }
1040 0 : t2 = L_shr( t2, 4 ); /* t2 = K in Q31 ->convert to Q27 */
1041 0 : L_Extract( t2, &Ah[i], &Al[i] ); /* An[i] in Q27 */
1042 :
1043 : /* Alpha = Alpha * (1-K**2) */
1044 : #ifdef ISSUE_1836_replace_overflow_libcom
1045 0 : t1 = L_mult_sat( Kh, Kh ); /* K*K in Q31 */
1046 : #else
1047 : t1 = L_mult_o( Kh, Kh, &Overflow ); /* K*K in Q31 */
1048 : #endif
1049 0 : t0 = L_mac( t1, mult( Kh, Kl ), 2 );
1050 0 : t0 = L_abs( t0 ); /* Some case <0 !! */
1051 0 : t0 = L_sub( (Word32) 0x7fffffffL, t0 ); /* 1 - K*K in Q31 */
1052 0 : lo = L_Extract_lc( t0, &hi ); /* DPF format */
1053 0 : t0 = Mpy_32( alp_h, alp_l, hi, lo ); /* Alpha in Q31 */
1054 :
1055 :
1056 : /* store denormalized alpha in epsP */
1057 0 : t1 = L_shr( t0, alp_exp );
1058 0 : if ( epsP != NULL )
1059 : {
1060 0 : epsP[i] = t1;
1061 0 : move32();
1062 : }
1063 :
1064 : /* Normalize Alpha */
1065 0 : j = norm_l( t0 );
1066 0 : t0 = L_shl( t0, j );
1067 0 : alp_l = L_Extract_lc( t0, &alp_h ); /* DPF format */
1068 0 : alp_exp = add( alp_exp, j ); /* Add normalization to alp_exp */
1069 : }
1070 :
1071 : /* Adaptive scaling */
1072 0 : t1 = L_deposit_l( 0 );
1073 0 : FOR( i = 1; i <= order; i++ )
1074 : {
1075 0 : t0 = L_Comp( Ah[i], Al[i] );
1076 0 : t1 = L_max( t1, L_abs( t0 ) );
1077 : }
1078 0 : k = s_min( norm_l( t1 ), 3 );
1079 0 : A[0] = L_shl( 2048, k + 16 );
1080 0 : move16();
1081 0 : FOR( i = 1; i <= order; i++ )
1082 : {
1083 0 : t0 = L_Comp( Ah[i], Al[i] );
1084 : #ifdef ISSUE_1836_replace_overflow_libcom
1085 0 : A[i] = L_shl_sat( t0, k );
1086 : #else
1087 : A[i] = L_shl_o( t0, k, &Overflow );
1088 : #endif
1089 0 : move16();
1090 : }
1091 :
1092 : BASOP_SATURATE_WARNING_ON_EVS
1093 0 : IF( mem != NULL )
1094 : {
1095 : /* Enforce stable LPC filter - parcorr[0] and parcorr[1] are not LPC coeffiecients */
1096 0 : IF( flag )
1097 : {
1098 0 : Copy32( mem, A, add( order, 1 ) );
1099 : }
1100 : ELSE /* If stable LPC filter, store into memories */
1101 : {
1102 0 : Copy32( A, mem, add( order, 1 ) );
1103 : }
1104 : }
1105 :
1106 :
1107 0 : return ( flag );
1108 : }
1109 :
1110 :
1111 : /*
1112 : * E_LPC_a_add_tilt
1113 : *
1114 : * Parameters:
1115 : * a I: LP filter coefficients (m+1 coeffs)
1116 : * ap O: modified LP filter coefficients (m+2 coeffs)
1117 : * gamma I: tilt factor
1118 : * m I: order of LP filter
1119 : *
1120 : * Function:
1121 : * Modified LP filter by adding 1st order pre-premphasis, Ap(z)=A(z).(1-gamma.z^(-1))
1122 : *
1123 : * Returns:
1124 : * void
1125 : */
1126 0 : void E_LPC_a_add_tilt( const Word16 *a /*Qa*/, Word16 *ap /*Qa*/, Word16 gamma /*Q15*/, Word16 m )
1127 : {
1128 : Word16 i;
1129 : Word32 Amax, Atmp[M + 2];
1130 : Word16 shift;
1131 :
1132 :
1133 0 : Amax = L_mult( 16384, a[0] );
1134 0 : FOR( i = 1; i <= m; i++ )
1135 : {
1136 0 : Atmp[i] = L_sub( L_mult( 16384, a[i] ), L_mult0( gamma, a[i - 1] ) );
1137 0 : move32();
1138 0 : Amax = L_max( Amax, L_abs( Atmp[i] ) );
1139 : }
1140 0 : Atmp[m + 1] = L_negate( L_mult0( gamma, a[m] ) );
1141 0 : move32();
1142 0 : Amax = L_max( Amax, L_abs( Atmp[add( m, 1 )] ) );
1143 0 : shift = norm_l( Amax );
1144 0 : ap[0] = shl( a[0], sub( shift, 1 ) );
1145 0 : move16();
1146 0 : FOR( i = 1; i <= m; i++ )
1147 : {
1148 0 : ap[i] = round_fx( L_shl( Atmp[i], shift ) );
1149 0 : move16();
1150 : }
1151 0 : ap[add( m, 1 )] = round_fx( L_shl( Atmp[add( m, 1 )], shift ) );
1152 0 : move16();
1153 0 : }
1154 :
1155 102799 : void E_LPC_int_lpc_tcx( const Word16 lsp_old[], /* input : LSPs from past frame Q15 */
1156 : const Word16 lsp_new[], /* input : LSPs from present frame Q15 */
1157 : Word16 a[] /* output: interpolated LP coefficients Q12 */
1158 : )
1159 : {
1160 : Word16 i, lsp[M];
1161 :
1162 :
1163 1747583 : FOR( i = 0; i < M; i++ )
1164 : {
1165 : /*lsp[i] = lsp_old[i]*0.125f + lsp_new[i]*0.875f;*/
1166 1644784 : lsp[i] = round_fx( L_mac( L_mult( lsp_old[i], 4096 ), lsp_new[i], 28672 ) );
1167 1644784 : move16();
1168 : }
1169 102799 : E_LPC_f_lsp_a_conversion( lsp, a, M );
1170 :
1171 :
1172 102799 : return;
1173 : }
1174 :
1175 14024 : static void lsp_reorder(
1176 : Word16 *lsp, /* (I/O): LSP vector (acos() domain) Q13*1.2732 */
1177 : Word16 min_dist, /* (I): minimum required distance Q13*1.2732 */
1178 : Word16 lpcorder /* (I): LPC order Q0 */
1179 : )
1180 : {
1181 : Word16 i;
1182 : Word16 lsp_min, lsp_max;
1183 :
1184 :
1185 : /* Verify the LSF ordering and minimum GAP */
1186 14024 : lsp_min = min_dist;
1187 14024 : move16();
1188 238408 : FOR( i = 0; i < lpcorder; ++i )
1189 : {
1190 224384 : lsp[i] = s_max( lsp[i], lsp_min );
1191 224384 : move16();
1192 224384 : lsp_min = add_sat( lsp[i], min_dist );
1193 : }
1194 :
1195 : /* Reverify the LSF ordering and minimum GAP in the reverse order (security) */
1196 14024 : lsp_max = sub( 32767, min_dist );
1197 :
1198 : /* If danger of unstable filter in case of resonance in HF */
1199 14024 : lpcorder = sub( lpcorder, 1 );
1200 14024 : IF( GT_16( lsp[lpcorder], lsp_max ) )
1201 : {
1202 : /* Reverify the minimum LSF gap in the reverse sense */
1203 0 : FOR( i = lpcorder; i >= 0; --i )
1204 : {
1205 0 : lsp[i] = s_min( lsp[i], lsp_max );
1206 0 : move16();
1207 0 : lsp_max = sub( lsp[i], min_dist );
1208 : }
1209 : }
1210 14024 : }
1211 :
1212 : /* Approximate unweighting */
1213 14024 : Word16 E_LPC_lsp_unweight(
1214 : /* const */ Word16 lsp_w[], /* (I): weighted xSP Q15 */
1215 : Word16 lsp_uw[], /* (O): unweighted xSP Q15 */
1216 : Word16 lsf_uw[], /* (O): unweighted LSF Q1*1.28 */
1217 : Word16 inv_gamma, /* (I): inverse weighting factor Q14 */
1218 : Word16 lpcorder /* (I): prediction order Q0 */
1219 : )
1220 : {
1221 : Word16 lsp_w_orig[M], lsp_w_diff[M], mean, step; /* Q13*1.2732 */
1222 14024 : const lsp_unw_triplet *unw_coeffs = NULL;
1223 : Word16 i;
1224 :
1225 14024 : step = 0; /* to avoid compilation warnings */
1226 :
1227 :
1228 14024 : assert( lpcorder == 16 );
1229 :
1230 : /* Table selection */
1231 14024 : IF( EQ_16( inv_gamma, GAMMA16k_INV ) )
1232 : {
1233 0 : unw_coeffs = p16_gamma0_94to1;
1234 0 : move16();
1235 : }
1236 14024 : ELSE IF( EQ_16( inv_gamma, GAMMA1_INV ) )
1237 : {
1238 14024 : unw_coeffs = p16_gamma0_92to1;
1239 14024 : move16();
1240 : }
1241 : ELSE
1242 : {
1243 0 : assert( 0 );
1244 : }
1245 :
1246 : /* step = M_PI/(float)(lpcorder+1); */
1247 14024 : step = 1927;
1248 14024 : move16();
1249 14024 : mean = 0;
1250 14024 : move16();
1251 :
1252 : /* Apply acos() and get mean removed version */
1253 238408 : FOR( i = 0; i < lpcorder; ++i )
1254 : {
1255 224384 : mean = add( mean, step );
1256 224384 : lsp_w_orig[i] = shl( xsp_to_xsf( lsp_w[i] ), 1 );
1257 224384 : move16();
1258 224384 : lsp_w_diff[i] = sub( lsp_w_orig[i], mean );
1259 224384 : move16();
1260 : }
1261 :
1262 : /* Approximate unweighting by 3-tap FIR */
1263 14024 : lsp_uw[0] = add( lsp_w_orig[0], round_fx( L_shl( L_mac0( L_mult0( unw_coeffs[0][1], lsp_w_diff[0] ), unw_coeffs[0][2], lsp_w_diff[1] ), 2 ) ) );
1264 14024 : move16();
1265 210360 : FOR( i = 1; i < lpcorder - 1; ++i )
1266 : {
1267 196336 : lsp_uw[i] = add( lsp_w_orig[i], round_fx( L_shl( L_mac0( L_mac0( L_mult0( unw_coeffs[i][0], lsp_w_diff[i - 1] ), unw_coeffs[i][1], lsp_w_diff[i] ), unw_coeffs[i][2], lsp_w_diff[i + 1] ), 2 ) ) );
1268 196336 : move16();
1269 : }
1270 14024 : lsp_uw[i] = add( lsp_w_orig[i], round_fx( L_shl( L_mac0( L_mult0( unw_coeffs[i][0], lsp_w_diff[i - 1] ), unw_coeffs[i][1], lsp_w_diff[i] ), 2 ) ) );
1271 14024 : move16();
1272 :
1273 : /* Reorder */
1274 14024 : lsp_reorder( lsp_uw, 256, lpcorder );
1275 :
1276 : /* Convert to LSF, apply cos() */
1277 238408 : FOR( i = 0; i < lpcorder; ++i )
1278 : {
1279 224384 : lsf_uw[i] = shr_r( lsp_uw[i], 1 );
1280 224384 : move16();
1281 224384 : lsp_uw[i] = xsf_to_xsp( lsf_uw[i] );
1282 224384 : move16();
1283 : }
1284 :
1285 14024 : return 0;
1286 : }
1287 :
1288 : /*
1289 : * E_LPC_schur_ivas
1290 : *
1291 : * Parameters:
1292 : * R I: Rh[M+1] Vector of autocorrelations (msb)
1293 : * reflCoeff O: rc[M] Reflection coefficients. Q15
1294 : * epsP O: error vector
1295 : *
1296 : * Function:
1297 : * Schur algorithm to compute
1298 : * the LPC parameters from the autocorrelations of speech.
1299 : *
1300 : * Returns:
1301 : * void
1302 : */
1303 0 : Word32 E_LPC_schur_ivas( Word32 r[] /*Qr*/, Word16 reflCoeff[] /*Q15*/, const Word16 m )
1304 : {
1305 : Word16 i, j, temp16, mMi, s;
1306 : Word32 g0[M], *g1, tmp32;
1307 0 : const Word32 min_epsP = 1; /* > 0.01f*2^27/2^30 */
1308 : Word32 tmp_epsP;
1309 :
1310 0 : s = getScaleFactor32( r, add( m, 1 ) );
1311 0 : IF( s != 0 )
1312 : {
1313 0 : scale_sig32( r, add( m, 1 ), s ); /* scale in-place */
1314 : }
1315 :
1316 0 : g1 = r;
1317 0 : Copy32( r + 1, g0, m );
1318 :
1319 : /* compute g0[0]/g1[0], where g0[0] < g1[0] */
1320 0 : temp16 = negate( divide3232( g0[0], g1[0] ) );
1321 0 : reflCoeff[0] = temp16;
1322 0 : move16();
1323 : // epsP[0] = r[0];
1324 0 : move32();
1325 :
1326 :
1327 0 : FOR( i = 0; i < m; i++ )
1328 : {
1329 : /* g1[0] = g0[0]*temp16 + g1[0]; */
1330 0 : tmp32 = Mpy_32_16_1( g0[0], temp16 );
1331 0 : g1[0] = L_add( g1[0], tmp32 );
1332 0 : move32();
1333 :
1334 0 : mMi = sub( m, i );
1335 0 : FOR( j = 1; j < mMi; j++ )
1336 : {
1337 : /* g0[j-1] = g0[j] + g1[j]*temp16;
1338 : g1[j] = g0[j]*temp16 + g1[j]; */
1339 0 : g0[j - 1] = L_add( g0[j], Mpy_32_16_1( g1[j], temp16 ) );
1340 0 : move32();
1341 0 : g1[j] = L_add( g1[j], Mpy_32_16_1( g0[j], temp16 ) );
1342 0 : move32();
1343 : }
1344 0 : temp16 = negate( divide3232( g0[0], g1[0] ) );
1345 0 : reflCoeff[i + 1] = temp16;
1346 0 : move16();
1347 :
1348 : /* Prediction errors */
1349 0 : tmp_epsP = L_shr( g1[0], s );
1350 0 : if ( tmp_epsP <= 0 )
1351 : {
1352 0 : tmp_epsP = min_epsP;
1353 0 : move32();
1354 : }
1355 : // epsP[i + 1] = tmp_epsP;
1356 0 : move32();
1357 : }
1358 :
1359 : /* epsP[i+1] = g0[0]*temp16 + g1[0]; */
1360 0 : tmp_epsP = L_add( g1[0], Mpy_32_16_1( g0[0], temp16 ) );
1361 0 : tmp_epsP = L_shr( tmp_epsP, s );
1362 0 : if ( tmp_epsP <= 0 )
1363 : {
1364 0 : tmp_epsP = min_epsP;
1365 0 : move32();
1366 : }
1367 :
1368 : /* prediction gain = divide3232(L_shr(epsP[0], PRED_GAIN_E), g1[0]); */
1369 :
1370 :
1371 0 : return g1[0];
1372 : }
1373 :
1374 : /*
1375 : * E_LPC_schur
1376 : *
1377 : * Parameters:
1378 : * R I: Rh[M+1] Vector of autocorrelations (msb)
1379 : * reflCoeff O: rc[M] Reflection coefficients. Q15
1380 : * epsP O: error vector
1381 : *
1382 : * Function:
1383 : * Schur algorithm to compute
1384 : * the LPC parameters from the autocorrelations of speech.
1385 : *
1386 : * Returns:
1387 : * void
1388 : */
1389 67177 : Word32 E_LPC_schur( Word32 r[] /*Qr*/, Word16 reflCoeff[] /*Q15*/, Word32 epsP[] /*Qr*/, const Word16 m )
1390 : {
1391 : Word16 i, j, temp16, mM1, mMi, s;
1392 : Word32 g0[M], *g1, tmp32;
1393 67177 : const Word32 min_epsP = 1; /* > 0.01f*2^27/2^30 */
1394 : Word32 tmp_epsP;
1395 :
1396 :
1397 67177 : mM1 = sub( m, 1 );
1398 :
1399 67177 : s = getScaleFactor32( r, add( m, 1 ) );
1400 67177 : IF( s != 0 )
1401 : {
1402 67155 : scale_sig32( r, add( m, 1 ), s ); /* scale in-place */
1403 : }
1404 :
1405 67177 : g1 = r;
1406 67177 : Copy32( r + 1, g0, m );
1407 :
1408 : /* compute g0[0]/g1[0], where g0[0] < g1[0] */
1409 67177 : temp16 = negate( divide3232( g0[0], g1[0] ) );
1410 67177 : reflCoeff[0] = temp16;
1411 67177 : move16();
1412 67177 : epsP[0] = r[0];
1413 67177 : move32();
1414 :
1415 :
1416 537416 : FOR( i = 0; i < mM1; i++ )
1417 : {
1418 : /* g1[0] = g0[0]*temp16 + g1[0]; */
1419 470239 : tmp32 = Mpy_32_16_1( g0[0], temp16 );
1420 470239 : g1[0] = L_add( g1[0], tmp32 );
1421 470239 : move32();
1422 :
1423 470239 : mMi = sub( m, i );
1424 2351195 : FOR( j = 1; j < mMi; j++ )
1425 : {
1426 : /* g0[j-1] = g0[j] + g1[j]*temp16;
1427 : g1[j] = g0[j]*temp16 + g1[j]; */
1428 1880956 : g0[j - 1] = L_add( g0[j], Mpy_32_16_1( g1[j], temp16 ) );
1429 1880956 : move32();
1430 1880956 : g1[j] = L_add( g1[j], Mpy_32_16_1( g0[j], temp16 ) );
1431 1880956 : move32();
1432 : }
1433 470239 : temp16 = negate( divide3232( g0[0], g1[0] ) );
1434 470239 : reflCoeff[i + 1] = temp16;
1435 470239 : move16();
1436 :
1437 : /* Prediction errors */
1438 470239 : tmp_epsP = L_shr( g1[0], s );
1439 470239 : if ( tmp_epsP <= 0 )
1440 : {
1441 0 : tmp_epsP = min_epsP;
1442 0 : move32();
1443 : }
1444 470239 : epsP[i + 1] = tmp_epsP;
1445 470239 : move32();
1446 : }
1447 :
1448 : /* epsP[i+1] = g0[0]*temp16 + g1[0]; */
1449 67177 : tmp_epsP = L_add( g1[0], Mpy_32_16_1( g0[0], temp16 ) );
1450 67177 : tmp_epsP = L_shr( tmp_epsP, s );
1451 67177 : if ( tmp_epsP <= 0 )
1452 : {
1453 0 : tmp_epsP = min_epsP;
1454 0 : move32();
1455 : }
1456 67177 : epsP[i + 1] = tmp_epsP;
1457 67177 : move32();
1458 :
1459 : /* prediction gain = divide3232(L_shr(epsP[0], PRED_GAIN_E), g1[0]); */
1460 :
1461 :
1462 67177 : return g1[0];
1463 : }
1464 :
1465 :
1466 : extern const PWord16 *w_a[7]; // Q15
1467 : extern const PWord16 w19N[127];
1468 : extern const PWord16 w18N[127];
1469 : extern void BASOP_getTables( const PWord16 **ptwiddle, const PWord16 **sin_twiddle, Word16 *psin_step, Word16 length );
1470 0 : static void spec2isf(
1471 : Word16 /*double*/ spec_r[], /* input spectrum real part (only left half + one zero)Q_spec*/
1472 : Word16 /*double*/ spec_i[], /* input spectrum imag part (only left half+right halt with zeros)Q_spec*/
1473 : Word16 /*short*/ speclen, /* length of spectrum (only left half)*/
1474 : Word16 /*double*/ lsf[],
1475 : /* locations of LSFs (buffer must be sufficiently long) */ /*15Q16*/
1476 : const Word16 /*double*/ old_lsf[] /* locations of LSFs (buffer must be sufficiently long) */ /*15Q16*/
1477 : )
1478 : {
1479 :
1480 : /*spec_r[] needs a 0 in the end!*/
1481 : Word16 s;
1482 : Word16 tmp, i;
1483 : Word16 specix, lsfix;
1484 :
1485 0 : specix = lsfix = 0;
1486 0 : move16();
1487 0 : move16();
1488 0 : s = spec_r[specix++];
1489 0 : move16();
1490 :
1491 0 : WHILE( LT_16( specix, speclen ) && LE_16( lsfix, 15 ) )
1492 : {
1493 0 : test();
1494 : /*check for next zero crossing*/
1495 : /*for (; s*spec_r[specix] >= 0; specix++);*/
1496 0 : WHILE( mult( s, spec_r[specix] ) >= 0 )
1497 0 : specix = add( specix, 1 );
1498 :
1499 0 : tmp = divide1616( spec_r[specix - 1], sub( spec_r[specix - 1], spec_r[specix] ) );
1500 : /*lsf[lsfix] = L_add(L_deposit_h(sub(specix,1)) , L_shl(L_deposit_l(tmp),1));*/ /*Q16*/
1501 0 : lsf[lsfix] = add( shl( sub( specix, 1 ), 7 ), shr( ( tmp ), 8 ) ); /*7Q8*/
1502 0 : move16();
1503 :
1504 0 : lsfix++;
1505 :
1506 : /*check for the next zero crossing*/
1507 : /*for (; s*spec_i[specix] >= 0; specix++);*/
1508 :
1509 0 : WHILE( mult( s, spec_i[specix] ) >= 0 )
1510 0 : specix = add( specix, 1 );
1511 :
1512 0 : tmp = divide1616( spec_i[specix - 1], sub( spec_i[specix - 1], spec_i[specix] ) );
1513 : /*lsf[lsfix] = L_add(L_deposit_h(sub(specix,1)) , L_shl(L_deposit_l(tmp),1));*/ /*Q16*/
1514 0 : lsf[lsfix] = add( shl( sub( specix, 1 ), 7 ), shr( ( tmp ), 8 ) ); /*7Q8*/
1515 0 : move16();
1516 :
1517 0 : lsfix++;
1518 :
1519 0 : spec_r[speclen] = s;
1520 0 : move16();
1521 0 : spec_i[speclen] = s;
1522 0 : move16();
1523 :
1524 0 : s = negate( s );
1525 : }
1526 :
1527 0 : IF( LT_16( lsfix, 16 ) )
1528 : {
1529 0 : FOR( i = 0; i < 16; i++ )
1530 : {
1531 0 : lsf[i] = old_lsf[i];
1532 0 : move16();
1533 : }
1534 : }
1535 :
1536 0 : return;
1537 : }
1538 :
1539 0 : void E_LPC_a_lsf_isf_conversion( Word16 *lpcCoeffs /*Qx*/, Word16 *lsf /*15Q16*/, const Word16 *old_lsf /*15Q16*/, Word16 lpcOrder, Word8 lpcRep /*Q0*/ )
1540 : {
1541 : Word32 RealFFT[128];
1542 : Word32 ImagFFT[128];
1543 : Word16 RealOut[130];
1544 : Word16 ImagOut[130];
1545 : Word32 *ptrReal;
1546 : Word32 *ptrImag;
1547 : Word16 n, i, j, step, scale;
1548 : const PWord16 *ptwiddle, *pwn17, *pwn17i;
1549 : PWord16 *pwn15, *pwn15i, tmpw15;
1550 0 : Word16 N = 256;
1551 : Word16 s[4];
1552 : Word32 L_tmp, L_tmp1, L_tmp3;
1553 : Word16 lpc[19];
1554 0 : move16();
1555 :
1556 : #ifndef ISSUE_1836_replace_overflow_libcom
1557 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1558 : Flag Overflow = 0;
1559 : move32();
1560 : #endif
1561 : #endif
1562 :
1563 : /* half length FFT */
1564 0 : scale = add( norm_s( lpcCoeffs[0] ), 1 ) + 5;
1565 0 : move16();
1566 :
1567 : /*s = [sum(a) ((-1).^(1:length(a)))*a];*/
1568 0 : L_tmp = L_deposit_h( 0 );
1569 0 : FOR( j = 0; j <= lpcOrder; j++ )
1570 : {
1571 0 : L_tmp = L_mac( L_tmp, lpcCoeffs[j], 0x800 );
1572 : }
1573 : /*s[1] = round_fx(L_tmp); move16();*/
1574 :
1575 0 : L_tmp1 = L_deposit_h( 0 );
1576 0 : FOR( j = 0; j < lpcOrder / 2; j++ )
1577 : {
1578 0 : L_tmp1 = L_msu( L_tmp1, lpcCoeffs[2 * j], 0x800 );
1579 0 : L_tmp1 = L_mac( L_tmp1, lpcCoeffs[2 * j + 1], 0x800 );
1580 : }
1581 0 : L_tmp1 = L_msu( L_tmp1, lpcCoeffs[2 * j], 0x800 );
1582 : /*s[2] = round_fx(L_tmp1); move16();*/
1583 :
1584 :
1585 0 : L_tmp3 = L_add( L_tmp1, L_tmp );
1586 0 : IF( L_tmp3 != 0 )
1587 : {
1588 0 : s[1] = BASOP_Util_Divide3232_Scale( L_sub( L_tmp1, L_tmp ), L_tmp3, &step );
1589 0 : move16();
1590 : /*s[1] = BASOP_Util_Divide1616_Scale(sub(s[2],s[1]),add(s[2],s[1]), &step); move16();*/
1591 : BASOP_SATURATE_WARNING_OFF_EVS
1592 0 : s[0] = negate( shr( -32768, step + 1 ) );
1593 0 : move16();
1594 0 : s[2] = negate( shr( -32768, step + 1 ) );
1595 0 : move16();
1596 : BASOP_SATURATE_WARNING_ON_EVS
1597 : }
1598 : ELSE
1599 : {
1600 0 : s[1] = 16384 / 4;
1601 0 : move16();
1602 0 : s[0] = 0;
1603 0 : move16();
1604 0 : s[2] = 0;
1605 0 : move16();
1606 : }
1607 0 : s[0] = shr( s[0], 1 );
1608 0 : move16();
1609 0 : s[1] = shr( s[1], 1 );
1610 0 : move16();
1611 0 : s[2] = shr( s[2], 1 );
1612 0 : move16();
1613 0 : lpc[0] = mult_r( lpcCoeffs[0], s[0] );
1614 0 : move16();
1615 0 : L_tmp = L_mult( s[0], lpcCoeffs[1] );
1616 0 : lpc[1] = mac_r( L_tmp, lpcCoeffs[1 - 1], s[1] );
1617 0 : move16();
1618 :
1619 0 : FOR( n = 2; n < 17; n++ )
1620 : {
1621 0 : L_tmp = L_mult( s[0], lpcCoeffs[n] );
1622 0 : L_tmp = L_mac( L_tmp, lpcCoeffs[n - 1], s[1] );
1623 0 : lpc[n] = mac_r( L_tmp, lpcCoeffs[n - 2], s[2] );
1624 0 : move16();
1625 : }
1626 0 : lpc[18] = mult_r( lpcCoeffs[16], s[0] );
1627 0 : move16();
1628 0 : L_tmp = L_mult( s[0], lpcCoeffs[15] );
1629 0 : lpc[17] = mac_r( L_tmp, lpcCoeffs[16], s[1] );
1630 0 : move16();
1631 :
1632 0 : scale = sub( getScaleFactor16( lpc, 19 ), SCALEFACTOR16_5 );
1633 :
1634 0 : ptrReal = RealFFT;
1635 0 : ptrImag = ImagFFT;
1636 :
1637 0 : FOR( j = 0; j < 9; j++ )
1638 : {
1639 0 : ptrReal[j * 8] = L_shl( L_deposit_h( lpc[2 * j] ), scale );
1640 0 : move32();
1641 0 : ptrImag[j * 8] = L_shl( L_deposit_h( lpc[2 * j + 1] ), scale );
1642 0 : move32();
1643 : }
1644 0 : ptrReal[j * 8] = L_shl( L_deposit_h( lpc[2 * j] ), scale );
1645 0 : move32();
1646 0 : ptrImag[j * 8] = 0;
1647 0 : move16();
1648 0 : j++;
1649 :
1650 0 : FOR( ; j < 16; j++ )
1651 : {
1652 0 : ptrReal[j * 8] = L_deposit_h( 0 );
1653 0 : move32();
1654 0 : ptrImag[j * 8] = L_deposit_h( 0 );
1655 0 : move32();
1656 : }
1657 :
1658 0 : fft16( ptrReal, ptrImag, 8, 0 );
1659 :
1660 0 : ptrReal++;
1661 0 : ptrImag++;
1662 :
1663 0 : FOR( i = 1; i < 8; i++ )
1664 : {
1665 0 : ptwiddle = w_a[i - 1];
1666 :
1667 0 : ptrReal[0] = L_shl( L_deposit_h( lpc[0] ), scale );
1668 0 : move32();
1669 0 : ptrImag[0] = L_shl( L_deposit_h( lpc[1] ), scale );
1670 0 : move32();
1671 :
1672 0 : FOR( j = 1; j < 9; j++ )
1673 : {
1674 0 : ptrReal[j * 8] = L_shl( L_msu( L_mult( lpc[2 * j], ptwiddle->v.re ), lpc[2 * j + 1], ptwiddle->v.im ), scale );
1675 0 : move32();
1676 0 : ptrImag[j * 8] = L_shl( L_mac( L_mult( lpc[2 * j + 1], ptwiddle->v.re ), lpc[2 * j], ptwiddle->v.im ), scale );
1677 0 : move32();
1678 0 : ptwiddle++;
1679 : }
1680 :
1681 0 : ptrReal[j * 8] = L_shl( L_mac( 0, lpc[2 * j], ptwiddle->v.re ), scale );
1682 0 : move32();
1683 0 : ptrImag[j * 8] = L_shl( L_mac( 0, lpc[2 * j], ptwiddle->v.im ), scale );
1684 0 : move32();
1685 0 : ptwiddle++;
1686 0 : j++;
1687 0 : FOR( ; j < 16; j++ )
1688 : {
1689 0 : ptrReal[j * 8] = L_deposit_h( 0 );
1690 0 : move32();
1691 0 : ptrImag[j * 8] = L_deposit_h( 0 );
1692 0 : move32();
1693 0 : ptwiddle++;
1694 : }
1695 :
1696 0 : fft16( ptrReal, ptrImag, 8, 0 );
1697 :
1698 0 : ptrReal++;
1699 0 : ptrImag++;
1700 : }
1701 :
1702 : /* pre-twiddle */
1703 0 : BASOP_getTables( NULL, &ptwiddle, &step, 128 );
1704 0 : IF( lpcRep != 0 )
1705 : {
1706 0 : pwn17i = &w19N[126];
1707 0 : pwn17 = w19N;
1708 : }
1709 : ELSE
1710 : {
1711 0 : pwn17i = &w18N[126];
1712 0 : pwn17 = w18N;
1713 : }
1714 :
1715 0 : pwn15 = &tmpw15;
1716 0 : pwn15i = &tmpw15;
1717 :
1718 0 : RealOut[0] = round_fx( 2 * L_add( RealFFT[0], ImagFFT[0] ) );
1719 0 : move16();
1720 0 : ImagOut[0] = 0;
1721 0 : move16();
1722 :
1723 0 : RealOut[128] = 0;
1724 0 : move16();
1725 0 : ImagOut[128] = round_fx( L_sub( L_add( RealFFT[0], RealFFT[0] ), L_add( ImagFFT[0], ImagFFT[0] ) ) );
1726 0 : move16();
1727 :
1728 0 : ptwiddle += 8;
1729 0 : FOR( i = 1; i <= N / 2 / 4; i++ )
1730 : {
1731 0 : Word16 ReAr = extract_h( L_add( RealFFT[i], RealFFT[N / 2 - i] ) );
1732 0 : Word16 ReBr = extract_h( L_sub( RealFFT[N / 2 - i], RealFFT[i] ) );
1733 0 : Word16 ImAr = extract_h( L_sub( ImagFFT[i], ImagFFT[N / 2 - i] ) );
1734 0 : Word16 ImBr = extract_h( L_add( ImagFFT[i], ImagFFT[N / 2 - i] ) );
1735 : BASOP_SATURATE_WARNING_OFF_EVS
1736 : #ifdef ISSUE_1836_replace_overflow_libcom
1737 0 : tmpw15.v.re = mac_r_sat( L_mult( ptwiddle->v.re, pwn17->v.re ), ptwiddle->v.im, pwn17->v.im );
1738 0 : move16();
1739 0 : tmpw15.v.im = msu_r_sat( L_mult( ptwiddle->v.re, pwn17->v.im ), ptwiddle->v.im, pwn17->v.re );
1740 0 : move16();
1741 : BASOP_SATURATE_WARNING_ON_EVS
1742 0 : RealOut[i] = mac_r( L_msu( L_msu( L_mult( ReAr, pwn17->v.re ), ImAr, pwn17->v.im ), ReBr, pwn15->v.im ), ImBr, pwn15->v.re );
1743 0 : move16();
1744 0 : ImagOut[i] = mac_r( L_mac( L_mac( L_mult( ReAr, pwn17->v.im ), ImAr, pwn17->v.re ), ReBr, pwn15->v.re ), ImBr, pwn15->v.im );
1745 0 : move16();
1746 : BASOP_SATURATE_WARNING_OFF_EVS
1747 0 : tmpw15.v.re = msu_r_sat( L_mult( ptwiddle->v.im, pwn17i->v.im ), ptwiddle->v.re, pwn17i->v.re );
1748 0 : move16();
1749 0 : tmpw15.v.im = mac_r_sat( L_mult( ptwiddle->v.re, pwn17i->v.im ), ptwiddle->v.im, pwn17i->v.re );
1750 0 : move16();
1751 : #else
1752 : tmpw15.v.re = mac_ro( L_mult( ptwiddle->v.re, pwn17->v.re ), ptwiddle->v.im, pwn17->v.im, &Overflow );
1753 : move16();
1754 : tmpw15.v.im = msu_ro( L_mult( ptwiddle->v.re, pwn17->v.im ), ptwiddle->v.im, pwn17->v.re, &Overflow );
1755 : move16();
1756 : BASOP_SATURATE_WARNING_ON_EVS
1757 : RealOut[i] = mac_r( L_msu( L_msu( L_mult( ReAr, pwn17->v.re ), ImAr, pwn17->v.im ), ReBr, pwn15->v.im ), ImBr, pwn15->v.re );
1758 : move16();
1759 : ImagOut[i] = mac_r( L_mac( L_mac( L_mult( ReAr, pwn17->v.im ), ImAr, pwn17->v.re ), ReBr, pwn15->v.re ), ImBr, pwn15->v.im );
1760 : move16();
1761 : BASOP_SATURATE_WARNING_OFF_EVS
1762 : tmpw15.v.re = msu_ro( L_mult( ptwiddle->v.im, pwn17i->v.im ), ptwiddle->v.re, pwn17i->v.re, &Overflow );
1763 : move16();
1764 : tmpw15.v.im = mac_ro( L_mult( ptwiddle->v.re, pwn17i->v.im ), ptwiddle->v.im, pwn17i->v.re, &Overflow );
1765 : move16();
1766 : #endif
1767 : BASOP_SATURATE_WARNING_ON_EVS
1768 0 : RealOut[N / 2 - i] = msu_r( L_mac( L_mac( L_mult( ReAr, pwn17i->v.re ), ImAr, pwn17i->v.im ), ImBr, pwn15i->v.re ), ReBr, pwn15i->v.im );
1769 0 : move16();
1770 0 : ImagOut[N / 2 - i] = msu_r( L_msu( L_msu( L_mult( ReAr, pwn17i->v.im ), ImAr, pwn17i->v.re ), ReBr, pwn15i->v.re ), ImBr, pwn15i->v.im );
1771 0 : move16();
1772 :
1773 0 : ptwiddle += 8;
1774 0 : pwn17++;
1775 0 : pwn17i--;
1776 : }
1777 :
1778 0 : ptwiddle -= 16;
1779 : /*change real with imaginary for ptwiddle*/
1780 0 : FOR( ; i < N / 2 / 2; i++ )
1781 : {
1782 0 : Word16 ReAr = extract_h( L_add( RealFFT[i], RealFFT[N / 2 - i] ) );
1783 0 : Word16 ReBr = extract_h( L_sub( RealFFT[N / 2 - i], RealFFT[i] ) );
1784 0 : Word16 ImAr = extract_h( L_sub( ImagFFT[i], ImagFFT[N / 2 - i] ) );
1785 0 : Word16 ImBr = extract_h( L_add( ImagFFT[i], ImagFFT[N / 2 - i] ) );
1786 : BASOP_SATURATE_WARNING_OFF_EVS
1787 : #ifdef ISSUE_1836_replace_overflow_libcom
1788 0 : tmpw15.v.re = mac_r_sat( L_mult( ptwiddle->v.im, pwn17->v.re ), ptwiddle->v.re, pwn17->v.im );
1789 0 : move16();
1790 0 : tmpw15.v.im = msu_r_sat( L_mult( ptwiddle->v.im, pwn17->v.im ), ptwiddle->v.re, pwn17->v.re );
1791 0 : move16();
1792 : BASOP_SATURATE_WARNING_ON_EVS
1793 0 : RealOut[i] = mac_r( L_msu( L_msu( L_mult( ReAr, pwn17->v.re ), ImAr, pwn17->v.im ), ReBr, pwn15->v.im ), ImBr, pwn15->v.re );
1794 0 : move16();
1795 0 : ImagOut[i] = mac_r( L_mac( L_mac( L_mult( ReAr, pwn17->v.im ), ImAr, pwn17->v.re ), ReBr, pwn15->v.re ), ImBr, pwn15->v.im );
1796 0 : move16();
1797 : BASOP_SATURATE_WARNING_OFF_EVS
1798 0 : tmpw15.v.re = msu_r_sat( L_mult( ptwiddle->v.re, pwn17i->v.im ), ptwiddle->v.im, pwn17i->v.re );
1799 0 : move16();
1800 0 : tmpw15.v.im = mac_r_sat( L_mult( ptwiddle->v.im, pwn17i->v.im ), ptwiddle->v.re, pwn17i->v.re );
1801 0 : move16();
1802 : #else
1803 : tmpw15.v.re = mac_ro( L_mult( ptwiddle->v.im, pwn17->v.re ), ptwiddle->v.re, pwn17->v.im, &Overflow );
1804 : move16();
1805 : tmpw15.v.im = msu_ro( L_mult( ptwiddle->v.im, pwn17->v.im ), ptwiddle->v.re, pwn17->v.re, &Overflow );
1806 : move16();
1807 : BASOP_SATURATE_WARNING_ON_EVS
1808 : RealOut[i] = mac_r( L_msu( L_msu( L_mult( ReAr, pwn17->v.re ), ImAr, pwn17->v.im ), ReBr, pwn15->v.im ), ImBr, pwn15->v.re );
1809 : move16();
1810 : ImagOut[i] = mac_r( L_mac( L_mac( L_mult( ReAr, pwn17->v.im ), ImAr, pwn17->v.re ), ReBr, pwn15->v.re ), ImBr, pwn15->v.im );
1811 : move16();
1812 : BASOP_SATURATE_WARNING_OFF_EVS
1813 : tmpw15.v.re = msu_ro( L_mult( ptwiddle->v.re, pwn17i->v.im ), ptwiddle->v.im, pwn17i->v.re, &Overflow );
1814 : move16();
1815 : tmpw15.v.im = mac_ro( L_mult( ptwiddle->v.im, pwn17i->v.im ), ptwiddle->v.re, pwn17i->v.re, &Overflow );
1816 : move16();
1817 : #endif
1818 : BASOP_SATURATE_WARNING_ON_EVS
1819 0 : RealOut[N / 2 - i] = msu_r( L_mac( L_mac( L_mult( ReAr, pwn17i->v.re ), ImAr, pwn17i->v.im ), ImBr, pwn15i->v.re ), ReBr, pwn15i->v.im );
1820 0 : move16();
1821 0 : ImagOut[N / 2 - i] = msu_r( L_msu( L_msu( L_mult( ReAr, pwn17i->v.im ), ImAr, pwn17i->v.re ), ReBr, pwn15i->v.re ), ImBr, pwn15i->v.im );
1822 0 : move16();
1823 :
1824 0 : ptwiddle -= 8;
1825 0 : pwn17++;
1826 0 : pwn17i--;
1827 : }
1828 0 : ptwiddle += 0;
1829 : {
1830 0 : Word16 ReAr = extract_h( L_add( RealFFT[i], RealFFT[N / 2 - i] ) );
1831 0 : Word16 ReBr = extract_h( L_sub( RealFFT[N / 2 - i], RealFFT[i] ) );
1832 0 : Word16 ImAr = extract_h( L_sub( ImagFFT[i], ImagFFT[N / 2 - i] ) );
1833 0 : Word16 ImBr = extract_h( ( L_negate( L_add( ImagFFT[i], ImagFFT[N / 2 - i] ) ) ) );
1834 : BASOP_SATURATE_WARNING_OFF_EVS
1835 0 : tmpw15.v.re = mac_r_sat( L_mult( ptwiddle->v.im, pwn17->v.re ), ptwiddle->v.re, pwn17->v.im );
1836 0 : move16();
1837 0 : tmpw15.v.im = msu_r_sat( L_mult( ptwiddle->v.im, pwn17->v.im ), ptwiddle->v.re, pwn17->v.re );
1838 0 : move16();
1839 : BASOP_SATURATE_WARNING_ON_EVS
1840 0 : RealOut[i] = msu_r( L_msu( L_msu( L_mult( ReAr, pwn17->v.re ), ImAr, pwn17->v.im ), ReBr, pwn15->v.im ), ImBr, pwn15->v.re );
1841 0 : move16();
1842 0 : ImagOut[i] = msu_r( L_mac( L_mac( L_mult( ReAr, pwn17->v.im ), ImAr, pwn17->v.re ), ReBr, pwn15->v.re ), ImBr, pwn15->v.im );
1843 0 : move16();
1844 : }
1845 :
1846 0 : spec2isf( RealOut, ImagOut, 128, lsf, old_lsf );
1847 0 : IF( lpcRep == 0 )
1848 : {
1849 0 : lsf[lpcOrder - 1] = shl( lpcCoeffs[lpcOrder], add( norm_s( lpcCoeffs[0] ), 1 ) );
1850 0 : move16(); /* From Qx to Q15 with saturation */
1851 0 : lsf[lpcOrder - 1] = xsp_to_xsf( lsf[lpcOrder - 1] );
1852 0 : move16();
1853 0 : lsf[lpcOrder - 1] = shr( lsf[lpcOrder - 1], 1 );
1854 0 : move16();
1855 : }
1856 0 : }
1857 :
1858 :
1859 1320 : Word16 lev_dur_fx(
1860 : Word32 *a_fx, /* o : LP coefficients (a[0] = 1.0) Q(q_a)*/
1861 : const Word32 *r_fx, /* i : vector of autocorrelations Q(q_r)*/
1862 : const Word16 m, /* i : order of LP filter */
1863 : Word32 epsP[], /* o : prediction error energy Q(q_r)*/
1864 : Word16 q_a,
1865 : Word16 q_r )
1866 : {
1867 : Word16 i, j, l;
1868 : Word16 buf_fx[TCXLTP_LTP_ORDER];
1869 : Word16 *rc_fx; /* reflection coefficients 0,...,m-1 */
1870 : Word32 at;
1871 : Word32 s, err;
1872 1320 : Word16 flag = 0, tmp16;
1873 1320 : move16();
1874 :
1875 1320 : rc_fx = &buf_fx[0];
1876 1320 : rc_fx[0] = divide3232( L_negate( r_fx[1] ), r_fx[0] ); // Q(31)
1877 1320 : move16();
1878 1320 : a_fx[0] = L_shl( 1, q_a );
1879 1320 : move32();
1880 1320 : a_fx[1] = L_shl( rc_fx[0], sub( q_a, 15 ) );
1881 1320 : move32();
1882 1320 : err = L_add( r_fx[0], Mpy_32_16_1( r_fx[1], rc_fx[0] ) ); // Q(q_r)
1883 1320 : IF( epsP != NULL )
1884 : {
1885 0 : epsP[0] = r_fx[0];
1886 0 : move32();
1887 0 : epsP[1] = err;
1888 0 : move32();
1889 : }
1890 :
1891 21120 : FOR( i = 2; i <= m; i++ )
1892 : {
1893 19800 : s = 0; // Q(q_a + q_r - 31)
1894 19800 : move32();
1895 198000 : FOR( j = 0; j < i; j++ )
1896 : {
1897 178200 : s = L_add( s, Mpy_32_32( r_fx[i - j], a_fx[j] ) ); // Q(q_a + q_r - 31)
1898 : }
1899 :
1900 19800 : rc_fx[i - 1] = divide3232( L_negate( s ), L_shr( err, sub( 31, q_a ) ) ); // Q15
1901 19800 : move16();
1902 :
1903 19800 : if ( GT_16( abs_s( rc_fx[i - 1] ), 32749 ) ) // 32749 = 0.99945 in Q15
1904 : {
1905 0 : flag = 1; /* Test for unstable filter. If unstable keep old A(z) */
1906 0 : move16();
1907 : }
1908 :
1909 19800 : tmp16 = shr( i, 1 );
1910 104280 : FOR( j = 1; j <= tmp16; j++ )
1911 : {
1912 84480 : l = sub( i, j );
1913 84480 : at = L_add( a_fx[j], Mpy_32_16_1( a_fx[l], rc_fx[i - 1] ) ); // Q(q_a)
1914 84480 : a_fx[l] = L_add( a_fx[l], Mpy_32_16_1( a_fx[j], rc_fx[i - 1] ) ); // Q(q_a)
1915 84480 : move32();
1916 84480 : a_fx[j] = at;
1917 84480 : move32();
1918 : }
1919 :
1920 19800 : a_fx[i] = L_shl( rc_fx[i - 1], sub( q_a, 15 ) ); // Q(q_a)
1921 19800 : move32();
1922 :
1923 19800 : err = L_add( err, L_shl( Mpy_32_16_1( s, rc_fx[i - 1] ), sub( 31, q_a ) ) ); // q_err - q_s
1924 19800 : IF( err <= 0 )
1925 : {
1926 0 : err = L_shr( 327, sub( 31, q_r ) ); // 327 = 0.01 in Q15
1927 : }
1928 :
1929 19800 : if ( epsP != NULL )
1930 : {
1931 0 : epsP[i] = err;
1932 0 : move32();
1933 : }
1934 : }
1935 :
1936 1320 : return ( flag );
1937 : }
|