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 2955066 : 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 2955066 : 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 2955066 : ELSE IF( EQ_16( sym_flag, 1 ) )
87 : {
88 : /* symmetric window of even length */
89 68035557 : FOR( i = 0; i < len / 2; i++ )
90 : {
91 67678030 : y[i] = mult_r( x[i], wind[i] );
92 67678030 : move16();
93 : }
94 68035557 : FOR( ; i < len; i++ )
95 : {
96 67678030 : y[i] = mult_r( x[i], wind[len - i - 1] );
97 67678030 : move16();
98 : }
99 : }
100 : ELSE /* assymetric window */
101 : {
102 861213859 : FOR( i = 0; i < len; i++ )
103 : {
104 858616320 : y[i] = mult_r( x[i], wind[i] );
105 858616320 : move16();
106 : }
107 : }
108 :
109 :
110 : /* calculate energy of signal */
111 2955066 : L_sum = L_deposit_h( 16 ); /* sqrt(256), avoid overflow after rounding */
112 499941256 : FOR( i = 0; i < len; i += 2 )
113 : {
114 496986190 : L_tmp = L_mult0( y[i], y[i] );
115 496986190 : L_tmp = L_and( L_tmp, ~( 128 - 1 ) );
116 496986190 : L_tmp = L_mac0( L_tmp, y[i + 1], y[i + 1] );
117 496986190 : L_tmp = L_shr( L_tmp, 7 );
118 496986190 : L_sum = L_add( L_sum, L_tmp );
119 : }
120 :
121 : /* scale signal to avoid overflow in autocorrelation */
122 2955066 : norm = norm_l( L_sum );
123 2955066 : shift = sub( 4, shr( norm, 1 ) );
124 :
125 2955066 : IF( shift > 0 )
126 : {
127 241888 : fact = lshr( -32768, shift );
128 95005888 : FOR( i = 0; i < len; i++ )
129 : {
130 94764000 : y[i] = mult_r( y[i], fact );
131 94764000 : move16();
132 : }
133 : }
134 : ELSE
135 : {
136 2713178 : shift = 0;
137 2713178 : move16();
138 : }
139 :
140 : /* Compute and normalize r[0] */
141 2955066 : L_sum = L_mac( 1, y[0], y[0] );
142 993972380 : FOR( i = 1; i < len; i++ )
143 : {
144 991017314 : L_sum = L_mac( L_sum, y[i], y[i] );
145 : }
146 2955066 : norm = norm_l( L_sum );
147 2955066 : L_sum = L_shl( L_sum, norm );
148 2955066 : 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 46990057 : FOR( i = 1; i <= m; i++ )
152 : {
153 44034991 : L_sum = L_mult( y[0], y[i] );
154 14427051369 : FOR( j = 1; j < len - i; j++ )
155 : {
156 14383016378 : L_sum = L_mac( L_sum, y[j], y[j + i] );
157 : }
158 :
159 44034991 : L_sum = L_shl( L_sum, norm );
160 44034991 : L_Extract( L_sum, &r_h[i], &r_l[i] ); /* Put in DPF format (see oper_32b) */
161 : }
162 :
163 2955066 : *Q_r = sub( norm, shl( shift, 1 ) );
164 2955066 : move16();
165 2955066 : }
166 :
167 15669 : 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 15669 : 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 15669 : 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 5029749 : FOR( i = 0; i < len; i++ )
210 : {
211 5014080 : y[i] = mult_r( x[i], wind[i] ); // Qx
212 5014080 : move16();
213 : }
214 : }
215 :
216 : /* calculate energy of signal */
217 : /* Compute and normalize r[0] */
218 15669 : W_sum = W_mult0_16_16( y[0], y[0] );
219 5014080 : FOR( i = 1; i < len; i++ )
220 : {
221 4998411 : 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 15669 : W_temp = W_shl( 1000, shl( Qx, 1 ) ); // 2*Qx
228 15669 : IF( LE_64( W_sum, W_temp ) && no_thr == 0 )
229 : {
230 35 : W_sum = W_temp; // 1000.0f in 2*Qx
231 : }
232 :
233 15669 : norm = W_norm( W_sum );
234 15669 : W_sum = W_shl( W_sum, norm ); // 2*Qx+norm
235 :
236 15669 : *Q_r = add( shl( Qx, 1 ), sub( norm, 32 ) ); // 2*Qx+norm-32
237 15669 : move16();
238 :
239 15669 : 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 172359 : FOR( i = 1; i <= m; i++ )
243 : {
244 156690 : W_sum = W_mult0_16_16( y[0], y[i] );
245 49279005 : FOR( j = 1; j < len - i; j++ )
246 : {
247 49122315 : W_sum = W_mac0_16_16( W_sum, y[j], y[j + i] );
248 : }
249 :
250 156690 : W_sum = W_shl( W_sum, norm ); // 2*Qx+norm-32
251 156690 : 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 15669 : return;
255 : }
256 :
257 1263 : 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 1263 : 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 1263 : 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 171599 : FOR( i = 0; i < len; i++ )
300 : {
301 170336 : y[i] = mult_r( x[i], wind[i] ); // Q(x)
302 170336 : move16();
303 : }
304 : }
305 :
306 :
307 : /* calculate energy of signal */
308 1263 : L_sum = L_deposit_h( 16 ); /* sqrt(256), avoid overflow after rounding */
309 86431 : FOR( i = 0; i < len; i += 2 )
310 : {
311 85168 : L_tmp = L_mult0( y[i], y[i] ); // 2*Q(x)
312 85168 : L_tmp = L_and( L_tmp, ~( 128 - 1 ) );
313 85168 : L_tmp = L_mac0( L_tmp, y[i + 1], y[i + 1] ); // 2*Q(x)
314 85168 : L_tmp = L_shr( L_tmp, 7 );
315 85168 : L_sum = L_add( L_sum, L_tmp );
316 : }
317 :
318 : /* scale signal to avoid overflow in autocorrelation */
319 1263 : norm = norm_l( L_sum );
320 1263 : shift = sub( 4, shr( norm, 1 ) );
321 :
322 1263 : IF( shift > 0 )
323 : {
324 0 : fact = lshr( -32768, shift );
325 0 : FOR( i = 0; i < len; i++ )
326 : {
327 0 : y[i] = mult_r( y[i], fact ); // Q(x)
328 0 : move16();
329 : }
330 : }
331 : ELSE
332 : {
333 1263 : shift = 0;
334 1263 : move16();
335 : }
336 :
337 : /* Compute and normalize r[0] */
338 1263 : L_sum = L_mac( 1, y[0], y[0] ); // 2*Q(x)
339 170336 : FOR( i = 1; i < len; i++ )
340 : {
341 169073 : L_sum = L_mac( L_sum, y[i], y[i] ); // 2*Q(x)
342 : }
343 1263 : norm = norm_l( L_sum );
344 1263 : L_sum = L_shl( L_sum, norm );
345 1263 : r[0] = L_sum;
346 1263 : move32();
347 :
348 : /* Compute r[1] to r[m] */
349 21471 : FOR( i = 1; i <= m; i++ )
350 : {
351 20208 : L_sum = L_mult( y[0], y[i] ); // 2*Q(x)+1
352 20208 : tmp16 = sub( len, i );
353 2553608 : FOR( j = 1; j < tmp16; j++ )
354 : {
355 2533400 : L_sum = L_mac( L_sum, y[j], y[j + i] ); // 2*Q(x)+1
356 : }
357 :
358 20208 : L_sum = L_shl( L_sum, norm ); // 2*Q(x)+1+norm
359 20208 : r[i] = L_sum;
360 20208 : move32();
361 : }
362 :
363 1263 : *Q_r = sub( norm, shl( shift, 1 ) );
364 1263 : move16();
365 1263 : }
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 48319265 : 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 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
413 48319265 : Flag Overflow = 0;
414 : #endif
415 :
416 : /* First approximation: 1 / L_denom = 1/denom_hi */
417 :
418 48319265 : approx = div_s( (Word16) 0x3fff, denom_hi );
419 :
420 : /* 1/L_denom = approx * (2.0 - L_denom * approx) */
421 :
422 48319265 : L_32 = Msu_32_16( (Word32) 0x7fffffffL, denom_hi, denom_lo, approx );
423 :
424 48319265 : L_32 = Mpy_32_16_1( L_32, approx );
425 :
426 : /* L_num * (1/L_denom) */
427 :
428 48319265 : L_32 = Mpy_32_32( L_num, L_32 );
429 :
430 48319265 : L_32 = L_shl_o( L_32, 2, &Overflow );
431 :
432 48319265 : return ( L_32 );
433 : }
434 :
435 : /*
436 : * E_LPC_lev_dur
437 : *
438 : * Parameters:
439 : * Rh I: Rh[m+1] Vector of autocorrelations (msb)
440 : * Rl I: Rl[m+1] Vector of autocorrelations (lsb)
441 : * 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]))
442 : * epsP O: error vector, msb
443 : * order I: LPC order Q0
444 : *
445 : * Function:
446 : * Levinson-Durbin algorithm to compute
447 : * the LPC parameters from the autocorrelations of speech.
448 : *
449 : * Returns:
450 : * void
451 : */
452 3254353 : 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*/ )
453 : {
454 3254353 : return ( E_LPC_lev_dur_stab( Rh, Rl, A, epsP, order, mem, 32750 ) ); /* 0.99945 in Q15 */
455 : }
456 :
457 3254353 : 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*/ )
458 : {
459 : Word16 i, j, k;
460 : Word16 hi, lo;
461 : Word16 Kh, Kl; /* reflection coefficient; hi and lo */
462 : Word16 alp_h, alp_l, alp_exp; /* Prediction gain; hi lo and exponent */
463 : Word32 t0, t1, t2; /* temporary variables */
464 : Word16 flag;
465 : Word16 Ah[TCXLTP_LTP_ORDER + 1], Al[TCXLTP_LTP_ORDER + 1]; /* LPC coef. in double prec. */
466 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
467 3254353 : Flag Overflow = 0;
468 : #endif
469 :
470 :
471 : BASOP_SATURATE_WARNING_OFF_EVS
472 3254353 : if ( epsP != NULL )
473 : {
474 3062779 : epsP[0] = L_Comp( Rh[0], Rl[0] );
475 3062779 : move32();
476 : }
477 :
478 3254353 : flag = 0;
479 3254353 : move16();
480 :
481 : /* K = A[1] = -R[1] / R[0] */
482 3254353 : t1 = L_Comp( Rh[1], Rl[1] ); /* R[1] in Q31 */
483 3254353 : t2 = L_abs( t1 ); /* abs R[1] */
484 3254353 : t0 = L_deposit_l( 0 );
485 3254353 : IF( Rh[0] != 0 )
486 : {
487 3254351 : t0 = Div_32_opt( t2, Rh[0], Rl[0] ); /* R[1]/R[0] in Q31 */
488 : /* Cause a difference in MODE1 due to different implementation of div32*/
489 : }
490 3254353 : if ( t1 > 0 )
491 : {
492 2414572 : t0 = L_negate( t0 ); /* -R[1]/R[0] */
493 : }
494 3254353 : Kl = L_Extract_lc( t0, &Kh ); /* K in DPF */
495 3254353 : t0 = L_shr( t0, 4 ); /* A[1] in Q27 */
496 3254353 : L_Extract( t0, &Ah[1], &Al[1] ); /* A[1] in DPF */
497 :
498 : /* Alpha = R[0] * (1-K**2) */
499 3254353 : t0 = Sqr_32( Kh, Kl ); /* K*K in Q31 */
500 3254353 : t0 = L_abs( t0 ); /* Some case <0 !! */
501 3254353 : t0 = L_sub( (Word32) 0x7fffffffL, t0 ); /* 1 - K*K in Q31 */
502 3254353 : lo = L_Extract_lc( t0, &hi ); /* DPF format */
503 3254353 : t0 = Mpy_32( Rh[0], Rl[0], hi, lo ); /* Alpha in Q31 */
504 3254353 : if ( epsP != NULL )
505 : {
506 3062779 : epsP[1] = t0;
507 3062779 : move32();
508 : }
509 :
510 : /* Normalize Alpha */
511 3254353 : alp_exp = norm_l( t0 );
512 3254353 : t0 = L_shl( t0, alp_exp );
513 3254353 : alp_l = L_Extract_lc( t0, &alp_h );
514 : /* DPF format */
515 :
516 : /*--------------------------------------*
517 : * ITERATIONS I=2 to m
518 : *--------------------------------------*/
519 :
520 48295060 : FOR( i = 2; i <= order; i++ )
521 : {
522 : /* t0 = SUM(R[j]*A[i-j], j=1, i-1) + R[i] */
523 45040707 : t0 = L_deposit_l( 0 );
524 397411713 : FOR( j = 1; j < i; j++ )
525 : {
526 352371006 : t0 = Mac_32( t0, Rh[j], Rl[j], Ah[i - j], Al[i - j] );
527 : }
528 :
529 45040707 : t0 = L_shl_o( t0, 4, &Overflow ); /* result in Q27 -> convert to Q31 */
530 : /* No overflow possible */
531 :
532 : /* Compose and add R[i] in Q3 */
533 45040707 : t0 = L_mac_o( t0, Rl[i], 1, &Overflow );
534 45040707 : t0 = L_msu_o( t0, Rh[i], -32768, &Overflow );
535 :
536 : /* K = -t0 / Alpha */
537 45040707 : t1 = L_abs( t0 );
538 45040707 : t2 = L_deposit_l( 0 );
539 45040707 : IF( alp_h != 0 )
540 : {
541 45040674 : t2 = Div_32_opt( t1, alp_h, alp_l ); /* abs(t0)/Alpha */
542 : /* Cause a difference in MODE1 due to different implementation of div32*/
543 : }
544 :
545 45040707 : if ( t0 > 0 )
546 : {
547 18562016 : t2 = L_negate( t2 ); /* K =-t0/Alpha */
548 : }
549 45040707 : t2 = L_shl_o( t2, alp_exp, &Overflow ); /* denormalize; compare to Alpha */
550 45040707 : test();
551 45040707 : if ( ( mem != NULL ) && ( ( GT_16( abs_s( extract_h( t2 ) ), k_max ) ) ) )
552 : {
553 10 : flag = 1;
554 10 : move16(); /* Test for unstable filter. If unstable keep old A(z) */
555 : }
556 45040707 : test();
557 45040707 : if ( ( mem != NULL ) && ( ( LT_32( L_abs( t2 ), 5 ) ) ) )
558 : {
559 9 : flag = 1;
560 9 : move16(); /*R matrix not reliable (R saturated for many coeff), keep old A(z) */
561 : }
562 45040707 : Kl = L_Extract_lc( t2, &Kh ); /* K in DPF */
563 :
564 : /*------------------------------------------*
565 : * Compute new LPC coeff. -> An[i]
566 : * An[j]= A[j] + K*A[i-j] , j=1 to i-1
567 : * An[i]= K
568 : *------------------------------------------*/
569 :
570 45040707 : k = mult_r( i, 16384 );
571 209152445 : FOR( j = 1; j < k; j++ )
572 : {
573 : /* Do two Iterations Together to Allow Direct Update of Ah & Al */
574 164111738 : t0 = Mac_32( L_Comp( Ah[j], Al[j] ), Kh, Kl, Ah[i - j], Al[i - j] );
575 164111738 : t1 = Mac_32( L_Comp( Ah[i - j], Al[i - j] ), Kh, Kl, Ah[j], Al[j] );
576 164111738 : L_Extract( t0, &Ah[j], &Al[j] );
577 164111738 : L_Extract( t1, &Ah[i - j], &Al[i - j] );
578 : }
579 45040707 : IF( s_and( i, 1 ) == 0 )
580 : {
581 24147530 : t0 = Mac_32( L_Comp( Ah[j], Al[j] ), Kh, Kl, Ah[i - j], Al[i - j] );
582 24147530 : L_Extract( t0, &Ah[j], &Al[j] );
583 : }
584 45040707 : t2 = L_shr( t2, 4 ); /* t2 = K in Q31 ->convert to Q27 */
585 45040707 : L_Extract( t2, &Ah[i], &Al[i] ); /* An[i] in Q27 */
586 :
587 : /* Alpha = Alpha * (1-K**2) */
588 45040707 : t1 = L_mult_o( Kh, Kh, &Overflow ); /* K*K in Q31 */
589 45040707 : t0 = L_mac( t1, mult( Kh, Kl ), 2 );
590 45040707 : t0 = L_abs( t0 ); /* Some case <0 !! */
591 45040707 : t0 = L_sub( (Word32) 0x7fffffffL, t0 ); /* 1 - K*K in Q31 */
592 45040707 : lo = L_Extract_lc( t0, &hi ); /* DPF format */
593 45040707 : t0 = Mpy_32( alp_h, alp_l, hi, lo ); /* Alpha in Q31 */
594 :
595 :
596 : /* store denormalized alpha in epsP */
597 45040707 : t1 = L_shr( t0, alp_exp );
598 45040707 : if ( epsP != NULL )
599 : {
600 42259079 : epsP[i] = t1;
601 42259079 : move32();
602 : }
603 :
604 : /* Normalize Alpha */
605 45040707 : j = norm_l( t0 );
606 45040707 : t0 = L_shl( t0, j );
607 45040707 : alp_l = L_Extract_lc( t0, &alp_h ); /* DPF format */
608 45040707 : alp_exp = add( alp_exp, j ); /* Add normalization to alp_exp */
609 : }
610 :
611 : /* Adaptive scaling */
612 3254353 : t1 = L_deposit_l( 0 );
613 51549413 : FOR( i = 1; i <= order; i++ )
614 : {
615 48295060 : t0 = L_Comp( Ah[i], Al[i] );
616 48295060 : t1 = L_max( t1, L_abs( t0 ) );
617 : }
618 3254353 : k = s_min( norm_l( t1 ), 3 );
619 3254353 : A[0] = shl( 2048, k );
620 3254353 : move16();
621 51549413 : FOR( i = 1; i <= order; i++ )
622 : {
623 48295060 : t0 = L_Comp( Ah[i], Al[i] );
624 48295060 : A[i] = round_fx_o( L_shl_o( t0, k, &Overflow ), &Overflow );
625 48295060 : move16();
626 : }
627 :
628 : BASOP_SATURATE_WARNING_ON_EVS
629 3254353 : IF( mem != NULL )
630 : {
631 : /* Enforce stable LPC filter - parcorr[0] and parcorr[1] are not LPC coeffiecients */
632 102567 : IF( flag )
633 : {
634 5 : Copy( mem, A, add( order, 1 ) );
635 : }
636 : ELSE /* If stable LPC filter, store into memories */
637 : {
638 102562 : Copy( A, mem, add( order, 1 ) );
639 : }
640 : }
641 :
642 :
643 3254353 : return ( flag );
644 : }
645 :
646 1515 : Word16 E_LPC_lev_dur_ivas_fx( const Word16 Rh[], const Word16 Rl[], Word16 A[], Word32 epsP[], const Word16 order, Word16 *mem )
647 : {
648 1515 : return ( E_LPC_lev_dur_stab_ivas_fx( Rh, Rl, A, epsP, order, mem, 32750 ) ); /* 0.99945 in Q15 */
649 : }
650 :
651 1515 : 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 )
652 : {
653 : Word16 i, j, k;
654 : Word16 hi, lo;
655 : Word16 Kh, Kl; /* reflection coefficient; hi and lo */
656 : Word16 alp_h, alp_l, alp_exp; /* Prediction gain; hi lo and exponent */
657 : Word32 t0, t1, t2; /* temporary variables */
658 : Word16 flag;
659 : Word16 Ah[TCXLTP_LTP_ORDER + 1], Al[TCXLTP_LTP_ORDER + 1]; /* LPC coef. in double prec. */
660 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
661 1515 : Flag Overflow = 0;
662 : #endif
663 :
664 :
665 : BASOP_SATURATE_WARNING_OFF_EVS
666 1515 : if ( epsP != NULL )
667 : {
668 0 : epsP[0] = L_Comp( Rh[0], Rl[0] );
669 0 : move32();
670 : }
671 :
672 1515 : flag = 0;
673 1515 : move16();
674 :
675 : /* K = A[1] = -R[1] / R[0] */
676 1515 : t1 = L_Comp( Rh[1], Rl[1] ); /* R[1] in Q31 */
677 1515 : t2 = L_abs( t1 ); /* abs R[1] */
678 1515 : t0 = L_deposit_l( 0 );
679 1515 : IF( Rh[0] != 0 )
680 : {
681 1515 : t0 = Div_32_opt( t2, Rh[0], Rl[0] ); /* R[1]/R[0] in Q31 */
682 : /* Cause a difference in MODE1 due to different implementation of div32*/
683 : }
684 1515 : if ( t1 > 0 )
685 : {
686 1506 : t0 = L_negate( t0 ); /* -R[1]/R[0] */
687 : }
688 1515 : Kl = L_Extract_lc( t0, &Kh ); /* K in DPF */
689 1515 : t0 = L_shr( t0, 4 ); /* A[1] in Q27 */
690 1515 : L_Extract( t0, &Ah[1], &Al[1] ); /* A[1] in DPF */
691 :
692 : /* Alpha = R[0] * (1-K**2) */
693 1515 : t0 = Sqr_32( Kh, Kl ); /* K*K in Q31 */
694 1515 : t0 = L_abs( t0 ); /* Some case <0 !! */
695 1515 : t0 = L_sub( (Word32) 0x7fffffffL, t0 ); /* 1 - K*K in Q31 */
696 1515 : lo = L_Extract_lc( t0, &hi ); /* DPF format */
697 1515 : t0 = Mpy_32( Rh[0], Rl[0], hi, lo ); /* Alpha in Q31 */
698 1515 : if ( epsP != NULL )
699 : {
700 0 : epsP[1] = t0;
701 0 : move32();
702 : }
703 :
704 : /* Normalize Alpha */
705 1515 : alp_exp = norm_l( t0 );
706 1515 : t0 = L_shl( t0, alp_exp );
707 1515 : alp_l = L_Extract_lc( t0, &alp_h );
708 : /* DPF format */
709 :
710 : /*--------------------------------------*
711 : * ITERATIONS I=2 to m
712 : *--------------------------------------*/
713 :
714 24240 : FOR( i = 2; i <= order; i++ )
715 : {
716 : /* t0 = SUM(R[j]*A[i-j], j=1, i-1) + R[i] */
717 22725 : t0 = L_deposit_l( 0 );
718 204525 : FOR( j = 1; j < i; j++ )
719 : {
720 181800 : t0 = Mac_32( t0, Rh[j], Rl[j], Ah[i - j], Al[i - j] );
721 : }
722 :
723 22725 : t0 = L_shl_o( t0, 4, &Overflow ); /* result in Q27 -> convert to Q31 */
724 : /* No overflow possible */
725 :
726 : /* Compose and add R[i] in Q3 */
727 22725 : t0 = L_mac_o( t0, Rl[i], 1, &Overflow );
728 22725 : t0 = L_msu_o( t0, Rh[i], -32768, &Overflow );
729 :
730 : /* K = -t0 / Alpha */
731 22725 : t1 = L_abs( t0 );
732 22725 : t2 = L_deposit_l( 0 );
733 22725 : IF( alp_h != 0 )
734 : {
735 22725 : t2 = Div_32_opt( t1, alp_h, alp_l ); /* abs(t0)/Alpha */
736 : /* Cause a difference in MODE1 due to different implementation of div32*/
737 : }
738 :
739 22725 : if ( t0 > 0 )
740 : {
741 10056 : t2 = L_negate( t2 ); /* K =-t0/Alpha */
742 : }
743 22725 : t2 = L_shl_o( t2, alp_exp, &Overflow ); /* denormalize; compare to Alpha */
744 22725 : test();
745 22725 : if ( ( mem != NULL ) && ( ( GT_16( abs_s( extract_h( t2 ) ), k_max ) ) ) )
746 : {
747 0 : flag = 1;
748 0 : move16(); /* Test for unstable filter. If unstable keep old A(z) */
749 : }
750 22725 : test();
751 22725 : if ( ( mem != NULL ) && ( ( LT_32( L_abs( t2 ), 5 ) ) ) )
752 : {
753 0 : flag = 1;
754 0 : move16(); /*R matrix not reliable (R saturated for many coeff), keep old A(z) */
755 : }
756 22725 : Kl = L_Extract_lc( t2, &Kh ); /* K in DPF */
757 :
758 : /*------------------------------------------*
759 : * Compute new LPC coeff. -> An[i]
760 : * An[j]= A[j] + K*A[i-j] , j=1 to i-1
761 : * An[i]= K
762 : *------------------------------------------*/
763 :
764 22725 : k = mult_r( i, 16384 );
765 107565 : FOR( j = 1; j < k; j++ )
766 : {
767 : /* Do two Iterations Together to Allow Direct Update of Ah & Al */
768 84840 : t0 = Mac_32( L_Comp( Ah[j], Al[j] ), Kh, Kl, Ah[i - j], Al[i - j] );
769 84840 : t1 = Mac_32( L_Comp( Ah[i - j], Al[i - j] ), Kh, Kl, Ah[j], Al[j] );
770 84840 : L_Extract( t0, &Ah[j], &Al[j] );
771 84840 : L_Extract( t1, &Ah[i - j], &Al[i - j] );
772 : }
773 22725 : IF( s_and( i, 1 ) == 0 )
774 : {
775 12120 : t0 = Mac_32( L_Comp( Ah[j], Al[j] ), Kh, Kl, Ah[i - j], Al[i - j] );
776 12120 : L_Extract( t0, &Ah[j], &Al[j] );
777 : }
778 22725 : t2 = L_shr( t2, 4 ); /* t2 = K in Q31 ->convert to Q27 */
779 22725 : L_Extract( t2, &Ah[i], &Al[i] ); /* An[i] in Q27 */
780 :
781 : /* Alpha = Alpha * (1-K**2) */
782 22725 : t1 = L_mult_o( Kh, Kh, &Overflow ); /* K*K in Q31 */
783 22725 : t0 = L_mac( t1, mult( Kh, Kl ), 2 );
784 22725 : t0 = L_abs( t0 ); /* Some case <0 !! */
785 22725 : t0 = L_sub( (Word32) 0x7fffffffL, t0 ); /* 1 - K*K in Q31 */
786 22725 : lo = L_Extract_lc( t0, &hi ); /* DPF format */
787 22725 : t0 = Mpy_32( alp_h, alp_l, hi, lo ); /* Alpha in Q31 */
788 :
789 :
790 : /* store denormalized alpha in epsP */
791 22725 : t1 = L_shr( t0, alp_exp );
792 22725 : if ( epsP != NULL )
793 : {
794 0 : epsP[i] = t1;
795 0 : move32();
796 : }
797 :
798 : /* Normalize Alpha */
799 22725 : j = norm_l( t0 );
800 22725 : t0 = L_shl( t0, j );
801 22725 : alp_l = L_Extract_lc( t0, &alp_h ); /* DPF format */
802 22725 : alp_exp = add( alp_exp, j ); /* Add normalization to alp_exp */
803 : }
804 :
805 : /* Adaptive scaling */
806 1515 : t1 = L_deposit_l( 0 );
807 25755 : FOR( i = 1; i <= order; i++ )
808 : {
809 24240 : t0 = L_Comp( Ah[i], Al[i] );
810 24240 : t1 = L_max( t1, L_abs( t0 ) );
811 : }
812 1515 : k = s_min( sub( norm_l( t1 ), 1 ), 3 );
813 1515 : A[0] = shl( 2048, k );
814 1515 : move16();
815 25755 : FOR( i = 1; i <= order; i++ )
816 : {
817 24240 : t0 = L_Comp( Ah[i], Al[i] );
818 24240 : A[i] = round_fx_o( L_shl_o( t0, k, &Overflow ), &Overflow );
819 24240 : move16();
820 : }
821 :
822 : BASOP_SATURATE_WARNING_ON_EVS
823 1515 : IF( mem != NULL )
824 : {
825 : /* Enforce stable LPC filter - parcorr[0] and parcorr[1] are not LPC coeffiecients */
826 0 : IF( flag )
827 : {
828 0 : Copy( mem, A, add( order, 1 ) );
829 : }
830 : ELSE /* If stable LPC filter, store into memories */
831 : {
832 0 : Copy( A, mem, add( order, 1 ) );
833 : }
834 : }
835 :
836 :
837 1515 : return ( flag );
838 : }
839 :
840 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*/ )
841 : {
842 0 : return ( E_LPC_lev_dur_stab_fx( Rh, Rl, A, epsP, order, mem, 32750 ) ); /* 0.99945 in Q15 */
843 : }
844 :
845 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*/ )
846 : {
847 : Word16 i, j, k;
848 : Word16 hi, lo;
849 : Word16 Kh, Kl; /* reflection coefficient; hi and lo */
850 : Word16 alp_h, alp_l, alp_exp; /* Prediction gain; hi lo and exponent */
851 : Word32 t0, t1, t2; /* temporary variables */
852 : Word16 flag;
853 : Word16 Ah[TCXLTP_LTP_ORDER + 1], Al[TCXLTP_LTP_ORDER + 1]; /* LPC coef. in double prec. */
854 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
855 0 : Flag Overflow = 0;
856 0 : move32();
857 : #endif
858 :
859 :
860 : BASOP_SATURATE_WARNING_OFF_EVS
861 0 : if ( epsP != NULL )
862 : {
863 0 : epsP[0] = L_Comp( Rh[0], Rl[0] );
864 0 : move32();
865 : }
866 :
867 0 : flag = 0;
868 0 : move16();
869 :
870 : /* K = A[1] = -R[1] / R[0] */
871 0 : t1 = L_Comp( Rh[1], Rl[1] ); /* R[1] in Q31 */
872 0 : t2 = L_abs( t1 ); /* abs R[1] */
873 0 : t0 = L_deposit_l( 0 );
874 0 : IF( Rh[0] != 0 )
875 : {
876 0 : t0 = Div_32_opt( t2, Rh[0], Rl[0] ); /* R[1]/R[0] in Q31 */
877 : /* Cause a difference in MODE1 due to different implementation of div32*/
878 : }
879 0 : if ( t1 > 0 )
880 : {
881 0 : t0 = L_negate( t0 ); /* -R[1]/R[0] */
882 : }
883 0 : Kl = L_Extract_lc( t0, &Kh ); /* K in DPF */
884 0 : t0 = L_shr( t0, 4 ); /* A[1] in Q27 */
885 0 : L_Extract( t0, &Ah[1], &Al[1] ); /* A[1] in DPF */
886 :
887 : /* Alpha = R[0] * (1-K**2) */
888 0 : t0 = Sqr_32( Kh, Kl ); /* K*K in Q31 */
889 0 : t0 = L_abs( t0 ); /* Some case <0 !! */
890 0 : t0 = L_sub( (Word32) 0x7fffffffL, t0 ); /* 1 - K*K in Q31 */
891 0 : lo = L_Extract_lc( t0, &hi ); /* DPF format */
892 0 : t0 = Mpy_32( Rh[0], Rl[0], hi, lo ); /* Alpha in Q31 */
893 0 : if ( epsP != NULL )
894 : {
895 0 : epsP[1] = t0;
896 0 : move32();
897 : }
898 :
899 : /* Normalize Alpha */
900 0 : alp_exp = norm_l( t0 );
901 0 : t0 = L_shl( t0, alp_exp );
902 0 : alp_l = L_Extract_lc( t0, &alp_h );
903 : /* DPF format */
904 :
905 : /*--------------------------------------*
906 : * ITERATIONS I=2 to m
907 : *--------------------------------------*/
908 :
909 0 : FOR( i = 2; i <= order; i++ )
910 : {
911 : /* t0 = SUM(R[j]*A[i-j], j=1, i-1) + R[i] */
912 0 : t0 = L_deposit_l( 0 );
913 0 : FOR( j = 1; j < i; j++ )
914 : {
915 0 : t0 = Mac_32( t0, Rh[j], Rl[j], Ah[i - j], Al[i - j] );
916 : }
917 :
918 0 : t0 = L_shl_o( t0, 4, &Overflow ); /* result in Q27 -> convert to Q31 */
919 : /* No overflow possible */
920 :
921 : /* Compose and add R[i] in Q3 */
922 0 : t0 = L_mac_o( t0, Rl[i], 1, &Overflow );
923 0 : t0 = L_msu_o( t0, Rh[i], -32768, &Overflow );
924 :
925 : /* K = -t0 / Alpha */
926 0 : t1 = L_abs( t0 );
927 0 : t2 = L_deposit_l( 0 );
928 0 : IF( alp_h != 0 )
929 : {
930 0 : t2 = Div_32_opt( t1, alp_h, alp_l ); /* abs(t0)/Alpha */
931 : /* Cause a difference in MODE1 due to different implementation of div32*/
932 : }
933 :
934 0 : if ( t0 > 0 )
935 : {
936 0 : t2 = L_negate( t2 ); /* K =-t0/Alpha */
937 : }
938 0 : t2 = L_shl_o( t2, alp_exp, &Overflow ); /* denormalize; compare to Alpha */
939 0 : test();
940 0 : if ( ( mem != NULL ) && ( ( GT_16( abs_s( extract_h( t2 ) ), k_max ) ) ) )
941 : {
942 0 : flag = 1;
943 0 : move16(); /* Test for unstable filter. If unstable keep old A(z) */
944 : }
945 0 : test();
946 0 : if ( ( mem != NULL ) && ( ( LT_32( L_abs( t2 ), 5 ) ) ) )
947 : {
948 0 : flag = 1;
949 0 : move16(); /*R matrix not reliable (R saturated for many coeff), keep old A(z) */
950 : }
951 0 : Kl = L_Extract_lc( t2, &Kh ); /* K in DPF */
952 :
953 : /*------------------------------------------*
954 : * Compute new LPC coeff. -> An[i]
955 : * An[j]= A[j] + K*A[i-j] , j=1 to i-1
956 : * An[i]= K
957 : *------------------------------------------*/
958 :
959 0 : k = mult_r( i, 16384 );
960 0 : FOR( j = 1; j < k; j++ )
961 : {
962 : /* Do two Iterations Together to Allow Direct Update of Ah & Al */
963 0 : t0 = Mac_32( L_Comp( Ah[j], Al[j] ), Kh, Kl, Ah[i - j], Al[i - j] );
964 0 : t1 = Mac_32( L_Comp( Ah[i - j], Al[i - j] ), Kh, Kl, Ah[j], Al[j] );
965 0 : L_Extract( t0, &Ah[j], &Al[j] );
966 0 : L_Extract( t1, &Ah[i - j], &Al[i - j] );
967 : }
968 0 : IF( s_and( i, 1 ) == 0 )
969 : {
970 0 : t0 = Mac_32( L_Comp( Ah[j], Al[j] ), Kh, Kl, Ah[i - j], Al[i - j] );
971 0 : L_Extract( t0, &Ah[j], &Al[j] );
972 : }
973 0 : t2 = L_shr( t2, 4 ); /* t2 = K in Q31 ->convert to Q27 */
974 0 : L_Extract( t2, &Ah[i], &Al[i] ); /* An[i] in Q27 */
975 :
976 : /* Alpha = Alpha * (1-K**2) */
977 0 : t1 = L_mult_o( Kh, Kh, &Overflow ); /* K*K in Q31 */
978 0 : t0 = L_mac( t1, mult( Kh, Kl ), 2 );
979 0 : t0 = L_abs( t0 ); /* Some case <0 !! */
980 0 : t0 = L_sub( (Word32) 0x7fffffffL, t0 ); /* 1 - K*K in Q31 */
981 0 : lo = L_Extract_lc( t0, &hi ); /* DPF format */
982 0 : t0 = Mpy_32( alp_h, alp_l, hi, lo ); /* Alpha in Q31 */
983 :
984 :
985 : /* store denormalized alpha in epsP */
986 0 : t1 = L_shr( t0, alp_exp );
987 0 : if ( epsP != NULL )
988 : {
989 0 : epsP[i] = t1;
990 0 : move32();
991 : }
992 :
993 : /* Normalize Alpha */
994 0 : j = norm_l( t0 );
995 0 : t0 = L_shl( t0, j );
996 0 : alp_l = L_Extract_lc( t0, &alp_h ); /* DPF format */
997 0 : alp_exp = add( alp_exp, j ); /* Add normalization to alp_exp */
998 : }
999 :
1000 : /* Adaptive scaling */
1001 0 : t1 = L_deposit_l( 0 );
1002 0 : FOR( i = 1; i <= order; i++ )
1003 : {
1004 0 : t0 = L_Comp( Ah[i], Al[i] );
1005 0 : t1 = L_max( t1, L_abs( t0 ) );
1006 : }
1007 0 : k = s_min( norm_l( t1 ), 3 );
1008 0 : A[0] = L_shl( 2048, k + 16 );
1009 0 : move16();
1010 0 : FOR( i = 1; i <= order; i++ )
1011 : {
1012 0 : t0 = L_Comp( Ah[i], Al[i] );
1013 0 : A[i] = L_shl_o( t0, k, &Overflow );
1014 0 : move16();
1015 : }
1016 :
1017 : BASOP_SATURATE_WARNING_ON_EVS
1018 0 : IF( mem != NULL )
1019 : {
1020 : /* Enforce stable LPC filter - parcorr[0] and parcorr[1] are not LPC coeffiecients */
1021 0 : IF( flag )
1022 : {
1023 0 : Copy32( mem, A, add( order, 1 ) );
1024 : }
1025 : ELSE /* If stable LPC filter, store into memories */
1026 : {
1027 0 : Copy32( A, mem, add( order, 1 ) );
1028 : }
1029 : }
1030 :
1031 :
1032 0 : return ( flag );
1033 : }
1034 :
1035 :
1036 : /*
1037 : * E_LPC_a_add_tilt
1038 : *
1039 : * Parameters:
1040 : * a I: LP filter coefficients (m+1 coeffs)
1041 : * ap O: modified LP filter coefficients (m+2 coeffs)
1042 : * gamma I: tilt factor
1043 : * m I: order of LP filter
1044 : *
1045 : * Function:
1046 : * Modified LP filter by adding 1st order pre-premphasis, Ap(z)=A(z).(1-gamma.z^(-1))
1047 : *
1048 : * Returns:
1049 : * void
1050 : */
1051 17495 : void E_LPC_a_add_tilt( const Word16 *a /*Qa*/, Word16 *ap /*Qa*/, Word16 gamma /*Q15*/, Word16 m )
1052 : {
1053 : Word16 i;
1054 : Word32 Amax, Atmp[M + 2];
1055 : Word16 shift;
1056 :
1057 :
1058 17495 : Amax = L_mult( 16384, a[0] );
1059 297415 : FOR( i = 1; i <= m; i++ )
1060 : {
1061 279920 : Atmp[i] = L_sub( L_mult( 16384, a[i] ), L_mult0( gamma, a[i - 1] ) );
1062 279920 : move32();
1063 279920 : Amax = L_max( Amax, L_abs( Atmp[i] ) );
1064 : }
1065 17495 : Atmp[m + 1] = L_negate( L_mult0( gamma, a[m] ) );
1066 17495 : move32();
1067 17495 : Amax = L_max( Amax, L_abs( Atmp[add( m, 1 )] ) );
1068 17495 : shift = norm_l( Amax );
1069 17495 : ap[0] = shl( a[0], sub( shift, 1 ) );
1070 17495 : move16();
1071 297415 : FOR( i = 1; i <= m; i++ )
1072 : {
1073 279920 : ap[i] = round_fx( L_shl( Atmp[i], shift ) );
1074 279920 : move16();
1075 : }
1076 17495 : ap[add( m, 1 )] = round_fx( L_shl( Atmp[add( m, 1 )], shift ) );
1077 17495 : move16();
1078 17495 : }
1079 :
1080 228504 : void E_LPC_int_lpc_tcx( const Word16 lsp_old[], /* input : LSPs from past frame Q15 */
1081 : const Word16 lsp_new[], /* input : LSPs from present frame Q15 */
1082 : Word16 a[] /* output: interpolated LP coefficients Q12 */
1083 : )
1084 : {
1085 : Word16 i, lsp[M];
1086 :
1087 :
1088 3884568 : FOR( i = 0; i < M; i++ )
1089 : {
1090 : /*lsp[i] = lsp_old[i]*0.125f + lsp_new[i]*0.875f;*/
1091 3656064 : lsp[i] = round_fx( L_mac( L_mult( lsp_old[i], 4096 ), lsp_new[i], 28672 ) );
1092 3656064 : move16();
1093 : }
1094 228504 : E_LPC_f_lsp_a_conversion( lsp, a, M );
1095 :
1096 :
1097 228504 : return;
1098 : }
1099 :
1100 31484 : static void lsp_reorder(
1101 : Word16 *lsp, /* (I/O): LSP vector (acos() domain) Q13*1.2732 */
1102 : Word16 min_dist, /* (I): minimum required distance Q13*1.2732 */
1103 : Word16 lpcorder /* (I): LPC order Q0 */
1104 : )
1105 : {
1106 : Word16 i;
1107 : Word16 lsp_min, lsp_max;
1108 :
1109 :
1110 : /* Verify the LSF ordering and minimum GAP */
1111 31484 : lsp_min = min_dist;
1112 31484 : move16();
1113 535228 : FOR( i = 0; i < lpcorder; ++i )
1114 : {
1115 503744 : lsp[i] = s_max( lsp[i], lsp_min );
1116 503744 : move16();
1117 503744 : lsp_min = add( lsp[i], min_dist );
1118 : }
1119 :
1120 : /* Reverify the LSF ordering and minimum GAP in the reverse order (security) */
1121 31484 : lsp_max = sub( 32767, min_dist );
1122 :
1123 : /* If danger of unstable filter in case of resonance in HF */
1124 31484 : lpcorder = sub( lpcorder, 1 );
1125 31484 : IF( GT_16( lsp[lpcorder], lsp_max ) )
1126 : {
1127 : /* Reverify the minimum LSF gap in the reverse sense */
1128 0 : FOR( i = lpcorder; i >= 0; --i )
1129 : {
1130 0 : lsp[i] = s_min( lsp[i], lsp_max );
1131 0 : move16();
1132 0 : lsp_max = sub( lsp[i], min_dist );
1133 : }
1134 : }
1135 31484 : }
1136 :
1137 : /* Approximate unweighting */
1138 31484 : Word16 E_LPC_lsp_unweight(
1139 : /* const */ Word16 lsp_w[], /* (I): weighted xSP Q15 */
1140 : Word16 lsp_uw[], /* (O): unweighted xSP Q15 */
1141 : Word16 lsf_uw[], /* (O): unweighted LSF Q1*1.28 */
1142 : Word16 inv_gamma, /* (I): inverse weighting factor Q14 */
1143 : Word16 lpcorder /* (I): prediction order Q0 */
1144 : )
1145 : {
1146 : Word16 lsp_w_orig[M], lsp_w_diff[M], mean, step; /* Q13*1.2732 */
1147 31484 : const lsp_unw_triplet *unw_coeffs = NULL;
1148 : Word16 i;
1149 :
1150 31484 : step = 0; /* to avoid compilation warnings */
1151 :
1152 :
1153 31484 : assert( lpcorder == 16 );
1154 :
1155 : /* Table selection */
1156 31484 : IF( EQ_16( inv_gamma, GAMMA16k_INV ) )
1157 : {
1158 0 : unw_coeffs = p16_gamma0_94to1;
1159 0 : move16();
1160 : }
1161 31484 : ELSE IF( EQ_16( inv_gamma, GAMMA1_INV ) )
1162 : {
1163 31484 : unw_coeffs = p16_gamma0_92to1;
1164 31484 : move16();
1165 : }
1166 : ELSE
1167 : {
1168 0 : assert( 0 );
1169 : }
1170 :
1171 : /* step = M_PI/(float)(lpcorder+1); */
1172 31484 : step = 1927;
1173 31484 : move16();
1174 31484 : mean = 0;
1175 31484 : move16();
1176 :
1177 : /* Apply acos() and get mean removed version */
1178 535228 : FOR( i = 0; i < lpcorder; ++i )
1179 : {
1180 503744 : mean = add( mean, step );
1181 503744 : lsp_w_orig[i] = shl( xsp_to_xsf( lsp_w[i] ), 1 );
1182 503744 : move16();
1183 503744 : lsp_w_diff[i] = sub( lsp_w_orig[i], mean );
1184 503744 : move16();
1185 : }
1186 :
1187 : /* Approximate unweighting by 3-tap FIR */
1188 31484 : 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 ) ) );
1189 31484 : move16();
1190 472260 : FOR( i = 1; i < lpcorder - 1; ++i )
1191 : {
1192 440776 : 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 ) ) );
1193 440776 : move16();
1194 : }
1195 31484 : 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 ) ) );
1196 31484 : move16();
1197 :
1198 : /* Reorder */
1199 31484 : lsp_reorder( lsp_uw, 256, lpcorder );
1200 :
1201 : /* Convert to LSF, apply cos() */
1202 535228 : FOR( i = 0; i < lpcorder; ++i )
1203 : {
1204 503744 : lsf_uw[i] = shr_r( lsp_uw[i], 1 );
1205 503744 : move16();
1206 503744 : lsp_uw[i] = xsf_to_xsp( lsf_uw[i] );
1207 503744 : move16();
1208 : }
1209 :
1210 31484 : return 0;
1211 : }
1212 :
1213 : /*
1214 : * E_LPC_schur_ivas
1215 : *
1216 : * Parameters:
1217 : * R I: Rh[M+1] Vector of autocorrelations (msb)
1218 : * reflCoeff O: rc[M] Reflection coefficients. Q15
1219 : * epsP O: error vector
1220 : *
1221 : * Function:
1222 : * Schur algorithm to compute
1223 : * the LPC parameters from the autocorrelations of speech.
1224 : *
1225 : * Returns:
1226 : * void
1227 : */
1228 2232344 : Word32 E_LPC_schur_ivas( Word32 r[] /*Qr*/, Word16 reflCoeff[] /*Q15*/, const Word16 m )
1229 : {
1230 : Word16 i, j, temp16, mMi, s;
1231 : Word32 g0[M], *g1, tmp32;
1232 2232344 : const Word32 min_epsP = 1; /* > 0.01f*2^27/2^30 */
1233 : Word32 tmp_epsP;
1234 :
1235 2232344 : s = getScaleFactor32( r, add( m, 1 ) );
1236 2232344 : IF( s != 0 )
1237 : {
1238 0 : scale_sig32( r, add( m, 1 ), s ); /* scale in-place */
1239 : }
1240 :
1241 2232344 : g1 = r;
1242 2232344 : Copy32( r + 1, g0, m );
1243 :
1244 : /* compute g0[0]/g1[0], where g0[0] < g1[0] */
1245 2232344 : temp16 = negate( divide3232( g0[0], g1[0] ) );
1246 2232344 : reflCoeff[0] = temp16;
1247 2232344 : move16();
1248 : // epsP[0] = r[0];
1249 2232344 : move32();
1250 :
1251 :
1252 20091096 : FOR( i = 0; i < m; i++ )
1253 : {
1254 : /* g1[0] = g0[0]*temp16 + g1[0]; */
1255 17858752 : tmp32 = Mpy_32_16_1( g0[0], temp16 );
1256 17858752 : g1[0] = L_add( g1[0], tmp32 );
1257 17858752 : move32();
1258 :
1259 17858752 : mMi = sub( m, i );
1260 80364384 : FOR( j = 1; j < mMi; j++ )
1261 : {
1262 : /* g0[j-1] = g0[j] + g1[j]*temp16;
1263 : g1[j] = g0[j]*temp16 + g1[j]; */
1264 62505632 : g0[j - 1] = L_add( g0[j], Mpy_32_16_1( g1[j], temp16 ) );
1265 62505632 : move32();
1266 62505632 : g1[j] = L_add( g1[j], Mpy_32_16_1( g0[j], temp16 ) );
1267 62505632 : move32();
1268 : }
1269 17858752 : temp16 = negate( divide3232( g0[0], g1[0] ) );
1270 17858752 : reflCoeff[i + 1] = temp16;
1271 17858752 : move16();
1272 :
1273 : /* Prediction errors */
1274 17858752 : tmp_epsP = L_shr( g1[0], s );
1275 17858752 : if ( tmp_epsP <= 0 )
1276 : {
1277 0 : tmp_epsP = min_epsP;
1278 0 : move32();
1279 : }
1280 : // epsP[i + 1] = tmp_epsP;
1281 17858752 : move32();
1282 : }
1283 :
1284 : /* epsP[i+1] = g0[0]*temp16 + g1[0]; */
1285 2232344 : tmp_epsP = L_add( g1[0], Mpy_32_16_1( g0[0], temp16 ) );
1286 2232344 : tmp_epsP = L_shr( tmp_epsP, s );
1287 2232344 : if ( tmp_epsP <= 0 )
1288 : {
1289 0 : tmp_epsP = min_epsP;
1290 0 : move32();
1291 : }
1292 :
1293 : /* prediction gain = divide3232(L_shr(epsP[0], PRED_GAIN_E), g1[0]); */
1294 :
1295 :
1296 2232344 : return g1[0];
1297 : }
1298 :
1299 : /*
1300 : * E_LPC_schur
1301 : *
1302 : * Parameters:
1303 : * R I: Rh[M+1] Vector of autocorrelations (msb)
1304 : * reflCoeff O: rc[M] Reflection coefficients. Q15
1305 : * epsP O: error vector
1306 : *
1307 : * Function:
1308 : * Schur algorithm to compute
1309 : * the LPC parameters from the autocorrelations of speech.
1310 : *
1311 : * Returns:
1312 : * void
1313 : */
1314 440614 : Word32 E_LPC_schur( Word32 r[] /*Qr*/, Word16 reflCoeff[] /*Q15*/, Word32 epsP[] /*Qr*/, const Word16 m )
1315 : {
1316 : Word16 i, j, temp16, mM1, mMi, s;
1317 : Word32 g0[M], *g1, tmp32;
1318 440614 : const Word32 min_epsP = 1; /* > 0.01f*2^27/2^30 */
1319 : Word32 tmp_epsP;
1320 :
1321 :
1322 440614 : mM1 = sub( m, 1 );
1323 :
1324 440614 : s = getScaleFactor32( r, add( m, 1 ) );
1325 440614 : IF( s != 0 )
1326 : {
1327 156766 : scale_sig32( r, add( m, 1 ), s ); /* scale in-place */
1328 : }
1329 :
1330 440614 : g1 = r;
1331 440614 : Copy32( r + 1, g0, m );
1332 :
1333 : /* compute g0[0]/g1[0], where g0[0] < g1[0] */
1334 440614 : temp16 = negate( divide3232( g0[0], g1[0] ) );
1335 440614 : reflCoeff[0] = temp16;
1336 440614 : move16();
1337 440614 : epsP[0] = r[0];
1338 440614 : move32();
1339 :
1340 :
1341 3524912 : FOR( i = 0; i < mM1; i++ )
1342 : {
1343 : /* g1[0] = g0[0]*temp16 + g1[0]; */
1344 3084298 : tmp32 = Mpy_32_16_1( g0[0], temp16 );
1345 3084298 : g1[0] = L_add( g1[0], tmp32 );
1346 3084298 : move32();
1347 :
1348 3084298 : mMi = sub( m, i );
1349 15421490 : FOR( j = 1; j < mMi; j++ )
1350 : {
1351 : /* g0[j-1] = g0[j] + g1[j]*temp16;
1352 : g1[j] = g0[j]*temp16 + g1[j]; */
1353 12337192 : g0[j - 1] = L_add( g0[j], Mpy_32_16_1( g1[j], temp16 ) );
1354 12337192 : move32();
1355 12337192 : g1[j] = L_add( g1[j], Mpy_32_16_1( g0[j], temp16 ) );
1356 12337192 : move32();
1357 : }
1358 3084298 : temp16 = negate( divide3232( g0[0], g1[0] ) );
1359 3084298 : reflCoeff[i + 1] = temp16;
1360 3084298 : move16();
1361 :
1362 : /* Prediction errors */
1363 3084298 : tmp_epsP = L_shr( g1[0], s );
1364 3084298 : if ( tmp_epsP <= 0 )
1365 : {
1366 0 : tmp_epsP = min_epsP;
1367 0 : move32();
1368 : }
1369 3084298 : epsP[i + 1] = tmp_epsP;
1370 3084298 : move32();
1371 : }
1372 :
1373 : /* epsP[i+1] = g0[0]*temp16 + g1[0]; */
1374 440614 : tmp_epsP = L_add( g1[0], Mpy_32_16_1( g0[0], temp16 ) );
1375 440614 : tmp_epsP = L_shr( tmp_epsP, s );
1376 440614 : if ( tmp_epsP <= 0 )
1377 : {
1378 0 : tmp_epsP = min_epsP;
1379 0 : move32();
1380 : }
1381 440614 : epsP[i + 1] = tmp_epsP;
1382 440614 : move32();
1383 :
1384 : /* prediction gain = divide3232(L_shr(epsP[0], PRED_GAIN_E), g1[0]); */
1385 :
1386 :
1387 440614 : return g1[0];
1388 : }
1389 :
1390 :
1391 : extern const PWord16 *w_a[7]; // Q15
1392 : extern const PWord16 w19N[127];
1393 : extern const PWord16 w18N[127];
1394 : extern void BASOP_getTables( const PWord16 **ptwiddle, const PWord16 **sin_twiddle, Word16 *psin_step, Word16 length );
1395 0 : static void spec2isf(
1396 : Word16 /*double*/ spec_r[], /* input spectrum real part (only left half + one zero)Q_spec*/
1397 : Word16 /*double*/ spec_i[], /* input spectrum imag part (only left half+right halt with zeros)Q_spec*/
1398 : Word16 /*short*/ speclen, /* length of spectrum (only left half)*/
1399 : Word16 /*double*/ lsf[],
1400 : /* locations of LSFs (buffer must be sufficiently long) */ /*15Q16*/
1401 : const Word16 /*double*/ old_lsf[] /* locations of LSFs (buffer must be sufficiently long) */ /*15Q16*/
1402 : )
1403 : {
1404 :
1405 : /*spec_r[] needs a 0 in the end!*/
1406 : Word16 s;
1407 : Word16 tmp, i;
1408 : Word16 specix, lsfix;
1409 :
1410 0 : specix = lsfix = 0;
1411 0 : move16();
1412 0 : move16();
1413 0 : s = spec_r[specix++];
1414 0 : move16();
1415 :
1416 0 : WHILE( LT_16( specix, speclen ) && LE_16( lsfix, 15 ) )
1417 : {
1418 0 : test();
1419 : /*check for next zero crossing*/
1420 : /*for (; s*spec_r[specix] >= 0; specix++);*/
1421 0 : WHILE( mult( s, spec_r[specix] ) >= 0 )
1422 0 : specix = add( specix, 1 );
1423 :
1424 0 : tmp = divide1616( spec_r[specix - 1], sub( spec_r[specix - 1], spec_r[specix] ) );
1425 : /*lsf[lsfix] = L_add(L_deposit_h(sub(specix,1)) , L_shl(L_deposit_l(tmp),1));*/ /*Q16*/
1426 0 : lsf[lsfix] = add( shl( sub( specix, 1 ), 7 ), shr( ( tmp ), 8 ) ); /*7Q8*/
1427 0 : move16();
1428 :
1429 0 : lsfix++;
1430 :
1431 : /*check for the next zero crossing*/
1432 : /*for (; s*spec_i[specix] >= 0; specix++);*/
1433 :
1434 0 : WHILE( mult( s, spec_i[specix] ) >= 0 )
1435 0 : specix = add( specix, 1 );
1436 :
1437 0 : tmp = divide1616( spec_i[specix - 1], sub( spec_i[specix - 1], spec_i[specix] ) );
1438 : /*lsf[lsfix] = L_add(L_deposit_h(sub(specix,1)) , L_shl(L_deposit_l(tmp),1));*/ /*Q16*/
1439 0 : lsf[lsfix] = add( shl( sub( specix, 1 ), 7 ), shr( ( tmp ), 8 ) ); /*7Q8*/
1440 0 : move16();
1441 :
1442 0 : lsfix++;
1443 :
1444 0 : spec_r[speclen] = s;
1445 0 : move16();
1446 0 : spec_i[speclen] = s;
1447 0 : move16();
1448 :
1449 0 : s = negate( s );
1450 : }
1451 :
1452 0 : IF( LT_16( lsfix, 16 ) )
1453 : {
1454 0 : FOR( i = 0; i < 16; i++ )
1455 : {
1456 0 : lsf[i] = old_lsf[i];
1457 0 : move16();
1458 : }
1459 : }
1460 :
1461 0 : return;
1462 : }
1463 :
1464 0 : void E_LPC_a_lsf_isf_conversion( Word16 *lpcCoeffs /*Qx*/, Word16 *lsf /*15Q16*/, const Word16 *old_lsf /*15Q16*/, Word16 lpcOrder, Word8 lpcRep /*Q0*/ )
1465 : {
1466 : Word32 RealFFT[128];
1467 : Word32 ImagFFT[128];
1468 : Word16 RealOut[130];
1469 : Word16 ImagOut[130];
1470 : Word32 *ptrReal;
1471 : Word32 *ptrImag;
1472 : Word16 n, i, j, step, scale;
1473 : const PWord16 *ptwiddle, *pwn17, *pwn17i;
1474 : PWord16 *pwn15, *pwn15i, tmpw15;
1475 0 : Word16 N = 256;
1476 : Word16 s[4];
1477 : Word32 L_tmp, L_tmp1, L_tmp3;
1478 : Word16 lpc[19];
1479 0 : move16();
1480 :
1481 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1482 0 : Flag Overflow = 0;
1483 0 : move32();
1484 : #endif
1485 :
1486 : /* half length FFT */
1487 0 : scale = add( norm_s( lpcCoeffs[0] ), 1 ) + 5;
1488 0 : move16();
1489 :
1490 : /*s = [sum(a) ((-1).^(1:length(a)))*a];*/
1491 0 : L_tmp = L_deposit_h( 0 );
1492 0 : FOR( j = 0; j <= lpcOrder; j++ )
1493 : {
1494 0 : L_tmp = L_mac( L_tmp, lpcCoeffs[j], 0x800 );
1495 : }
1496 : /*s[1] = round_fx(L_tmp); move16();*/
1497 :
1498 0 : L_tmp1 = L_deposit_h( 0 );
1499 0 : FOR( j = 0; j < lpcOrder / 2; j++ )
1500 : {
1501 0 : L_tmp1 = L_msu( L_tmp1, lpcCoeffs[2 * j], 0x800 );
1502 0 : L_tmp1 = L_mac( L_tmp1, lpcCoeffs[2 * j + 1], 0x800 );
1503 : }
1504 0 : L_tmp1 = L_msu( L_tmp1, lpcCoeffs[2 * j], 0x800 );
1505 : /*s[2] = round_fx(L_tmp1); move16();*/
1506 :
1507 :
1508 0 : L_tmp3 = L_add( L_tmp1, L_tmp );
1509 0 : IF( L_tmp3 != 0 )
1510 : {
1511 0 : s[1] = BASOP_Util_Divide3232_Scale( L_sub( L_tmp1, L_tmp ), L_tmp3, &step );
1512 0 : move16();
1513 : /*s[1] = BASOP_Util_Divide1616_Scale(sub(s[2],s[1]),add(s[2],s[1]), &step); move16();*/
1514 : BASOP_SATURATE_WARNING_OFF_EVS
1515 0 : s[0] = negate( shr( -32768, step + 1 ) );
1516 0 : move16();
1517 0 : s[2] = negate( shr( -32768, step + 1 ) );
1518 0 : move16();
1519 : BASOP_SATURATE_WARNING_ON_EVS
1520 : }
1521 : ELSE
1522 : {
1523 0 : s[1] = 16384 / 4;
1524 0 : move16();
1525 0 : s[0] = 0;
1526 0 : move16();
1527 0 : s[2] = 0;
1528 0 : move16();
1529 : }
1530 0 : s[0] = shr( s[0], 1 );
1531 0 : move16();
1532 0 : s[1] = shr( s[1], 1 );
1533 0 : move16();
1534 0 : s[2] = shr( s[2], 1 );
1535 0 : move16();
1536 0 : lpc[0] = mult_r( lpcCoeffs[0], s[0] );
1537 0 : move16();
1538 0 : L_tmp = L_mult( s[0], lpcCoeffs[1] );
1539 0 : lpc[1] = mac_r( L_tmp, lpcCoeffs[1 - 1], s[1] );
1540 0 : move16();
1541 :
1542 0 : FOR( n = 2; n < 17; n++ )
1543 : {
1544 0 : L_tmp = L_mult( s[0], lpcCoeffs[n] );
1545 0 : L_tmp = L_mac( L_tmp, lpcCoeffs[n - 1], s[1] );
1546 0 : lpc[n] = mac_r( L_tmp, lpcCoeffs[n - 2], s[2] );
1547 0 : move16();
1548 : }
1549 0 : lpc[18] = mult_r( lpcCoeffs[16], s[0] );
1550 0 : move16();
1551 0 : L_tmp = L_mult( s[0], lpcCoeffs[15] );
1552 0 : lpc[17] = mac_r( L_tmp, lpcCoeffs[16], s[1] );
1553 0 : move16();
1554 :
1555 0 : scale = sub( getScaleFactor16( lpc, 19 ), SCALEFACTOR16_5 );
1556 :
1557 0 : ptrReal = RealFFT;
1558 0 : ptrImag = ImagFFT;
1559 :
1560 0 : FOR( j = 0; j < 9; j++ )
1561 : {
1562 0 : ptrReal[j * 8] = L_shl( L_deposit_h( lpc[2 * j] ), scale );
1563 0 : move32();
1564 0 : ptrImag[j * 8] = L_shl( L_deposit_h( lpc[2 * j + 1] ), scale );
1565 0 : move32();
1566 : }
1567 0 : ptrReal[j * 8] = L_shl( L_deposit_h( lpc[2 * j] ), scale );
1568 0 : move32();
1569 0 : ptrImag[j * 8] = 0;
1570 0 : move16();
1571 0 : j++;
1572 :
1573 0 : FOR( ; j < 16; j++ )
1574 : {
1575 0 : ptrReal[j * 8] = L_deposit_h( 0 );
1576 0 : move32();
1577 0 : ptrImag[j * 8] = L_deposit_h( 0 );
1578 0 : move32();
1579 : }
1580 :
1581 0 : fft16( ptrReal, ptrImag, 8, 0 );
1582 :
1583 0 : ptrReal++;
1584 0 : ptrImag++;
1585 :
1586 0 : FOR( i = 1; i < 8; i++ )
1587 : {
1588 0 : ptwiddle = w_a[i - 1];
1589 :
1590 0 : ptrReal[0] = L_shl( L_deposit_h( lpc[0] ), scale );
1591 0 : move32();
1592 0 : ptrImag[0] = L_shl( L_deposit_h( lpc[1] ), scale );
1593 0 : move32();
1594 :
1595 0 : FOR( j = 1; j < 9; j++ )
1596 : {
1597 0 : ptrReal[j * 8] = L_shl( L_msu( L_mult( lpc[2 * j], ptwiddle->v.re ), lpc[2 * j + 1], ptwiddle->v.im ), scale );
1598 0 : move32();
1599 0 : ptrImag[j * 8] = L_shl( L_mac( L_mult( lpc[2 * j + 1], ptwiddle->v.re ), lpc[2 * j], ptwiddle->v.im ), scale );
1600 0 : move32();
1601 0 : ptwiddle++;
1602 : }
1603 :
1604 0 : ptrReal[j * 8] = L_shl( L_mac( 0, lpc[2 * j], ptwiddle->v.re ), scale );
1605 0 : move32();
1606 0 : ptrImag[j * 8] = L_shl( L_mac( 0, lpc[2 * j], ptwiddle->v.im ), scale );
1607 0 : move32();
1608 0 : ptwiddle++;
1609 0 : j++;
1610 0 : FOR( ; j < 16; j++ )
1611 : {
1612 0 : ptrReal[j * 8] = L_deposit_h( 0 );
1613 0 : move32();
1614 0 : ptrImag[j * 8] = L_deposit_h( 0 );
1615 0 : move32();
1616 0 : ptwiddle++;
1617 : }
1618 :
1619 0 : fft16( ptrReal, ptrImag, 8, 0 );
1620 :
1621 0 : ptrReal++;
1622 0 : ptrImag++;
1623 : }
1624 :
1625 : /* pre-twiddle */
1626 0 : BASOP_getTables( NULL, &ptwiddle, &step, 128 );
1627 0 : IF( lpcRep != 0 )
1628 : {
1629 0 : pwn17i = &w19N[126];
1630 0 : pwn17 = w19N;
1631 : }
1632 : ELSE
1633 : {
1634 0 : pwn17i = &w18N[126];
1635 0 : pwn17 = w18N;
1636 : }
1637 :
1638 0 : pwn15 = &tmpw15;
1639 0 : pwn15i = &tmpw15;
1640 :
1641 0 : RealOut[0] = round_fx( 2 * L_add( RealFFT[0], ImagFFT[0] ) );
1642 0 : move16();
1643 0 : ImagOut[0] = 0;
1644 0 : move16();
1645 :
1646 0 : RealOut[128] = 0;
1647 0 : move16();
1648 0 : ImagOut[128] = round_fx( L_sub( L_add( RealFFT[0], RealFFT[0] ), L_add( ImagFFT[0], ImagFFT[0] ) ) );
1649 0 : move16();
1650 :
1651 0 : ptwiddle += 8;
1652 0 : FOR( i = 1; i <= N / 2 / 4; i++ )
1653 : {
1654 0 : Word16 ReAr = extract_h( L_add( RealFFT[i], RealFFT[N / 2 - i] ) );
1655 0 : Word16 ReBr = extract_h( L_sub( RealFFT[N / 2 - i], RealFFT[i] ) );
1656 0 : Word16 ImAr = extract_h( L_sub( ImagFFT[i], ImagFFT[N / 2 - i] ) );
1657 0 : Word16 ImBr = extract_h( L_add( ImagFFT[i], ImagFFT[N / 2 - i] ) );
1658 : BASOP_SATURATE_WARNING_OFF_EVS
1659 0 : tmpw15.v.re = mac_ro( L_mult( ptwiddle->v.re, pwn17->v.re ), ptwiddle->v.im, pwn17->v.im, &Overflow );
1660 0 : move16();
1661 0 : tmpw15.v.im = msu_ro( L_mult( ptwiddle->v.re, pwn17->v.im ), ptwiddle->v.im, pwn17->v.re, &Overflow );
1662 0 : move16();
1663 : BASOP_SATURATE_WARNING_ON_EVS
1664 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 );
1665 0 : move16();
1666 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 );
1667 0 : move16();
1668 : BASOP_SATURATE_WARNING_OFF_EVS
1669 0 : tmpw15.v.re = msu_ro( L_mult( ptwiddle->v.im, pwn17i->v.im ), ptwiddle->v.re, pwn17i->v.re, &Overflow );
1670 0 : move16();
1671 0 : tmpw15.v.im = mac_ro( L_mult( ptwiddle->v.re, pwn17i->v.im ), ptwiddle->v.im, pwn17i->v.re, &Overflow );
1672 0 : move16();
1673 : BASOP_SATURATE_WARNING_ON_EVS
1674 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 );
1675 0 : move16();
1676 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 );
1677 0 : move16();
1678 :
1679 0 : ptwiddle += 8;
1680 0 : pwn17++;
1681 0 : pwn17i--;
1682 : }
1683 :
1684 0 : ptwiddle -= 16;
1685 : /*change real with imaginary for ptwiddle*/
1686 0 : FOR( ; i < N / 2 / 2; i++ )
1687 : {
1688 0 : Word16 ReAr = extract_h( L_add( RealFFT[i], RealFFT[N / 2 - i] ) );
1689 0 : Word16 ReBr = extract_h( L_sub( RealFFT[N / 2 - i], RealFFT[i] ) );
1690 0 : Word16 ImAr = extract_h( L_sub( ImagFFT[i], ImagFFT[N / 2 - i] ) );
1691 0 : Word16 ImBr = extract_h( L_add( ImagFFT[i], ImagFFT[N / 2 - i] ) );
1692 : BASOP_SATURATE_WARNING_OFF_EVS
1693 0 : tmpw15.v.re = mac_ro( L_mult( ptwiddle->v.im, pwn17->v.re ), ptwiddle->v.re, pwn17->v.im, &Overflow );
1694 0 : move16();
1695 0 : tmpw15.v.im = msu_ro( L_mult( ptwiddle->v.im, pwn17->v.im ), ptwiddle->v.re, pwn17->v.re, &Overflow );
1696 0 : move16();
1697 : BASOP_SATURATE_WARNING_ON_EVS
1698 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 );
1699 0 : move16();
1700 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 );
1701 0 : move16();
1702 : BASOP_SATURATE_WARNING_OFF_EVS
1703 0 : tmpw15.v.re = msu_ro( L_mult( ptwiddle->v.re, pwn17i->v.im ), ptwiddle->v.im, pwn17i->v.re, &Overflow );
1704 0 : move16();
1705 0 : tmpw15.v.im = mac_ro( L_mult( ptwiddle->v.im, pwn17i->v.im ), ptwiddle->v.re, pwn17i->v.re, &Overflow );
1706 0 : move16();
1707 : BASOP_SATURATE_WARNING_ON_EVS
1708 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 );
1709 0 : move16();
1710 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 );
1711 0 : move16();
1712 :
1713 0 : ptwiddle -= 8;
1714 0 : pwn17++;
1715 0 : pwn17i--;
1716 : }
1717 0 : ptwiddle += 0;
1718 : {
1719 0 : Word16 ReAr = extract_h( L_add( RealFFT[i], RealFFT[N / 2 - i] ) );
1720 0 : Word16 ReBr = extract_h( L_sub( RealFFT[N / 2 - i], RealFFT[i] ) );
1721 0 : Word16 ImAr = extract_h( L_sub( ImagFFT[i], ImagFFT[N / 2 - i] ) );
1722 0 : Word16 ImBr = extract_h( ( L_negate( L_add( ImagFFT[i], ImagFFT[N / 2 - i] ) ) ) );
1723 : BASOP_SATURATE_WARNING_OFF_EVS
1724 0 : tmpw15.v.re = mac_r_sat( L_mult( ptwiddle->v.im, pwn17->v.re ), ptwiddle->v.re, pwn17->v.im );
1725 0 : move16();
1726 0 : tmpw15.v.im = msu_r_sat( L_mult( ptwiddle->v.im, pwn17->v.im ), ptwiddle->v.re, pwn17->v.re );
1727 0 : move16();
1728 : BASOP_SATURATE_WARNING_ON_EVS
1729 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 );
1730 0 : move16();
1731 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 );
1732 0 : move16();
1733 : }
1734 :
1735 0 : spec2isf( RealOut, ImagOut, 128, lsf, old_lsf );
1736 0 : IF( lpcRep == 0 )
1737 : {
1738 0 : lsf[lpcOrder - 1] = shl( lpcCoeffs[lpcOrder], add( norm_s( lpcCoeffs[0] ), 1 ) );
1739 0 : move16(); /* From Qx to Q15 with saturation */
1740 0 : lsf[lpcOrder - 1] = xsp_to_xsf( lsf[lpcOrder - 1] );
1741 0 : move16();
1742 0 : lsf[lpcOrder - 1] = shr( lsf[lpcOrder - 1], 1 );
1743 0 : move16();
1744 : }
1745 0 : }
1746 :
1747 :
1748 1263 : Word16 lev_dur_fx(
1749 : Word32 *a_fx, /* o : LP coefficients (a[0] = 1.0) Q(q_a)*/
1750 : const Word32 *r_fx, /* i : vector of autocorrelations Q(q_r)*/
1751 : const Word16 m, /* i : order of LP filter */
1752 : Word32 epsP[], /* o : prediction error energy Q(q_r)*/
1753 : Word16 q_a,
1754 : Word16 q_r )
1755 : {
1756 : Word16 i, j, l;
1757 : Word16 buf_fx[TCXLTP_LTP_ORDER];
1758 : Word16 *rc_fx; /* reflection coefficients 0,...,m-1 */
1759 : Word32 at;
1760 : Word32 s, err;
1761 1263 : Word16 flag = 0, tmp16;
1762 1263 : move16();
1763 :
1764 1263 : rc_fx = &buf_fx[0];
1765 1263 : rc_fx[0] = divide3232( L_negate( r_fx[1] ), r_fx[0] ); // Q(31)
1766 1263 : move16();
1767 1263 : a_fx[0] = L_shl( 1, q_a );
1768 1263 : move32();
1769 1263 : a_fx[1] = L_shl( rc_fx[0], sub( q_a, 15 ) );
1770 1263 : move32();
1771 1263 : err = L_add( r_fx[0], Mpy_32_16_1( r_fx[1], rc_fx[0] ) ); // Q(q_r)
1772 1263 : IF( epsP != NULL )
1773 : {
1774 0 : epsP[0] = r_fx[0];
1775 0 : move32();
1776 0 : epsP[1] = err;
1777 0 : move32();
1778 : }
1779 :
1780 20208 : FOR( i = 2; i <= m; i++ )
1781 : {
1782 18945 : s = 0; // Q(q_a + q_r - 31)
1783 18945 : move32();
1784 189450 : FOR( j = 0; j < i; j++ )
1785 : {
1786 170505 : s = L_add( s, Mpy_32_32( r_fx[i - j], a_fx[j] ) ); // Q(q_a + q_r - 31)
1787 : }
1788 :
1789 18945 : rc_fx[i - 1] = divide3232( L_negate( s ), L_shr( err, sub( 31, q_a ) ) ); // Q15
1790 18945 : move16();
1791 :
1792 18945 : if ( GT_16( abs_s( rc_fx[i - 1] ), 32749 ) ) // 32749 = 0.99945 in Q15
1793 : {
1794 0 : flag = 1; /* Test for unstable filter. If unstable keep old A(z) */
1795 0 : move16();
1796 : }
1797 :
1798 18945 : tmp16 = shr( i, 1 );
1799 99777 : FOR( j = 1; j <= tmp16; j++ )
1800 : {
1801 80832 : l = sub( i, j );
1802 80832 : at = L_add( a_fx[j], Mpy_32_16_1( a_fx[l], rc_fx[i - 1] ) ); // Q(q_a)
1803 80832 : a_fx[l] = L_add( a_fx[l], Mpy_32_16_1( a_fx[j], rc_fx[i - 1] ) ); // Q(q_a)
1804 80832 : move32();
1805 80832 : a_fx[j] = at;
1806 80832 : move32();
1807 : }
1808 :
1809 18945 : a_fx[i] = L_shl( rc_fx[i - 1], sub( q_a, 15 ) ); // Q(q_a)
1810 18945 : move32();
1811 :
1812 18945 : err = L_add( err, L_shl( Mpy_32_16_1( s, rc_fx[i - 1] ), sub( 31, q_a ) ) ); // q_err - q_s
1813 18945 : IF( err <= 0 )
1814 : {
1815 0 : err = L_shr( 327, sub( 31, q_r ) ); // 327 = 0.01 in Q15
1816 : }
1817 :
1818 18945 : if ( epsP != NULL )
1819 : {
1820 0 : epsP[i] = err;
1821 0 : move32();
1822 : }
1823 : }
1824 :
1825 1263 : return ( flag );
1826 : }
|