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 : #include <stdint.h>
34 : #include <assert.h>
35 : #include "options.h" /* Compilation switches */
36 : #include "basop_util.h"
37 : #include "rom_com.h"
38 : #include "ivas_cnst.h"
39 : #include "prot_fx.h"
40 : #include "ivas_error.h"
41 : #include "ivas_prot_fx.h"
42 :
43 : /*-------------------------------------------------------------------*
44 : * Local constants
45 : *-------------------------------------------------------------------*/
46 : #define NC_MAX 8
47 : #define GUESS_TBL_SZ 256
48 :
49 : #define depack_4_values( cbp, val0, val1, val2, val3 ) \
50 : val0 = shr( ( cbp )[0], 4 ); \
51 : val1 = shr( ( cbp )[1], 4 ); \
52 : val2 = shr( ( cbp )[2], 4 ); \
53 : val3 = add( add( shr( lshl( ( cbp )[2], 12 ), 4 ), lshr( lshl( ( cbp )[1], 12 ), 8 ) ), s_and( ( cbp )[0], 0xF ) );
54 :
55 : #define SPC 0.0234952f
56 : #define SPC_plus SPC * 1.001f
57 : /*-------------------------------------------------------------------*
58 : * Local functions
59 : *-------------------------------------------------------------------*/
60 : Word16 root_search_fx( Word16 low, Word16 high, Word32 *v_low, Word32 *coef, Word16 order );
61 : Word32 calc_weight( Word16 delta1, Word16 delta2, Word16 *n1 );
62 : Word32 polynomial_eval_fx( Word16 f, Word32 *coef, Word16 order );
63 : void E_LPC_isf_isp_conversion( const Word16 isf[], Word16 isp[], const Word16 m );
64 : void E_LPC_lsp_lsf_conversion( const Word16 lsp[], Word16 lsf[], const Word16 m );
65 : Word16 E_LPC_f_lsp_pol_get( const Word16 lsp[], Word32 f[], const Word16 n, const Word16 past_Ovf, const Word16 isMODE1 );
66 :
67 3191287 : static Word16 chebyshev( Word16 x, Word32 *f, const Word16 n, const Word16 shift )
68 : {
69 :
70 : Word16 cheb;
71 : Word32 t0, b1, b2;
72 : #ifndef ISSUE_1836_replace_overflow_libcom
73 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
74 : Flag Overflow = 0;
75 : #endif
76 : #endif
77 :
78 3191287 : cheb = norm_s( x );
79 3191287 : if ( cheb )
80 : {
81 1088484 : x = shl( x, 1 );
82 : }
83 3191287 : t0 = Mpy_32_16_1( *f++, x ); /* t0 = x*b2 */
84 3191287 : if ( !cheb )
85 2102803 : t0 = L_shl( t0, 1 ); /* t0 = 2*x*b2 */
86 3191287 : b1 = L_add( t0, *f++ ); /* b1 = 2*x*b2 + f[1] */
87 :
88 : /* i = 2 */
89 3191287 : t0 = Mpy_32_16_1( b1, x ); /* t0 = x*b1 */
90 3191287 : if ( !cheb )
91 2102803 : t0 = L_shl( t0, 1 ); /* t0 = 2*x*b1 */
92 3191287 : b2 = L_add( t0, *f++ ); /* b0 = 2*x*b1 - b2 + f[i] */
93 :
94 : /* i = 3 */
95 3191287 : t0 = Mpy_32_16_1( b2, x ); /* t0 = x*b1 */
96 3191287 : if ( !cheb )
97 2102803 : t0 = L_shl( t0, 1 ); /* t0 = 2*x*b1 */
98 3191287 : t0 = L_sub( t0, b1 ); /* t0 = 2*x*b1 - b2 */
99 3191287 : b1 = L_add( t0, *f++ ); /* b0 = 2*x*b1 - b2 + f[i] */
100 :
101 : /* i = 4 */
102 3191287 : t0 = Mpy_32_16_1( b1, x ); /* t0 = x*b1 */
103 3191287 : if ( !cheb )
104 2102803 : t0 = L_shl( t0, 1 ); /* t0 = 2*x*b1 */
105 3191287 : t0 = L_sub( t0, b2 ); /* t0 = 2*x*b1 - b2 */
106 :
107 : /* If the LP order is greater than 10 */
108 3191287 : IF( GT_16( n, 5 ) )
109 : {
110 3191287 : b2 = L_add( t0, *f++ ); /* b0 = 2*x*b1 - b2 + f[i] */
111 : /* i = 5 */
112 3191287 : t0 = Mpy_32_16_1( b2, x ); /* t0 = x*b1 */
113 : #ifdef ISSUE_1836_replace_overflow_libcom
114 3191287 : if ( !cheb )
115 2102803 : t0 = L_shl_sat( t0, 1 ); /* t0 = 2*x*b1 */
116 : #else
117 : if ( !cheb )
118 : t0 = L_shl_o( t0, 1, &Overflow ); /* t0 = 2*x*b1 */
119 : #endif
120 3191287 : t0 = L_sub( t0, b1 ); /* t0 = 2*x*b1 - b2 */
121 3191287 : b1 = L_add( t0, *f++ ); /* b0 = 2*x*b1 - b2 + f[i] */
122 :
123 : /* i = 6 */
124 3191287 : t0 = Mpy_32_16_1( b1, x ); /* t0 = x*b1 */
125 : #ifdef ISSUE_1836_replace_overflow_libcom
126 3191287 : if ( !cheb )
127 2102803 : t0 = L_shl_sat( t0, 1 ); /* t0 = 2*x*b1 */
128 : #else
129 : if ( !cheb )
130 : t0 = L_shl_o( t0, 1, &Overflow ); /* t0 = 2*x*b1 */
131 : #endif
132 3191287 : t0 = L_sub( t0, b2 ); /* t0 = 2*x*b1 - b2 */
133 : }
134 : /* IF (sub(n,8) == 0) */
135 3191287 : IF( n == 8 )
136 : {
137 3191287 : b2 = L_add( t0, *f++ ); /* b0 = 2*x*b1 - b2 + f[i] */
138 : /* i = 7 */
139 3191287 : t0 = Mpy_32_16_1( b2, x ); /* t0 = x*b1 */
140 : #ifdef ISSUE_1836_replace_overflow_libcom
141 3191287 : if ( !cheb )
142 2102803 : t0 = L_shl_sat( t0, 1 ); /* t0 = 2*x*b1 */
143 : #else
144 : if ( !cheb )
145 : t0 = L_shl_o( t0, 1, &Overflow ); /* t0 = 2*x*b1 */
146 : #endif
147 3191287 : t0 = L_sub( t0, b1 ); /* t0 = 2*x*b1 - b2 */
148 : /*b1 = L_add(b2,0);*/
149 : }
150 : ELSE
151 : {
152 0 : b2 = b1;
153 0 : move32();
154 : }
155 :
156 3191287 : t0 /*b2*/ = L_add( t0, *f++ ); /* b0 = 2*x*b1 - b2 + f[i] */
157 :
158 3191287 : t0 = Mpy_32_16_1( t0 /*b2*/, x ); /* t0 = x*b1 */
159 3191287 : if ( cheb )
160 1088484 : t0 = L_shr( t0, 1 );
161 3191287 : t0 = L_sub( t0, /*b1*/ b2 ); /* t0 = x*b1 - b2 */
162 3191287 : t0 = L_add( t0, *f++ ); /* t0 = x*b1 - b2 + 0.5*f[n] */
163 :
164 :
165 : BASOP_SATURATE_WARNING_OFF_EVS
166 : #ifdef ISSUE_1836_replace_overflow_libcom
167 3191287 : t0 = L_shl_sat( t0, shift ); /* Qx to Q30 with saturation */
168 3191287 : cheb = round_fx_sat( t0 ); /* Result in Q14 */
169 : #else
170 : t0 = L_shl_o( t0, shift, &Overflow ); /* Qx to Q30 with saturation */
171 : cheb = round_fx_o( t0, &Overflow ); /* Result in Q14 */
172 : #endif
173 3191287 : cheb = s_max( -32767, cheb ); /* to avoid saturation */
174 : BASOP_SATURATE_WARNING_ON_EVS
175 3191287 : return ( cheb );
176 : }
177 :
178 0 : void E_LPC_a_isp_conversion( const Word16 a[], Word16 isp[], const Word16 old_isp[], const Word16 m )
179 : {
180 : Word16 i, nf, ip, order, nc;
181 : Word16 xlow, ylow, xhigh, yhigh;
182 : Word16 x, y, tmp, exp;
183 : Word32 f[2][NC_MAX + 1];
184 : Word32 t0, t1;
185 0 : Word16 scale = 1024;
186 0 : move16();
187 : #ifndef ISSUE_1836_replace_overflow_libcom
188 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
189 : Flag Overflow = 0;
190 : #endif
191 : #endif
192 :
193 : /*-------------------------------------------------------------*
194 : * find the sum and diff polynomials F1(z) and F2(z)
195 : * F1(z) = [A(z) + z^M A(z^-1)]
196 : * F2(z) = [A(z) - z^M A(z^-1)]/(1-z^-2)
197 : *
198 : * for (i=0; i<NC; i++)
199 : * {
200 : * f1[i] = a[i] + a[m-i];
201 : * f2[i] = a[i] - a[m-i];
202 : * }
203 : * f1[NC] = 2.0*a[NC];
204 : *
205 : * for (i=2; i<NC; i++) Divide by (1-z^-2)
206 : * f2[i] += f2[i-2];
207 : *-------------------------------------------------------------*/
208 0 : nc = shr( m, 1 );
209 :
210 0 : scale = shl( 256, norm_s( a[0] ) );
211 :
212 0 : FOR( i = 0; i < nc; i++ )
213 : {
214 0 : t0 = L_mult( a[i], scale ); /*Q23*/
215 0 : t1 = L_mult( a[m - i], scale ); /*Q23*/
216 0 : f[0][i] = L_add( t0, t1 );
217 0 : move32(); /*Q23*/
218 0 : f[1][i] = L_sub( t0, t1 );
219 0 : move32(); /*Q23*/
220 : }
221 0 : f[0][nc] = L_mult( a[nc], scale );
222 0 : move32(); /*Q23-1*/
223 :
224 0 : FOR( i = 2; i < nc; i++ )
225 : {
226 0 : f[1][i] = L_add( f[1][i], f[1][i - 2] );
227 0 : move32();
228 : }
229 : /* f[1][nc] = L_shr(f[1][nc],1); move32(); */
230 0 : f[1][nc - 1] = L_shr( f[1][nc - 1], 1 );
231 0 : move32();
232 :
233 0 : f[0][2] = L_sub( f[0][2], f[0][0] );
234 0 : move32();
235 0 : f[1][2] = L_sub( f[1][2], f[1][0] );
236 0 : move32();
237 :
238 :
239 : /*----------------------------------------------------------------*
240 : * Find the ISPs (roots of F1(z) and F2(z) ) using the
241 : * Chebyshev polynomial evaluation.
242 : * The roots of F1(z) and F2(z) are alternatively searched.
243 : * We start by finding the first root of F1(z) then we switch_fx
244 : * to F2(z) then back to F1(z) and so on until all roots are found.
245 : *
246 : * - Evaluate Chebyshev pol. at grid points and check for sign change.
247 : * - If sign change track the root by subdividing the interval
248 : * 2 times and ckecking sign change.
249 : *----------------------------------------------------------------*/
250 :
251 0 : nf = 0;
252 0 : move16(); /* number of found frequencies */
253 0 : ip = 0;
254 0 : move16(); /* indicator for f1 or f2 */
255 :
256 0 : order = nc;
257 0 : move16();
258 :
259 0 : xlow = Grid[0];
260 0 : move16();
261 0 : ylow = chebyshev( xlow, f[ip], order, 7 );
262 :
263 0 : FOR( i = 1; i <= GRID100_POINTS; i++ )
264 : {
265 0 : xhigh = xlow;
266 0 : move16();
267 0 : yhigh = ylow;
268 0 : move16();
269 0 : xlow = Grid[i];
270 0 : move16();
271 0 : ylow = chebyshev( xlow, f[ip], order, 7 );
272 :
273 0 : IF( L_mult( ylow, yhigh ) <= 0 )
274 : {
275 0 : t0 = L_mult( xhigh, 0x4000 );
276 : /* divide 2 times the interval */
277 0 : x = mac_r( t0, xlow, 0x4000 ); /* xmid = (xlow + xhigh)/2 */
278 0 : y = chebyshev( x, f[ip], order, 7 );
279 :
280 0 : IF( L_mult( ylow, y ) <= 0 )
281 : {
282 0 : yhigh = y;
283 0 : move16();
284 0 : xhigh = x;
285 0 : move16();
286 0 : y = ylow;
287 0 : move16();
288 0 : x = xlow;
289 0 : move16();
290 : /* 'xhigh' has changed, update 't0' */
291 0 : t0 = L_mult( xhigh, 0x4000 );
292 : }
293 0 : xlow = mac_r( t0, x, 0x4000 ); /* xlow = (x + xhigh)/2 */
294 0 : ylow = chebyshev( xlow, f[ip], order, 7 );
295 :
296 0 : IF( L_mult( y, ylow ) <= 0 )
297 : {
298 0 : yhigh = ylow;
299 0 : move16();
300 0 : xhigh = xlow;
301 0 : move16();
302 0 : ylow = y;
303 0 : move16();
304 0 : xlow = x;
305 0 : move16();
306 : }
307 :
308 : /*--------------------------------------------------------*
309 : * Linear interpolation
310 : * xint = xlow - ylow*(xhigh-xlow)/(yhigh-ylow)
311 : *--------------------------------------------------------*/
312 :
313 : #ifdef ISSUE_1836_replace_overflow_libcom
314 0 : y = sub_sat( yhigh, ylow );
315 : #else
316 : y = sub_o( yhigh, ylow, &Overflow );
317 : #endif
318 0 : IF( y != 0 )
319 : {
320 0 : x = sub( xhigh, xlow );
321 :
322 0 : tmp = abs_s( y );
323 0 : exp = norm_s( tmp );
324 0 : if ( exp )
325 0 : tmp = shl( tmp, exp );
326 0 : tmp = div_s( (Word16) 16383, tmp );
327 0 : t0 = L_mult( x, tmp );
328 0 : t0 = L_shr( t0, sub( 20, exp ) );
329 0 : tmp = extract_l( t0 ); /* y = (xhigh-xlow)/(yhigh-ylow) in Q11 */
330 :
331 : /* Restore Sign */
332 0 : if ( y < 0 )
333 0 : tmp = negate( tmp );
334 :
335 0 : t0 = L_mult( ylow, tmp ); /* result in Q26 */
336 0 : t0 = L_shr( t0, 11 ); /* result in Q15 */
337 0 : xlow = sub( xlow, extract_l( t0 ) ); /* xint = xlow - ylow*y */
338 : }
339 :
340 0 : isp[nf++] = xlow;
341 0 : move16();
342 :
343 0 : IF( GE_16( nf, ( m - 1 ) ) )
344 : {
345 0 : BREAK;
346 : }
347 :
348 0 : ip = s_xor( ip, 1 );
349 0 : order = sub( nc, ip );
350 0 : ylow = chebyshev( xlow, f[ip], order, 7 );
351 : }
352 : }
353 :
354 : /*----------------------------------------------------------------*
355 : * Check if m-1 roots found, if not use the ISPs from previous frame
356 : *----------------------------------------------------------------*/
357 :
358 0 : isp[m - 1] = shl( a[m], add( norm_s( a[0] ), 1 ) );
359 0 : move16(); /* From Qx to Q15 with saturation */
360 :
361 0 : IF( s_min( sub( nf, m - 1 ), sub( 8192, abs_s( a[m] ) ) ) < 0 )
362 : {
363 0 : FOR( i = 0; i < m; i++ )
364 : {
365 0 : isp[i] = old_isp[i];
366 0 : move16();
367 : }
368 : }
369 0 : }
370 :
371 : /*
372 : * E_LPC_f_isp_a_conversion
373 : *
374 : * Parameters:
375 : * isp I: Immittance spectral pairs Q15
376 : * a O: Predictor coefficients (order = m) Q12
377 : * m I: order of LP filter
378 : *
379 : * Function:
380 : * Convert ISPs to predictor coefficients a[]
381 : *
382 : * Returns:
383 : * void
384 : */
385 0 : void E_LPC_f_isp_a_conversion( const Word16 *isp, Word16 *a, const Word16 m )
386 : {
387 : Word16 i, j;
388 : Word32 f1[NC_MAX + 1], f2[NC_MAX + 1]; /* Q23 */
389 : Word16 nc, q;
390 : Word32 t0, tmax, t0p, t0n;
391 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
392 0 : Flag Overflow = 0;
393 : #endif
394 :
395 :
396 : /*-----------------------------------------------------*
397 : * Find the polynomials F1(z) and F2(z) *
398 : *-----------------------------------------------------*/
399 :
400 0 : nc = shr( m, 1 );
401 :
402 0 : E_LPC_f_lsp_pol_get( &isp[0], f1, nc, 0, 0 );
403 0 : E_LPC_f_lsp_pol_get( &isp[1], f2, sub( nc, 1 ), 0, 0 );
404 : /*-----------------------------------------------------*
405 : * Multiply F2(z) by (1 - z^-2) *
406 : *-----------------------------------------------------*/
407 :
408 0 : FOR( i = sub( nc, 1 ); i > 1; i-- )
409 : {
410 : /* f2[i] -= f2[i-2]; */
411 0 : f2[i] = L_sub( f2[i], f2[i - 2] );
412 0 : move32();
413 : }
414 :
415 : /*----------------------------------------------------------*
416 : * Scale F1(z) by (1+isp[m-1]) and F2(z) by (1-isp[m-1]) *
417 : *----------------------------------------------------------*/
418 :
419 0 : FOR( i = 0; i < nc; i++ )
420 : {
421 : /* f1[i] *= (1.0 + isp[m-1]); */
422 0 : f1[i] = Madd_32_16( f1[i], f1[i], isp[m - 1] );
423 0 : move32();
424 :
425 : /* f2[i] *= (1.0 - isp[m-1]); */
426 0 : f2[i] = Msub_32_16( f2[i], f2[i], isp[m - 1] );
427 0 : move32();
428 : }
429 :
430 : /*-----------------------------------------------------*
431 : * A(z) = (F1(z)+F2(z))/2 *
432 : * F1(z) is symmetric and F2(z) is antisymmetric *
433 : *-----------------------------------------------------*/
434 :
435 : /* Maximum LPC */
436 0 : tmax = L_deposit_l( 1 );
437 0 : FOR( i = 1; i < nc; i++ )
438 : {
439 0 : t0 = L_add( f1[i], f2[i] );
440 0 : tmax = L_max( tmax, L_abs( t0 ) );
441 0 : t0 = L_sub( f1[i], f2[i] );
442 0 : tmax = L_max( tmax, L_abs( t0 ) );
443 : }
444 0 : q = s_min( norm_l( tmax ), 6 );
445 :
446 : DO
447 : {
448 0 : test();
449 : /* a[0] = 1.0 */
450 0 : a[0] = shl( 256, q );
451 0 : move16();
452 :
453 0 : j = sub( m, 1 );
454 0 : FOR( i = 1; i < nc; i++ )
455 : {
456 : /* a[i] = 0.5*(f1[i] + f2[i]) */
457 0 : t0 = L_add( f1[i], f2[i] ); /* f1[i] + f2[i] */
458 0 : t0 = L_shl( t0, q );
459 0 : a[i] = round_fx_sat( t0 ); /* from Q23 to Q12 and * 0.5 */
460 0 : move16();
461 :
462 : /* a[j] = 0.5*(f1[i] - f2[i]) */
463 0 : t0 = L_sub( f1[i], f2[i] ); /* f1[i] - f2[i] */
464 0 : t0 = L_shl( t0, q );
465 0 : a[j] = round_fx_sat( t0 ); /* from Q23 to Q12 and * 0.5 */
466 0 : move16();
467 :
468 0 : j = sub( j, 1 );
469 : }
470 :
471 : /* a[NC] = 0.5*f1[NC]*(1.0 + isp[m-1]) */
472 0 : t0 = Madd_32_16( f1[nc], f1[nc], isp[m - 1] );
473 :
474 : BASOP_SATURATE_WARNING_OFF_EVS /*overflow handling in loop expression*/
475 :
476 0 : t0 = L_shl_o( t0, q, &Overflow );
477 0 : t0n = L_sub_o( t0, 0x7FFFFFFF, &Overflow ); /*check for positive overflow*/
478 0 : t0p = L_sub_o( t0, 0x80000000, &Overflow ); /*check for negative overflow*/
479 : BASOP_SATURATE_WARNING_ON_EVS
480 :
481 0 : q = sub( q, 1 ); /*decrease q in case of overflow*/
482 : }
483 0 : WHILE( t0n == 0 || t0p == 0 ); /*in case of overflow, recalculate coefficients*/
484 :
485 0 : a[nc] = round_fx_sat( t0 ); /* from Q23 to Q12 and * 0.5 */
486 0 : move16();
487 : /* a[m] = isp[m-1] */
488 0 : t0 = L_mult( a[0], isp[m - 1] ); /* from Q15 to Q12 */
489 0 : a[m] = round_fx_sat( t0 );
490 0 : move16();
491 :
492 0 : return;
493 : }
494 :
495 : /*===================================================================*/
496 : /* FUNCTION : lpc2lsp_fx () */
497 : /*-------------------------------------------------------------------*/
498 : /* PURPOSE : Convert LPC coefficients to LSP coefficients */
499 : /*-------------------------------------------------------------------*/
500 : /* INPUT ARGUMENTS : */
501 : /* */
502 : /* _ (Word32 []) a : LPC coefficients, Q27 */
503 : /* _ (Word16 []) old_freq: Previous frame LSP coefficients, Q15 */
504 : /* _ (Word16 []) order: LPC order */
505 : /*-------------------------------------------------------------------*/
506 : /* OUTPUT ARGUMENTS : */
507 : /* _ (Word16 []) freq: LSP coefficients, Q15 */
508 : /*-------------------------------------------------------------------*/
509 : /* INPUT/OUTPUT ARGUMENTS : */
510 : /* _ None */
511 : /*-------------------------------------------------------------------*/
512 : /* RETURN ARGUMENTS : */
513 : /* _ (Word16) flag: 1 means all 10 LSPs are found, 0 otherwise */
514 : /*===================================================================*/
515 0 : Word16 lpc2lsp_fx(
516 : Word32 *a,
517 : Word16 *freq,
518 : Word16 *old_freq,
519 : Word16 order )
520 : {
521 : Word16 i;
522 : Word16 rt, low, high, prev_rt, rc;
523 : Word32 p[11], q[11]; /* Q26 */
524 : Word32 Ltemp, v_low;
525 : Word32 Lacc;
526 : Word16 tfreq[21];
527 :
528 : /* First construct the P,Q polynomial */
529 : /* p[0] = q[0] = 1 */
530 : /* p[i] = -lpcCoeff[i] - lpcCoeff[11-i] - p[i-1] ( 1<=i<=5)*/
531 : /* q[i] = -lpcCoeff[i] + lpcCoeff[11-i] + q[i-1] ( 1<=i<=5)*/
532 0 : Ltemp = L_deposit_h( 0x400 ); /* Ltemp is 1.0 in Q26 */
533 :
534 0 : p[0] = Ltemp;
535 0 : move32();
536 0 : q[0] = Ltemp;
537 0 : move32();
538 :
539 0 : FOR( i = 1; i < ( order / 2 ) + 1; i++ )
540 : {
541 0 : Lacc = a[order - i];
542 0 : move32(); /* Q27 */
543 0 : Lacc = L_sub( Lacc, a[i - 1] ); /* Lacc=-lpcCoeff[i-1] + lpcCoeff[order-i]//Q27 */
544 0 : q[i] = L_add( L_shr( Lacc, 1 ), q[i - 1] );
545 0 : move32(); /* Q26 */
546 :
547 0 : Lacc = L_add( Lacc, L_shl( a[i - 1], 1 ) ); /* Lacc=lpcCoeff[i-1] + lpcCoeff[order-i]//Q27 */
548 :
549 0 : p[i] = L_sub( L_negate( L_shr( Lacc, 1 ) ), p[i - 1] );
550 0 : move32(); /* Q26 */
551 : }
552 :
553 : /* Search roots of the P and Q polynomials */
554 :
555 0 : v_low = polynomial_eval_fx( 0, p, order ); /* Q25 */
556 0 : move16();
557 0 : move16();
558 0 : move16();
559 0 : move16();
560 0 : low = 0;
561 0 : high = 8;
562 0 : prev_rt = 0;
563 0 : rc = 0; /* root counter */
564 0 : FOR( i = 0; i < 32; i++ )
565 : {
566 0 : rt = root_search_fx( low, high, &v_low, p, order );
567 0 : low = high;
568 0 : move16();
569 0 : high = add( high, 8 );
570 :
571 0 : IF( GE_16( rt, prev_rt ) )
572 : {
573 0 : tfreq[rc] = rt;
574 0 : move16();
575 0 : rc = add( rc, 2 );
576 : }
577 0 : prev_rt = add( rt, 6 );
578 : } /* End for P roots */
579 :
580 0 : tfreq[rc] = 0x3f80;
581 0 : move16(); /* Set a high enough value as fake root for Q search */
582 :
583 0 : IF( LT_16( rc, order ) )
584 : {
585 : /* lost P root */
586 : /* copy from previous LSP and return */
587 0 : FOR( i = 0; i < order; i++ )
588 : {
589 0 : move16();
590 0 : freq[i] = old_freq[i];
591 : }
592 0 : return ( 0 );
593 : }
594 : ELSE
595 : {
596 : /* Search for Q roots between P roots */
597 0 : v_low = L_deposit_h( 0x800 ); /* Init a positive value for v_low */
598 0 : rc = 1;
599 0 : move16();
600 0 : FOR( i = 0; i < order / 2; i++ )
601 : {
602 0 : low = shr( tfreq[rc - 1], 6 );
603 0 : high = add( shr( tfreq[rc + 1], 6 ), 1 );
604 0 : rt = root_search_fx( low, high, &v_low, q, order );
605 :
606 0 : IF( rt < 0 )
607 : {
608 : /* No Q root in this interval */
609 : /* copy from previous LSP and return */
610 0 : FOR( i = 0; i < order; i++ )
611 : {
612 0 : move16();
613 0 : freq[i] = old_freq[i];
614 : }
615 0 : return ( 0 );
616 : }
617 : ELSE
618 : {
619 0 : move16();
620 0 : tfreq[rc] = rt;
621 0 : rc = add( rc, 2 );
622 : } /* end else, find Q root */
623 : } /* end for */
624 : } /* end else */
625 :
626 0 : FOR( i = 0; i < order; i++ )
627 : {
628 0 : freq[i] = tfreq[i];
629 0 : move16();
630 : }
631 :
632 0 : return ( 1 );
633 : }
634 :
635 : /*===================================================================*/
636 : /* FUNCTION : lpc2lsp_ivas_fx () */
637 : /*-------------------------------------------------------------------*/
638 : /* PURPOSE : Convert LPC coefficients to LSP coefficients */
639 : /*-------------------------------------------------------------------*/
640 : /* INPUT ARGUMENTS : */
641 : /* */
642 : /* _ (Word32 []) a : LPC coefficients, Q27 */
643 : /* _ (Word16 []) old_freq: Previous frame LSP coefficients, Q15 */
644 : /* _ (Word16 []) order: LPC order */
645 : /*-------------------------------------------------------------------*/
646 : /* OUTPUT ARGUMENTS : */
647 : /* _ (Word16 []) freq: LSP coefficients, Q15 */
648 : /*-------------------------------------------------------------------*/
649 : /* INPUT/OUTPUT ARGUMENTS : */
650 : /* _ None */
651 : /*-------------------------------------------------------------------*/
652 : /* RETURN ARGUMENTS : */
653 : /* _ (Word16) flag: 1 means all 10 LSPs are found, 0 otherwise */
654 : /*===================================================================*/
655 :
656 : /*NOTE: This function was created to avoid a crash that happens in the*/
657 : /* first for loop of this function while performing L_shl on a in*/
658 : /* lpc2lsp_fx, this computation assigns value to Lacc, which is */
659 : /* kept in Q26 here to avoid L_shl when a has saturated value. */
660 0 : Word16 lpc2lsp_ivas_fx(
661 : Word32 *a,
662 : Word16 *freq,
663 : Word16 *old_freq,
664 : Word16 order )
665 : {
666 : Word16 i;
667 : Word16 rt, low, high, prev_rt, rc;
668 : Word32 p[11], q[11]; /* Q26 */
669 : Word32 Ltemp, v_low;
670 : Word32 Lacc;
671 : Word16 tfreq[21];
672 :
673 : /* First construct the P,Q polynomial */
674 : /* p[0] = q[0] = 1 */
675 : /* p[i] = -lpcCoeff[i] - lpcCoeff[11-i] - p[i-1] ( 1<=i<=5)*/
676 : /* q[i] = -lpcCoeff[i] + lpcCoeff[11-i] + q[i-1] ( 1<=i<=5)*/
677 0 : Ltemp = L_deposit_h( 0x400 ); /* Ltemp is 1.0 in Q26 */
678 :
679 0 : p[0] = Ltemp;
680 0 : move32();
681 0 : q[0] = Ltemp;
682 0 : move32();
683 :
684 0 : FOR( i = 1; i < ( order / 2 ) + 1; i++ )
685 : {
686 0 : Lacc = L_shr( a[order - i], 1 );
687 0 : move32(); /* Q26 */
688 0 : Lacc = L_sub( Lacc, L_shr( a[i - 1], 1 ) ); /* Lacc=-lpcCoeff[i-1] + lpcCoeff[order-i]//Q26 */
689 0 : q[i] = L_add( ( Lacc ), q[i - 1] );
690 0 : move32(); /* Q26 */
691 :
692 0 : Lacc = L_add( Lacc, a[i - 1] ); /* Lacc=lpcCoeff[i-1] + lpcCoeff[order-i]//Q26 */
693 :
694 0 : p[i] = L_sub( L_negate( Lacc ), p[i - 1] );
695 0 : move32(); /* Q26 */
696 : }
697 :
698 : /* Search roots of the P and Q polynomials */
699 :
700 0 : v_low = polynomial_eval_fx( 0, p, order ); /* Q25 */
701 0 : move16();
702 0 : move16();
703 0 : move16();
704 0 : move16();
705 0 : low = 0;
706 0 : high = 8;
707 0 : prev_rt = 0;
708 0 : rc = 0; /* root counter */
709 0 : FOR( i = 0; i < 32; i++ )
710 : {
711 0 : rt = root_search_fx( low, high, &v_low, p, order );
712 0 : low = high;
713 0 : move16();
714 0 : high = add( high, 8 );
715 :
716 0 : IF( GE_16( rt, prev_rt ) )
717 : {
718 0 : tfreq[rc] = rt;
719 0 : move16();
720 0 : rc = add( rc, 2 );
721 : }
722 0 : prev_rt = add( rt, 6 );
723 : } /* End for P roots */
724 :
725 0 : tfreq[rc] = 0x3f80;
726 0 : move16(); /* Set a high enough value as fake root for Q search */
727 :
728 0 : IF( LT_16( rc, order ) )
729 : {
730 : /* lost P root */
731 : /* copy from previous LSP and return */
732 0 : FOR( i = 0; i < order; i++ )
733 : {
734 0 : move16();
735 0 : freq[i] = old_freq[i];
736 : }
737 0 : return ( 0 );
738 : }
739 : ELSE
740 : {
741 : /* Search for Q roots between P roots */
742 0 : v_low = L_deposit_h( 0x800 ); /* Init a positive value for v_low */
743 0 : rc = 1;
744 0 : move16();
745 0 : FOR( i = 0; i < order / 2; i++ )
746 : {
747 0 : low = shr( tfreq[rc - 1], 6 );
748 0 : high = add( shr( tfreq[rc + 1], 6 ), 1 );
749 0 : rt = root_search_fx( low, high, &v_low, q, order );
750 :
751 0 : IF( rt < 0 )
752 : {
753 : /* No Q root in this interval */
754 : /* copy from previous LSP and return */
755 0 : FOR( i = 0; i < order; i++ )
756 : {
757 0 : move16();
758 0 : freq[i] = old_freq[i];
759 : }
760 0 : return ( 0 );
761 : }
762 : ELSE
763 : {
764 0 : move16();
765 0 : tfreq[rc] = rt;
766 0 : rc = add( rc, 2 );
767 : } /* end else, find Q root */
768 : } /* end for */
769 : } /* end else */
770 :
771 0 : FOR( i = 0; i < order; i++ )
772 : {
773 0 : freq[i] = tfreq[i];
774 0 : move16();
775 : }
776 :
777 0 : return ( 1 );
778 : }
779 :
780 : /*===================================================================*/
781 : /* FUNCTION : lsp2lpc_fx () */
782 : /*-------------------------------------------------------------------*/
783 : /* PURPOSE : Convert LSP coefficients to LPC coefficients */
784 : /*-------------------------------------------------------------------*/
785 : /* INPUT ARGUMENTS : */
786 : /* */
787 : /* _ (Word16 []) freq: LSP coefficients, Q15 */
788 : /* _ (Word16 []) prev_a : previous frame LPC coefficients, Q12 */
789 : /* _ (Word16 []) order : LPC order */
790 : /*-------------------------------------------------------------------*/
791 : /* OUTPUT ARGUMENTS : */
792 : /* _ (Word16 []) a : LPC coefficients, Q12 */
793 : /*-------------------------------------------------------------------*/
794 : /* INPUT/OUTPUT ARGUMENTS : */
795 : /* _ None */
796 : /*-------------------------------------------------------------------*/
797 : /* RETURN ARGUMENTS : */
798 : /* _ None */
799 : /*===================================================================*/
800 6909 : void lsp2lpc_fx(
801 : Word16 *a,
802 : Word16 *freq,
803 : Word16 *prev_a,
804 : Word16 order )
805 : {
806 : Word16 i;
807 : Word32 pq[LPC_SHB_ORDER];
808 : Word32 p[LPC_SHB_ORDER], q[LPC_SHB_ORDER];
809 : Word32 Ltemp;
810 : Word32 Lacc;
811 : Word16 tmp_pci[M + 1];
812 : Word16 giOverflow;
813 :
814 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
815 6909 : Flag Overflow = 0;
816 : #endif
817 :
818 43483 : FOR( i = 0; i < order; i++ )
819 : {
820 36574 : tmp_pci[i] = prev_a[i];
821 36574 : move16();
822 : }
823 :
824 6909 : compute_poly_product_fx( freq, pq, order );
825 : /*This change is to get funtionality if L_sub_sat*/
826 6909 : giOverflow = 0;
827 6909 : move16(); /* clear overflow flag */
828 6909 : Overflow = 0;
829 6909 : move16();
830 25196 : FOR( i = 0; i < order / 2; i++ )
831 : {
832 18287 : Ltemp = L_add_o( pq[i], pq[i + 1], &Overflow );
833 18287 : giOverflow = (Word16) Overflow;
834 18287 : move16();
835 18287 : IF( EQ_16( giOverflow, 1 ) )
836 : {
837 0 : BREAK;
838 : }
839 :
840 18287 : p[i] = Ltemp;
841 18287 : move32();
842 : }
843 :
844 6909 : IF( EQ_16( giOverflow, 1 ) )
845 : {
846 0 : FOR( i = 0; i < order; i++ )
847 : {
848 0 : a[i] = mult_r( prev_a[i], pwAlpha[i] );
849 0 : move16();
850 : }
851 0 : return;
852 : }
853 :
854 6909 : compute_poly_product_fx( freq + 1, pq, order );
855 :
856 :
857 6909 : giOverflow = 0;
858 6909 : move16();
859 6909 : Overflow = 0;
860 6909 : move16();
861 :
862 25196 : FOR( i = 0; i < order / 2; i++ )
863 : {
864 18287 : Ltemp = L_sub_o( pq[i + 1], pq[i], &Overflow );
865 18287 : giOverflow = (Word16) Overflow;
866 18287 : move16();
867 18287 : IF( EQ_16( giOverflow, 1 ) )
868 : {
869 0 : BREAK;
870 : }
871 :
872 18287 : q[i] = Ltemp;
873 18287 : move32();
874 : }
875 :
876 6909 : IF( EQ_16( giOverflow, 1 ) )
877 : {
878 0 : FOR( i = 0; i < order; i++ )
879 : {
880 0 : a[i] = mult_r( prev_a[i], pwAlpha[i] );
881 0 : move16();
882 : }
883 : }
884 : ELSE
885 : {
886 25196 : FOR( i = 0; i < order / 2; i++ )
887 : {
888 18287 : Overflow = 0;
889 18287 : move16();
890 18287 : Lacc = L_add_o( p[i], q[i], &Overflow ); /* p[i], q[i] in Q24 */
891 18287 : if ( Overflow )
892 : {
893 0 : giOverflow = 1;
894 0 : move16();
895 : }
896 :
897 18287 : Lacc = L_negate( Lacc ); /* Lacc=-(p[i]-q[i])/2 in Q25 */
898 18287 : Overflow = 0;
899 18287 : move16();
900 18287 : Lacc = L_add_o( L_shl_o( Lacc, 3, &Overflow ), 0x08000, &Overflow ); /* rounding */
901 18287 : if ( Overflow )
902 : {
903 0 : giOverflow = 1;
904 0 : move16();
905 : }
906 :
907 18287 : a[i] = extract_h( Lacc ); /* a[i] in Q12 */
908 :
909 18287 : IF( EQ_16( giOverflow, 1 ) )
910 : {
911 0 : BREAK;
912 : }
913 : }
914 25196 : FOR( i = 0; i < order / 2; i++ )
915 : {
916 18287 : Overflow = 0;
917 18287 : move16();
918 18287 : Lacc = L_sub_o( q[i], p[i], &Overflow ); /* p[i], q[i] in Q24 */
919 18287 : if ( Overflow )
920 : {
921 0 : giOverflow = 1;
922 0 : move16();
923 : }
924 18287 : Overflow = 0;
925 18287 : move16();
926 18287 : Lacc = L_add_o( L_shl_o( Lacc, 3, &Overflow ), 0x08000, &Overflow ); /* rounding */
927 18287 : if ( Overflow )
928 : {
929 0 : giOverflow = 1;
930 0 : move16();
931 : }
932 :
933 18287 : a[order - 1 - i] = extract_h( Lacc );
934 :
935 :
936 18287 : IF( EQ_16( giOverflow, 1 ) )
937 : {
938 0 : BREAK;
939 : }
940 : }
941 : }
942 :
943 :
944 6909 : IF( EQ_16( giOverflow, 1 ) )
945 : {
946 0 : FOR( i = 0; i < order; i++ )
947 : {
948 0 : a[i] = mult_r( tmp_pci[i], pwAlpha[i] );
949 0 : move16();
950 : }
951 : }
952 : }
953 :
954 : /*
955 : * E_LPC_f_lsp_pol_get
956 : *
957 : * Parameters:
958 : * lsp/isp I: Line spectral pairs (cosine domaine) Q15
959 : * f O: the coefficients of F1 or F2 Q23
960 : * n I: no of coefficients (m/2)
961 : * == NC for F1(z); == NC-1 for F2(z)
962 : * fact I: scaling factor
963 : *
964 : *-----------------------------------------------------------*
965 : * procedure E_LPC_f_lsp_pol_get: *
966 : * ~~~~~~~~~~~ *
967 : * Find the polynomial F1(z) or F2(z) from the LSPs. *
968 : * This is performed by expanding the product polynomials: *
969 : * *
970 : * F1(z) = product ( 1 - 2 LSF_i z^-1 + z^-2 ) *
971 : * i=0,2,4,6,8 *
972 : * F2(z) = product ( 1 - 2 LSF_i z^-1 + z^-2 ) *
973 : * i=1,3,5,7,9 *
974 : * *
975 : * where LSP_i are the LSPs in the cosine domain. *
976 : * *
977 : *-----------------------------------------------------------*
978 : * R.A.Salami October 1990 *
979 : *-----------------------------------------------------------*
980 : */
981 3565470 : Word16 E_LPC_f_lsp_pol_get( const Word16 lsp[], Word32 f[], const Word16 n, const Word16 past_Ovf, const Word16 isMODE1 )
982 : {
983 : /* All computation in Q23 */
984 : const Word16 *plsp;
985 : Word16 i, j;
986 : Word16 b;
987 : Word32 b32;
988 3565470 : Word16 Ovf = 0;
989 3565470 : move16();
990 : Word16 Q_out;
991 : Word16 m2;
992 :
993 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
994 3565470 : Flag Overflow = 0;
995 3565470 : move16();
996 : #endif
997 :
998 3565470 : Q_out = 31 - 23;
999 3565470 : move16();
1000 3565470 : Ovf = past_Ovf;
1001 3565470 : move16();
1002 :
1003 3565470 : test();
1004 3565470 : IF( past_Ovf && isMODE1 ) /* Currently this feature is implemented only in MODE1 */
1005 : {
1006 : /* In some NB cases, overflow where detectected
1007 : in f1 or f2 polynomial computation when it
1008 : happen we reduce the precision of the computing
1009 : to limit the risk of saturation*/
1010 209356 : Q_out = add( Q_out, past_Ovf );
1011 : }
1012 3565470 : Overflow = 0;
1013 3565470 : move16();
1014 3565470 : plsp = lsp;
1015 3565470 : f[0] = L_shl_o( 1, sub( 31, Q_out ), &Overflow );
1016 3565470 : move32();
1017 : /*b = -2.0f * *plsp;*/
1018 3565470 : b = *plsp;
1019 3565470 : move16();
1020 3565470 : m2 = shl_o( -2, sub( 15, Q_out ), &Overflow );
1021 3565470 : f[1] = L_mult_o( b, m2, &Overflow );
1022 3565470 : move32();
1023 :
1024 27309156 : FOR( i = 2; i <= n; i++ )
1025 : {
1026 23743686 : plsp += 2;
1027 : /*b = 2.0f * *plsp;*/
1028 23743686 : move16();
1029 23743686 : b = *plsp;
1030 23743686 : b32 = L_mult_o( b, m2, &Overflow );
1031 : /*f[i] = -b*f[i-1] + 2.0f*f[i-2];*/
1032 23743686 : move32();
1033 23743686 : f[i] = L_shl_o( L_sub_o( f[i - 2], Mpy_32_16_1( f[i - 1], b ), &Overflow ), 1, &Overflow );
1034 :
1035 92545536 : FOR( j = i - 1; j > 1; j-- )
1036 : {
1037 : /*f[j] += b*f[j-1] + f[j-2];*/
1038 68801850 : move32();
1039 68801850 : f[j] = L_add_o( f[j], L_sub_o( f[j - 2], L_shl_o( Mpy_32_16_1( f[j - 1], b ), 1, &Overflow ), &Overflow ), &Overflow );
1040 : }
1041 23743686 : move32();
1042 23743686 : f[1] = L_add_o( f[1], b32, &Overflow );
1043 : }
1044 :
1045 :
1046 3565470 : test();
1047 3565470 : IF( Overflow > 0 && isMODE1 )
1048 : {
1049 : /* If an overflow is detected, redo the computation with 1 bit less */
1050 179448 : Ovf = add( Ovf, 1 );
1051 179448 : Ovf = E_LPC_f_lsp_pol_get( lsp, f, n, Ovf, isMODE1 );
1052 : }
1053 3565470 : return Ovf;
1054 : }
1055 :
1056 22412 : void E_LPC_a_lsp_conversion(
1057 : const Word16 *a, /* input : LP filter coefficients (Qx) */
1058 : Word16 *lsp, /* output: Line spectral pairs (in the cosine domain)(0Q15) */
1059 : const Word16 *old_lsp, /* input : LSP vector from past frame (0Q15) */
1060 : const Word16 m /* input : length of the LP filter coefficients */
1061 : )
1062 : {
1063 : Word16 i, nf, ip, nc;
1064 : Word16 xlow, ylow, xhigh, yhigh;
1065 : Word16 x, y, tmp, exp;
1066 : Word32 f[2][NC_MAX + 1];
1067 : Word32 t0, t1;
1068 : Word32 sum, diff;
1069 : Word16 scale;
1070 :
1071 :
1072 22412 : nc = shr( m, 1 );
1073 :
1074 22412 : scale = shl( 128, norm_s( a[0] ) );
1075 :
1076 : /*-------------------------------------------------------------*
1077 : * find the sum and diff polynomials F1(z) and F2(z) *
1078 : * F1(z) = [A(z) + z^11 A(z^-1)]/(1+z^-1) *
1079 : * F2(z) = [A(z) - z^11 A(z^-1)]/(1-z^-1) *
1080 : *-------------------------------------------------------------*/
1081 :
1082 22412 : f[0][0] = L_mult( a[0], scale ); /*1.0f in Q23*/
1083 22412 : move32();
1084 22412 : f[1][0] = L_mult( a[0], scale ); /*1.0f in Q23*/
1085 22412 : move32();
1086 179296 : FOR( i = 1; i < nc; i++ )
1087 : {
1088 156884 : t0 = L_mult( a[i], scale ); /*Q23*/
1089 156884 : sum = L_mac( t0, a[m + 1 - i], scale );
1090 156884 : diff = L_msu( t0, a[m + 1 - i], scale );
1091 156884 : f[0][i] = L_sub( sum, f[0][i - 1] );
1092 156884 : move32(); /*Q23*/
1093 156884 : f[1][i] = L_add( diff, f[1][i - 1] );
1094 156884 : move32(); /*Q23*/
1095 : }
1096 22412 : t1 = L_mult0( a[i], scale ); /*Q23-1*/
1097 22412 : sum = L_mac0( t1, a[m + 1 - i], scale );
1098 22412 : diff = L_msu0( t1, a[m + 1 - i], scale );
1099 22412 : f[0][nc] = L_sub( sum, L_shr( f[0][i - 1], 1 ) );
1100 22412 : move32(); /*Q23-1*/
1101 22412 : f[1][nc] = L_add( diff, L_shr( f[1][i - 1], 1 ) );
1102 22412 : move32(); /*Q23-1*/
1103 :
1104 : /* Precalculate difference to index 0 for index 2 */
1105 22412 : f[0][2] = L_sub( f[0][2], f[0][0] );
1106 22412 : move32();
1107 22412 : f[1][2] = L_sub( f[1][2], f[1][0] );
1108 22412 : move32();
1109 :
1110 : /*---------------------------------------------------------------------*
1111 : * Find the LSPs (roots of F1(z) and F2(z) ) using the *
1112 : * Chebyshev polynomial evaluation. *
1113 : * The roots of F1(z) and F2(z) are alternatively searched. *
1114 : * We start by finding the first root of F1(z) then we switch *
1115 : * to F2(z) then back to F1(z) and so on until all roots are found. *
1116 : * *
1117 : * - Evaluate Chebyshev pol. at grid points and check for sign change.*
1118 : * - If sign change track the root by subdividing the interval *
1119 : * 4 times and ckecking sign change. *
1120 : *---------------------------------------------------------------------*/
1121 22412 : nf = 0;
1122 22412 : move16(); /* number of found frequencies */
1123 22412 : ip = 0;
1124 22412 : move16(); /* indicator for f1 or f2 */
1125 :
1126 22412 : xlow = Grid[0];
1127 22412 : move16();
1128 22412 : ylow = chebyshev( xlow, f[ip], nc, 8 );
1129 :
1130 2115511 : FOR( i = 1; i <= GRID100_POINTS; i++ )
1131 : {
1132 2115511 : xhigh = xlow;
1133 2115511 : move16();
1134 2115511 : yhigh = ylow;
1135 2115511 : move16();
1136 2115511 : xlow = Grid[i];
1137 2115511 : move16();
1138 2115511 : ylow = chebyshev( xlow, f[ip], nc, 8 );
1139 :
1140 2115511 : IF( L_mult( ylow, yhigh ) <= 0 )
1141 : {
1142 358592 : t0 = L_mult( xhigh, 0x4000 );
1143 : /* divide 2 times the interval */
1144 358592 : x = mac_r( t0, xlow, 0x4000 ); /* xmid = (xlow + xhigh)/2 */
1145 358592 : y = chebyshev( x, f[ip], nc, 8 );
1146 :
1147 358592 : IF( L_mult( ylow, y ) <= 0 )
1148 : {
1149 173100 : yhigh = y;
1150 173100 : move16();
1151 173100 : xhigh = x;
1152 173100 : move16();
1153 173100 : y = ylow;
1154 173100 : move16();
1155 173100 : x = xlow;
1156 173100 : move16();
1157 : /* 'xhigh' has changed, update 't0' */
1158 173100 : t0 = L_mult( xhigh, 0x4000 );
1159 : }
1160 358592 : xlow = mac_r( t0, x, 0x4000 ); /* xmid = (xlow + xhigh)/2 */
1161 358592 : ylow = chebyshev( xlow, f[ip], nc, 8 );
1162 :
1163 358592 : IF( L_mult( y, ylow ) <= 0 )
1164 : {
1165 183117 : yhigh = ylow;
1166 183117 : move16();
1167 183117 : xhigh = xlow;
1168 183117 : move16();
1169 183117 : ylow = y;
1170 183117 : move16();
1171 183117 : xlow = x;
1172 183117 : move16();
1173 : }
1174 :
1175 : /*--------------------------------------------------------*
1176 : * Linear interpolation
1177 : * xint = xlow - ylow*(xhigh-xlow)/(yhigh-ylow)
1178 : *--------------------------------------------------------*/
1179 358592 : y = msu_r( L_mult( yhigh, 0x4000 ), ylow, 0x4000 );
1180 :
1181 358592 : IF( y != 0 )
1182 : {
1183 358592 : x = sub( xhigh, xlow );
1184 : BASOP_SATURATE_WARNING_OFF_EVS
1185 358592 : tmp = abs_s( y );
1186 : BASOP_SATURATE_WARNING_ON_EVS
1187 358592 : exp = norm_s( tmp );
1188 358592 : if ( exp )
1189 358592 : tmp = shl( tmp, exp );
1190 358592 : tmp = div_s( (Word16) 16383 / 2, tmp );
1191 358592 : t0 = L_mult( x, tmp );
1192 358592 : t0 = L_shr( t0, sub( 20, exp ) );
1193 358592 : tmp = extract_l( t0 ); /* y = (xhigh-xlow)/(yhigh-ylow) in Q11 */
1194 :
1195 : /* Restore Sign */
1196 358592 : if ( y < 0 )
1197 179296 : tmp = negate( tmp );
1198 :
1199 358592 : t0 = L_mult( ylow, tmp ); /* result in Q26 */
1200 358592 : t0 = L_shr( t0, 11 ); /* result in Q15 */
1201 358592 : xlow = sub( xlow, extract_l( t0 ) ); /* xint = xlow - ylow*y */
1202 : }
1203 358592 : lsp[nf++] = xlow;
1204 358592 : move16();
1205 :
1206 358592 : IF( GE_16( nf, m ) )
1207 : {
1208 22412 : BREAK;
1209 : }
1210 :
1211 336180 : ip = s_xor( ip, 1 );
1212 336180 : ylow = chebyshev( xlow, f[ip], nc, 8 );
1213 : }
1214 : }
1215 :
1216 : /* Check if m roots found */
1217 : /* if not use the LSPs from previous frame */
1218 :
1219 22412 : IF( LT_16( nf, m ) )
1220 : {
1221 0 : FOR( i = 0; i < m; i++ )
1222 : {
1223 0 : lsp[i] = old_lsp[i];
1224 0 : move16();
1225 : }
1226 : }
1227 :
1228 :
1229 22412 : return;
1230 : }
1231 :
1232 : /*
1233 : * E_LPC_f_lsp_a_conversion
1234 : *
1235 : * Parameters:
1236 : * lsp I: Line spectral pairs Q15
1237 : * a O: Predictor coefficients (order = m) Qx (The Q factor of the output to be deduced from a(0))
1238 : * m I: order of LP filter
1239 : *
1240 : * Function:
1241 : * Convert ISPs to predictor coefficients a[]
1242 : *
1243 : * Returns:
1244 : * void
1245 : */
1246 1693011 : void E_LPC_f_lsp_a_conversion( const Word16 *lsp, Word16 *a, const Word16 m )
1247 : {
1248 : Word16 i, j, k;
1249 : Word32 f1[NC_MAX + 1], f2[NC_MAX + 1];
1250 : Word16 nc;
1251 : Word32 t0;
1252 : Word16 Ovf, Ovf2;
1253 : #ifndef ISSUE_1836_replace_overflow_libcom
1254 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1255 : Flag Overflow = 0;
1256 : #endif
1257 : #endif
1258 :
1259 :
1260 : /*-----------------------------------------------------*
1261 : * Find the polynomials F1(z) and F2(z) *
1262 : *-----------------------------------------------------*/
1263 :
1264 1693011 : nc = shr( m, 1 );
1265 :
1266 1693011 : assert( m == 16 || m == 10 );
1267 :
1268 1693011 : Ovf = 0;
1269 1693011 : move16();
1270 1693011 : Ovf = E_LPC_f_lsp_pol_get( &lsp[0], f1, nc, Ovf, 1 );
1271 1693011 : Ovf2 = E_LPC_f_lsp_pol_get( &lsp[1], f2, nc, Ovf, 1 );
1272 1693011 : IF( NE_16( Ovf2, Ovf ) )
1273 : {
1274 : /* to ensure similar scaling for f1 and f2 in case
1275 : an overflow would be detected only in f2,
1276 : but this case never happen on my dtb */
1277 0 : E_LPC_f_lsp_pol_get( &lsp[0], f1, nc, s_max( Ovf2, Ovf ), 1 );
1278 : }
1279 : /*-----------------------------------------------------*
1280 : * Multiply F1(z) by (1+z^-1) and F2(z) by (1-z^-1) *
1281 : *-----------------------------------------------------*/
1282 : /*modification*/
1283 1693011 : k = sub( nc, 1 );
1284 14629797 : FOR( i = 0; i <= k; i++ )
1285 : {
1286 12936786 : f1[nc - i] = L_add( f1[nc - i], f1[nc - i - 1] );
1287 12936786 : move32();
1288 : #ifdef ISSUE_1836_replace_overflow_libcom
1289 12936786 : f2[nc - i] = L_sub_sat( f2[nc - i], f2[nc - i - 1] );
1290 : #else
1291 : f2[nc - i] = L_sub_o( f2[nc - i], f2[nc - i - 1], &Overflow );
1292 : #endif
1293 12936786 : move32();
1294 : }
1295 :
1296 : /*-----------------------------------------------------*
1297 : * A(z) = (F1(z)+F2(z))/2 *
1298 : * F1(z) is symmetric and F2(z) is antisymmetric *
1299 : *-----------------------------------------------------*/
1300 :
1301 1693011 : t0 = L_deposit_l( 0 );
1302 : #ifdef ISSUE_1836_replace_overflow_libcom
1303 14629797 : FOR( i = 1; i <= nc; i++ )
1304 : {
1305 12936786 : t0 = L_max( t0, L_abs( L_add_sat( f1[i], f2[i] ) ) );
1306 12936786 : t0 = L_max( t0, L_abs( L_sub_sat( f1[i], f2[i] ) ) );
1307 : }
1308 : #else
1309 : FOR( i = 1; i <= nc; i++ )
1310 : {
1311 : t0 = L_max( t0, L_abs( L_add_o( f1[i], f2[i], &Overflow ) ) );
1312 : t0 = L_max( t0, L_abs( L_sub_o( f1[i], f2[i], &Overflow ) ) );
1313 : }
1314 : #endif
1315 1693011 : k = s_min( norm_l( t0 ), 6 );
1316 1693011 : a[0] = shl( 256, k );
1317 1693011 : move16();
1318 1693011 : test();
1319 1693011 : IF( Ovf || Ovf2 )
1320 : {
1321 29908 : a[0] = shl( 256, sub( k, Ovf ) );
1322 29908 : move16();
1323 : }
1324 1693011 : j = m;
1325 14629797 : FOR( i = 1; i <= nc; i++ )
1326 : {
1327 : /* a[i] = 0.5*(f1[i] + f2[i]) */
1328 : #ifdef ISSUE_1836_replace_overflow_libcom
1329 12936786 : t0 = L_add_sat( f1[i], f2[i] );
1330 12936786 : t0 = L_shl( t0, k );
1331 12936786 : a[i] = round_fx_sat( t0 ); /* from Q23 to Qx and * 0.5 */
1332 :
1333 : /* a[j] = 0.5*(f1[i] - f2[i]) */
1334 12936786 : t0 = L_sub_sat( f1[i], f2[i] );
1335 12936786 : t0 = L_shl( t0, k );
1336 12936786 : a[j] = round_fx_sat( t0 ); /* from Q23 to Qx and * 0.5 */
1337 : #else
1338 : t0 = L_add_o( f1[i], f2[i], &Overflow );
1339 : t0 = L_shl( t0, k );
1340 : a[i] = round_fx_o( t0, &Overflow ); /* from Q23 to Qx and * 0.5 */
1341 :
1342 : /* a[j] = 0.5*(f1[i] - f2[i]) */
1343 : t0 = L_sub_o( f1[i], f2[i], &Overflow );
1344 : t0 = L_shl( t0, k );
1345 : a[j] = round_fx_o( t0, &Overflow ); /* from Q23 to Qx and * 0.5 */
1346 : #endif
1347 12936786 : j--;
1348 : }
1349 :
1350 1693011 : return;
1351 : }
1352 :
1353 : /*---------------------------------------------------------------------------
1354 : * reorder_lsf()
1355 : *
1356 : * To make sure that the LSFs are properly ordered and to keep a certain
1357 : * minimum distance between consecutive LSFs.
1358 : *--------------------------------------------------------------------------*/
1359 530273 : void reorder_lsf_fx(
1360 : Word16 *lsf, /* i/o: LSFs in the frequency domain (0..0.5) Q(x2.56)*/
1361 : const Word16 min_dist, /* i : minimum required distance x2.56*/
1362 : const Word16 n, /* i : LPC order */
1363 : const Word32 fs /* i : sampling frequency */
1364 : )
1365 : {
1366 : Word16 i, lsf_min, n_m_1;
1367 : Word16 lsf_max;
1368 :
1369 530273 : lsf_min = min_dist;
1370 530273 : move16();
1371 :
1372 : /*-----------------------------------------------------------------------*
1373 : * Verify the LSF ordering and minimum GAP
1374 : *-----------------------------------------------------------------------*/
1375 :
1376 9014641 : FOR( i = 0; i < n; i++ )
1377 : {
1378 8484368 : if ( LT_16( lsf[i], lsf_min ) )
1379 : {
1380 36775 : lsf[i] = lsf_min;
1381 36775 : move16();
1382 : }
1383 8484368 : lsf_min = add_sat( lsf[i], min_dist );
1384 : }
1385 :
1386 : /*-----------------------------------------------------------------------*
1387 : * Reverify the LSF ordering and minimum GAP in the reverse order (security)
1388 : *-----------------------------------------------------------------------*/
1389 530273 : lsf_max = round_fx( L_sub( L_shr( L_mult0( extract_l( L_shr( fs, 1 ) ), 1311 ), 9 - 16 ), L_deposit_h( min_dist ) ) ); /* Q0 + Q9 , 1311 is 2.56 in Q9 */
1390 530273 : n_m_1 = sub( n, 1 );
1391 530273 : IF( GT_16( lsf[n_m_1], lsf_max ) ) /* If danger of unstable filter in case of resonance in HF */
1392 : {
1393 0 : FOR( i = n_m_1; i >= 0; i-- ) /* Reverify the minimum LSF gap in the reverse direction */
1394 : {
1395 0 : if ( GT_16( lsf[i], lsf_max ) )
1396 : {
1397 0 : lsf[i] = lsf_max;
1398 0 : move16();
1399 : }
1400 0 : lsf_max = sub( lsf[i], min_dist );
1401 : }
1402 : }
1403 530273 : }
1404 :
1405 103880 : void space_lsfs_fx(
1406 : Word16 *lsfs, /* i/o: Line spectral frequencies */
1407 : const Word16 order /* i : order of LP analysis */
1408 : )
1409 : {
1410 : Word16 delta; /* Q1.15 */
1411 103880 : Word16 i, flag = 1;
1412 :
1413 227281 : WHILE( flag == 1 )
1414 : {
1415 123401 : flag = 0;
1416 123401 : move16();
1417 1480812 : FOR( i = 0; i <= order; i++ )
1418 : {
1419 1357411 : IF( i == 0 )
1420 : {
1421 123401 : delta = lsfs[0];
1422 123401 : move16();
1423 : }
1424 : ELSE
1425 : {
1426 1234010 : IF( EQ_16( i, order ) )
1427 : {
1428 123401 : delta = sub( HALF_POINT_FX, lsfs[i - 1] );
1429 123401 : move16();
1430 : }
1431 : ELSE
1432 : {
1433 1110609 : delta = sub( lsfs[i], lsfs[i - 1] );
1434 1110609 : move16();
1435 : }
1436 : }
1437 1357411 : IF( LT_16( delta, SPC_FX ) )
1438 : {
1439 27001 : flag = 1;
1440 27001 : move16();
1441 27001 : delta = sub( delta, SPC_PLUS_FX );
1442 :
1443 27001 : IF( i == order )
1444 : {
1445 1066 : lsfs[i - 1] = add( lsfs[i - 1], delta );
1446 1066 : move16();
1447 : }
1448 : ELSE
1449 : {
1450 25935 : IF( i == 0 )
1451 : {
1452 0 : lsfs[i] = sub( lsfs[i], delta );
1453 0 : move16();
1454 : }
1455 : ELSE
1456 : {
1457 25935 : delta = mult_r( delta, HALF_POINT_FX );
1458 25935 : lsfs[i - 1] = add( lsfs[i - 1], delta );
1459 25935 : move16();
1460 25935 : lsfs[i] = sub( lsfs[i], delta );
1461 25935 : move16();
1462 : }
1463 : }
1464 : }
1465 : }
1466 : }
1467 :
1468 103880 : return;
1469 : }
1470 :
1471 : /*=================================================================== */
1472 : /* FUNCTION : lsp_weights_fx () */
1473 : /*------------------------------------------------------------------- */
1474 : /* PURPOSE : This function computes the weights for the */
1475 : /* given unquantized lsp vector */
1476 : /*------------------------------------------------------------------- */
1477 : /* INPUT ARGUMENTS :
1478 : _ (Word16 []) lsp_nq_fx: input unquantized lsp vector */
1479 : /* _(Word16 Order) FilterOrder */
1480 : /*------------------------------------------------------------------- */
1481 : /* OUTPUT ARGUMENTS : */
1482 : /* _ (Word16 []) w: weight vector Q(9-n_max) */
1483 :
1484 : /*------------------------------------------------------------------- */
1485 : /* INPUT/OUTPUT ARGUMENTS : */
1486 : /* _ None. */
1487 : /*------------------------------------------------------------------- */
1488 : /* RETURN ARGUMENTS : */
1489 : /* _ None. */
1490 : /*=================================================================== */
1491 :
1492 0 : void lsp_weights_fx(
1493 : Word16 lsp_nq_fx[],
1494 : Word16 w[],
1495 : Word16 Order,
1496 : Word16 *Qout )
1497 : {
1498 0 : Word16 lpcOrder = Order;
1499 :
1500 : Word16 i, n1, tmp_loop;
1501 : Word16 norm[20];
1502 : Word32 Lsum1[20];
1503 : Word16 delta1, delta2, temp;
1504 0 : Word16 n_max = -32768;
1505 0 : move16();
1506 :
1507 0 : temp = 0;
1508 0 : move16();
1509 :
1510 0 : tmp_loop = sub( lpcOrder, 1 );
1511 0 : FOR( i = 0; i < tmp_loop; i++ )
1512 : {
1513 0 : delta1 = sub( lsp_nq_fx[i], temp );
1514 0 : delta2 = sub( lsp_nq_fx[i + 1], lsp_nq_fx[i] );
1515 0 : Lsum1[i] = calc_weight( delta1, delta2, &n1 );
1516 0 : move32(); /* Q( 26-n1) */
1517 0 : norm[i] = n1;
1518 0 : move16();
1519 :
1520 0 : if ( GT_16( norm[i], n_max ) )
1521 : {
1522 0 : n_max = norm[i];
1523 0 : move16();
1524 : }
1525 0 : temp = lsp_nq_fx[i];
1526 0 : move16();
1527 : }
1528 0 : delta1 = sub( lsp_nq_fx[i], temp );
1529 0 : delta2 = sub( 16384, lsp_nq_fx[i] );
1530 :
1531 0 : Lsum1[i] = calc_weight( delta1, delta2, &n1 );
1532 0 : move32(); /* Q( 26-n1) */
1533 0 : norm[i] = n1;
1534 0 : move16();
1535 :
1536 0 : if ( GT_16( norm[i], n_max ) )
1537 : {
1538 0 : n_max = norm[i];
1539 0 : move16();
1540 : }
1541 0 : FOR( i = 0; i < lpcOrder; i++ )
1542 : {
1543 0 : w[i] = round_fx( L_shl( Lsum1[i], sub( norm[i], n_max + 1 ) ) ); /* Q( 9-n_max) */
1544 0 : move16();
1545 : }
1546 :
1547 0 : IF( lpcOrder != LPC_SHB_ORDER_WB )
1548 : {
1549 0 : w[3] = round_fx( L_shl( L_mult( w[3], 18022 ), 1 ) ); /* Q( 9-n_max) */
1550 0 : w[4] = round_fx( L_shl( L_mult( w[4], 18022 ), 1 ) ); /* Q( 9-n_max) */
1551 0 : move16();
1552 0 : move16();
1553 : }
1554 :
1555 0 : *Qout = sub( 9, n_max );
1556 0 : move16();
1557 0 : }
1558 :
1559 0 : void lsp_weights_ivas_fx(
1560 : Word16 lsp_nq_fx[],
1561 : Word16 w[],
1562 : Word16 Order,
1563 : Word16 *Qout )
1564 : {
1565 : Word16 i;
1566 : Word16 q_weight[20];
1567 : Word32 weight[20];
1568 : Word16 delta1, delta2;
1569 : Word32 L_tmp;
1570 : Word16 q_min;
1571 :
1572 0 : delta1 = lsp_nq_fx[0]; // Q15
1573 0 : move16();
1574 0 : delta2 = sub( lsp_nq_fx[1], lsp_nq_fx[0] ); // Q15
1575 :
1576 0 : L_tmp = L_mult0( delta1, delta2 ); // Q30 // Q30
1577 0 : L_tmp = root_a_over_b_ivas_fx( ALPHA_SQ_Q30, Q30, L_tmp, Q30, &q_weight[0] ); // q_weight[0]
1578 :
1579 0 : weight[0] = Mpy_32_16_1( L_tmp, 32000 /* 250 in Q7*/ ); // q_weight[0]-8
1580 0 : q_weight[0] = sub( q_weight[0], 8 );
1581 0 : move32();
1582 0 : move16();
1583 :
1584 0 : q_min = q_weight[0];
1585 0 : move16();
1586 :
1587 0 : FOR( i = 1; i < Order - 1; i++ )
1588 : {
1589 0 : delta1 = sub( lsp_nq_fx[i], lsp_nq_fx[i - 1] ); // Q15
1590 0 : delta2 = sub( lsp_nq_fx[i + 1], lsp_nq_fx[i] ); // Q15
1591 :
1592 0 : L_tmp = L_mult0( delta1, delta2 ); // Q30
1593 0 : L_tmp = root_a_over_b_ivas_fx( ALPHA_SQ_Q30, Q30, L_tmp, Q30, &q_weight[i] ); // q_weight[i]
1594 :
1595 0 : weight[i] = Mpy_32_16_1( L_tmp, 32000 /* 250 in Q7*/ ); // q_weight[i]
1596 0 : q_weight[i] = sub( q_weight[i], 8 );
1597 0 : move32();
1598 0 : move16();
1599 :
1600 0 : q_min = s_min( q_min, q_weight[i] );
1601 : }
1602 0 : delta1 = sub( lsp_nq_fx[i], lsp_nq_fx[i - 1] ); // Q15
1603 0 : delta2 = sub( 16384 /* 0.5 in Q15*/, lsp_nq_fx[i] ); // Q15
1604 :
1605 0 : L_tmp = L_mult0( delta1, delta2 ); // Q30
1606 0 : L_tmp = root_a_over_b_ivas_fx( ALPHA_SQ_Q30, Q30, L_tmp, Q30, &q_weight[i] ); // q_weight[i]
1607 :
1608 0 : weight[i] = Mpy_32_16_1( L_tmp, 32000 /* 250 in Q7*/ ); // q_weight[i]
1609 0 : q_weight[i] = sub( q_weight[i], 8 );
1610 0 : move32();
1611 0 : move16();
1612 :
1613 0 : q_min = s_min( q_min, q_weight[i] );
1614 :
1615 0 : FOR( i = 0; i < Order; i++ )
1616 : {
1617 0 : w[i] = round_fx( L_shl( weight[i], sub( q_min, q_weight[i] ) ) ); /* q_min-16 */
1618 0 : move16();
1619 : }
1620 :
1621 0 : IF( Order != LPC_SHB_ORDER_WB )
1622 : {
1623 0 : w[3] = round_fx( L_shl( L_mult( w[3], 18022 ), 1 ) ); /* q_min-16 */
1624 0 : w[4] = round_fx( L_shl( L_mult( w[4], 18022 ), 1 ) ); /* q_min-16 */
1625 0 : move16();
1626 0 : move16();
1627 : }
1628 :
1629 0 : *Qout = sub( q_min, 16 );
1630 0 : move16();
1631 0 : }
1632 :
1633 : /*
1634 : * E_LPC_isf_isp_conversion
1635 : *
1636 : * Parameters:
1637 : * isf I: isf[m] normalized (range: 0 <= val <= 0.5) 14Q1*1.28
1638 : * isp O: isp[m] (range: -1 <= val < 1) Q15
1639 : * m I: LPC order
1640 : *
1641 : * Function:
1642 : * Transformation isf to isp
1643 : *
1644 : * ISF are immitance spectral pair in frequency domain (0 to 6400).
1645 : * ISP are immitance spectral pair in cosine domain (-1 to 1).
1646 : *
1647 : * Returns:
1648 : * void
1649 : */
1650 0 : void E_LPC_isf_isp_conversion( const Word16 isf[], Word16 isp[], const Word16 m )
1651 : {
1652 : Word16 i;
1653 :
1654 0 : assert( m == 16 || m == 10 );
1655 :
1656 :
1657 0 : FOR( i = 1; i < m; i++ )
1658 : {
1659 0 : *isp++ = xsf_to_xsp( *isf++ );
1660 0 : move16();
1661 : }
1662 0 : *isp = xsf_to_xsp( shl( *isf, 1 ) );
1663 0 : move16();
1664 :
1665 :
1666 0 : return;
1667 : }
1668 :
1669 : /*
1670 : * E_LPC_isp_isf_conversion
1671 : *
1672 : * Parameters:
1673 : * isp I: isp[m] (range: -1 <= val < 1) Q15
1674 : * isf O: isf[m] normalized (range: 0 <= val <= 6400) x1.28
1675 : * m I: LPC order
1676 : *
1677 : * Function:
1678 : * Transformation isp to isf
1679 : *
1680 : * ISP are immitance spectral pair in cosine domain (-1 to 1).
1681 : * ISF are immitance spectral pair in frequency domain (0 to 6400).
1682 : *
1683 : * Returns:
1684 : * energy of prediction error
1685 : */
1686 0 : void E_LPC_isp_isf_conversion( const Word16 isp[], Word16 isf[], const Word16 m )
1687 : {
1688 : Word16 i;
1689 :
1690 0 : assert( m == 16 || m == 10 );
1691 :
1692 :
1693 0 : FOR( i = 0; i < m; i++ )
1694 : {
1695 0 : isf[i] = xsp_to_xsf( isp[i] );
1696 0 : move16();
1697 : }
1698 :
1699 0 : isf[m - 1] = shr( isf[m - 1], 1 );
1700 0 : move16();
1701 :
1702 :
1703 0 : return;
1704 : }
1705 :
1706 :
1707 3687756 : Word16 xsf_to_xsp( Word16 lsf )
1708 : {
1709 : /* lsp = cos(lsf * 3.1415/6400); */
1710 3687756 : return getCosWord16R2( lsf );
1711 : }
1712 :
1713 563344 : Word16 xsp_to_xsf( Word16 lsp )
1714 : {
1715 : Word16 ind, tmp;
1716 : Word32 L_tmp;
1717 :
1718 :
1719 : /*------------------------------------------------------*
1720 : * find value in table that is just greater than lsp
1721 : *------------------------------------------------------*/
1722 :
1723 : /* Retrieve Index Guess */
1724 : /* Based on lsp */
1725 563344 : ind = mac_r( GUESS_TBL_SZ / 2 * 65536 - 0x8000, lsp, GUESS_TBL_SZ / 2 );
1726 563344 : ind = Ind_Guess[ind];
1727 563344 : move16();
1728 :
1729 : /* Correct Index so that */
1730 : /* cos_table_129[ind] > isp[i] */
1731 563344 : tmp = sub( lsp, cos_table_129[ind] );
1732 : /*
1733 : 69%: (Final Index - Index Guess) is <= 1
1734 : 28%: (Final Index - Index Guess) is 2
1735 : 2%: (Final Index - Index Guess) is >= 3
1736 : <1%: ...
1737 : */
1738 563344 : IF( tmp > 0 ) /* possible range 0 to -5 (-1-2-2) */
1739 : {
1740 151325 : ind = sub( ind, 1 );
1741 151325 : tmp = sub( lsp, cos_table_129[ind] );
1742 :
1743 151325 : IF( tmp > 0 )
1744 : {
1745 37819 : ind = sub( ind, 2 );
1746 37819 : tmp = sub( lsp, cos_table_129[ind] );
1747 37819 : if ( tmp > 0 )
1748 : {
1749 454 : ind = sub( ind, 2 );
1750 : }
1751 37819 : tmp = sub( lsp, cos_table_129[ind + 1] );
1752 37819 : if ( tmp <= 0 )
1753 : {
1754 33873 : ind = add( ind, 1 );
1755 : }
1756 37819 : tmp = sub( lsp, cos_table_129[ind] );
1757 : }
1758 : }
1759 :
1760 : /* acos(lsp)= ind*128 + (lsp-cos_table_129[ind]) * acos_slope[ind] / 2048 */
1761 563344 : L_tmp = L_mac( 1L << 11, tmp, acos_slope[ind] );
1762 563344 : L_tmp = L_shr( L_tmp, 12 ); /* (lsp-cos_table_129[ind]) * acos_slope[ind]) >> 11 */
1763 563344 : L_tmp = L_mac0( L_tmp, ind, 128 );
1764 :
1765 :
1766 563344 : return extract_l( L_tmp );
1767 : }
1768 :
1769 : /*-------------------------------------------------------------------*
1770 : * a2rc()
1771 : *
1772 : * Convert from LPC to reflection coeff
1773 : *-------------------------------------------------------------------*/
1774 :
1775 105754 : void a2rc_fx( const Word16 *a, /* i: can be any Q */
1776 : Word16 *refl, /* o: Q15 */
1777 : Word16 lpcorder )
1778 :
1779 : {
1780 : Word16 f_fx[M];
1781 : Word16 km_fx;
1782 : Word32 L_tmp1, L_tmp2;
1783 : Word16 tmp;
1784 : Word16 denom_mant, exp;
1785 : Word32 new_mant;
1786 : Word16 temp;
1787 : Word16 m, j, n;
1788 : Word16 q, q_a, q_a2, One_Qx;
1789 : Word32 One_Qx2;
1790 : #ifndef ISSUE_1836_replace_overflow_libcom
1791 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1792 : Flag Overflow = 0;
1793 : #endif
1794 : #endif
1795 105754 : q = add( norm_s( a[-1] ), 1 );
1796 105754 : q_a = sub( 15, q );
1797 105754 : q_a2 = add( shl( q_a, 1 ), 1 );
1798 : /* copy into internal vars so they can be changed */
1799 :
1800 1797818 : FOR( m = 0; m < lpcorder; m++ )
1801 : {
1802 : /* f_fx[m] = p_fx[m]; */
1803 1692064 : f_fx[m] = negate( a[m] );
1804 1692064 : move16();
1805 : }
1806 105754 : One_Qx = shl( 1, q_a );
1807 105754 : One_Qx2 = L_shl( 1, q_a2 );
1808 1796889 : FOR( m = lpcorder - 1; m >= 0; m-- )
1809 : {
1810 1691718 : km_fx = f_fx[m];
1811 1691718 : move16();
1812 :
1813 1691718 : test();
1814 1691718 : IF( LE_16( km_fx, negate( One_Qx ) ) || GE_16( km_fx, One_Qx ) )
1815 : {
1816 9911 : FOR( j = 0; j < lpcorder; j++ )
1817 : {
1818 9328 : refl[j] = 0;
1819 9328 : move16();
1820 : }
1821 :
1822 583 : return;
1823 : }
1824 :
1825 1691135 : refl[m] = negate( km_fx );
1826 1691135 : move16();
1827 1691135 : L_tmp1 = One_Qx2; /* 1 in 2xq_a+1 */
1828 1691135 : move32();
1829 1691135 : L_tmp1 = L_msu( L_tmp1, km_fx, km_fx ); /* 1-km*km in Q25 */
1830 :
1831 : /* new_mant = invert_dp(L_tmp1,4, &tmp_denom_exp,1); sum in Q61-Q25-n=Q36-n */
1832 1691135 : exp = norm_l( L_tmp1 );
1833 1691135 : tmp = extract_h( L_shl( L_tmp1, exp ) );
1834 1691135 : exp = sub( sub( 30, exp ), q_a2 );
1835 1691135 : IF( tmp )
1836 : {
1837 1691135 : tmp = div_s( 16384, tmp ); /* 15+exp */
1838 : }
1839 : ELSE
1840 : {
1841 0 : tmp = 0;
1842 : }
1843 1691135 : new_mant = L_deposit_h( tmp );
1844 1691135 : temp = round_fx( L_shl( new_mant, 0 ) ); /* in Q14 */
1845 1691135 : denom_mant = temp;
1846 1691135 : move16();
1847 1691135 : L_tmp1 = L_mult( km_fx, denom_mant ); /* km*denom. Q12*Q14 = Q27 */
1848 1691135 : L_tmp1 = L_shl( L_tmp1, q ); /* change to Q31. simulation showed no overflow */
1849 1691135 : tmp = round_fx( L_tmp1 ); /* extract in Q15 */
1850 :
1851 7613210 : FOR( j = 0; j < m / 2; j++ )
1852 : {
1853 5922075 : n = sub( sub( m, (Word16) 1 ), j );
1854 5922075 : L_tmp1 = L_mult( denom_mant, f_fx[j] ); /* denom*f[j]. Q15*Q12 = Q28 (floating with exp) */
1855 : #ifdef ISSUE_1836_replace_overflow_libcom
1856 5922075 : L_tmp1 = L_mac_sat( L_tmp1, tmp, f_fx[n] ); /* denom*f[j]+km*denom*f[n] in Q28 (floating with exp) */
1857 5922075 : L_tmp2 = L_mult( denom_mant, f_fx[n] ); /* denom*f[n]. Q15*Q12 = Q28 (floating with exp) */
1858 5922075 : L_tmp2 = L_mac_sat( L_tmp2, tmp, f_fx[j] ); /* denom*f[n]+km*denom*f[j] in Q28 (floating with exp) */
1859 5922075 : L_tmp1 = L_shr_sat( L_tmp1, exp ); /* bringing to true Q28 */
1860 5922075 : L_tmp2 = L_shr_sat( L_tmp2, exp ); /* bringing to true Q28 */
1861 5922075 : f_fx[j] = round_fx_sat( L_tmp1 ); /* extracting in q_a */
1862 5922075 : f_fx[n] = round_fx_sat( L_tmp2 ); /* extracting in q_a */
1863 : #else
1864 : L_tmp1 = L_mac_o( L_tmp1, tmp, f_fx[n], &Overflow ); /* denom*f[j]+km*denom*f[n] in Q28 (floating with exp) */
1865 : L_tmp2 = L_mult( denom_mant, f_fx[n] ); /* denom*f[n]. Q15*Q12 = Q28 (floating with exp) */
1866 : L_tmp2 = L_mac_o( L_tmp2, tmp, f_fx[j], &Overflow ); /* denom*f[n]+km*denom*f[j] in Q28 (floating with exp) */
1867 : L_tmp1 = L_shr_o( L_tmp1, exp, &Overflow ); /* bringing to true Q28 */
1868 : L_tmp2 = L_shr_o( L_tmp2, exp, &Overflow ); /* bringing to true Q28 */
1869 : f_fx[j] = round_fx_o( L_tmp1, &Overflow ); /* extracting in q_a */
1870 : f_fx[n] = round_fx_o( L_tmp2, &Overflow ); /* extracting in q_a */
1871 : #endif
1872 : }
1873 :
1874 1691135 : IF( m & 1 )
1875 : {
1876 845772 : L_tmp1 = L_mult( denom_mant, f_fx[j] ); /* denom*f[j]. Q15*Q12 = Q28 (floating with exp) */
1877 : #ifdef ISSUE_1836_replace_overflow_libcom
1878 845772 : L_tmp1 = L_mac_sat( L_tmp1, tmp, f_fx[j] ); /* denom*f[j]+km*denom*f[j] in Q28 (floating with exp) */
1879 845772 : L_tmp1 = L_shr_sat( L_tmp1, exp ); /* bringing to true Q28 */
1880 845772 : f_fx[j] = round_fx_sat( L_tmp1 ); /* extracting in q_a */
1881 845772 : move16();
1882 : #else
1883 : L_tmp1 = L_mac_o( L_tmp1, tmp, f_fx[j], &Overflow ); /* denom*f[j]+km*denom*f[j] in Q28 (floating with exp) */
1884 : L_tmp1 = L_shr_o( L_tmp1, exp, &Overflow ); /* bringing to true Q28 */
1885 : f_fx[j] = round_fx_o( L_tmp1, &Overflow ); /* extracting in q_a */
1886 : move16();
1887 : #endif
1888 : }
1889 : }
1890 :
1891 1787907 : FOR( j = 0; j < lpcorder; j++ )
1892 : {
1893 1682736 : refl[j] = shl( refl[j], q );
1894 1682736 : move16();
1895 : }
1896 :
1897 :
1898 105171 : return;
1899 : }
1900 2086 : Word16 vq_dec_lvq_fx(
1901 : Word16 sf_flag, /* i : safety net flag */
1902 : Word16 x[], /* o : Decoded vector Q(x2.56)*/
1903 : Word16 indices[], /* i : Indices */
1904 : Word16 stages, /* i : Number of stages */
1905 : Word16 N, /* i : Vector dimension */
1906 : Word16 mode, /* (i): mode_lvq, or mode_lvq_p */
1907 : Word16 no_bits, /* (i): no. bits for lattice */
1908 : Word32 *p_offset_scale1,
1909 : Word32 *p_offset_scale2,
1910 : Word32 *p_offset_scale1_p,
1911 : Word32 *p_offset_scale2_p,
1912 : Word16 *p_no_scales,
1913 : Word16 *p_no_scales_p )
1914 : {
1915 : Word16 x_lvq[M];
1916 : Word16 i, stagesm1;
1917 : Word16 pt_fx;
1918 : Word16 ber_flag;
1919 :
1920 : /* clear vector */
1921 2086 : set16_fx( x, 0, N );
1922 :
1923 : /*-----------------------------------------------*
1924 : * add contribution of each stage
1925 : *-----------------------------------------------*/
1926 2086 : stagesm1 = sub( stages, 1 );
1927 2086 : IF( EQ_16( sf_flag, 1 ) )
1928 : {
1929 645 : FOR( i = 0; i < stagesm1; i++ )
1930 : {
1931 402 : pt_fx = i_mult2( indices[i], N );
1932 402 : Vr_add( x, &Quantizers_fx[CB_lsf[mode] + i][pt_fx], x, N );
1933 : }
1934 :
1935 : ber_flag =
1936 243 : deindex_lvq_fx( &indices[stagesm1], x_lvq, mode, sf_flag, no_bits, p_offset_scale1, p_offset_scale2, p_no_scales );
1937 : }
1938 : ELSE
1939 : {
1940 3675 : FOR( i = 0; i < stagesm1; i++ )
1941 : {
1942 1832 : pt_fx = i_mult2( indices[i], N );
1943 1832 : Vr_add( x, &Quantizers_p_fx[CB_p_lsf[mode] + i][pt_fx], x, N );
1944 : }
1945 :
1946 : ber_flag =
1947 1843 : deindex_lvq_fx( &indices[stagesm1], x_lvq, mode, sf_flag, no_bits, p_offset_scale1_p, p_offset_scale2_p, p_no_scales_p );
1948 : }
1949 :
1950 2086 : Vr_add( x, x_lvq, x, N );
1951 :
1952 2086 : return ber_flag;
1953 : }
1954 :
1955 242050 : Word16 vq_dec_lvq_ivas_fx(
1956 : Word16 sf_flag, /* i : safety net flag */
1957 : Word16 x[], /* o : Decoded vector Q(x2.56)*/
1958 : Word16 indices[], /* i : Indices */
1959 : Word16 stages, /* i : Number of stages */
1960 : Word16 N, /* i : Vector dimension */
1961 : Word16 mode, /* (i): mode_lvq, or mode_lvq_p */
1962 : Word16 no_bits /* (i): no. bits for lattice */
1963 : )
1964 : {
1965 : Word16 x_lvq[M];
1966 : Word16 i, stagesm1;
1967 : Word16 pt_fx;
1968 : Word16 ber_flag;
1969 :
1970 : /* clear vector */
1971 242050 : set16_fx( x, 0, N );
1972 :
1973 : /*-----------------------------------------------*
1974 : * add contribution of each stage
1975 : *-----------------------------------------------*/
1976 242050 : stagesm1 = sub( stages, 1 );
1977 242050 : IF( EQ_16( sf_flag, 1 ) )
1978 : {
1979 88797 : FOR( i = 0; i < stagesm1; i++ )
1980 : {
1981 54874 : pt_fx = i_mult2( indices[i], N );
1982 54874 : Vr_add( x, &Quantizers_fx[CB_lsf[mode] + i][pt_fx], x, N );
1983 : }
1984 :
1985 : ber_flag =
1986 : // deindex_lvq_fx(&indices[stagesm1], x_lvq, mode, sf_flag, no_bits, p_offset_scale1, p_offset_scale2, p_no_scales);
1987 33923 : deindex_lvq_ivas_fx( &indices[stagesm1], x_lvq, mode, sf_flag, no_bits );
1988 : }
1989 : ELSE
1990 : {
1991 416512 : FOR( i = 0; i < stagesm1; i++ )
1992 : {
1993 208385 : pt_fx = i_mult2( indices[i], N );
1994 208385 : Vr_add( x, &Quantizers_p_fx[CB_p_lsf[mode] + i][pt_fx], x, N );
1995 : }
1996 :
1997 : ber_flag =
1998 : // deindex_lvq_fx(&indices[stagesm1], x_lvq, mode, sf_flag, no_bits, p_offset_scale1_p, p_offset_scale2_p, p_no_scales_p);
1999 208127 : deindex_lvq_ivas_fx( &indices[stagesm1], x_lvq, mode, sf_flag, no_bits );
2000 : }
2001 :
2002 242050 : Vr_add( x, x_lvq, x, N );
2003 :
2004 242050 : return ber_flag;
2005 : }
2006 :
2007 346817 : ivas_error lsf_allocate_fx(
2008 : const Word16 nBits, /* i : Number of bits to use for quantization */
2009 : const Word16 framemode, /* i : ISF quantizer mode */
2010 : const Word16 framemode_p, /* i : ISF quantizer mode predmode (mode_lvq_p) */
2011 : Word16 *stages0, /* o : Number of stages for safety-net quantizer */
2012 : Word16 *stages1, /* o : Number of stages for predictive quantizer */
2013 : Word16 levels0[], /* o : Number of vectors for each stage for SFNET */
2014 : Word16 levels1[], /* o : Number of vectors for each stage for pred */
2015 : Word16 bits0[], /* o : Number of bits for each stage safety net */
2016 : Word16 bits1[] /* o : Number of bits for each stage pred */
2017 : )
2018 : {
2019 : Word16 i;
2020 : Word16 cumleft;
2021 : Word16 bits_lvq, n_stages, nbits0;
2022 : ivas_error error;
2023 :
2024 346817 : error = IVAS_ERR_OK;
2025 346817 : move16();
2026 :
2027 346817 : cumleft = nBits;
2028 346817 : move16();
2029 :
2030 : /*---------------------------------------------------*
2031 : * Calculate bit allocation for safety-net quantizer
2032 : *---------------------------------------------------*/
2033 :
2034 346817 : cumleft = BitsVQ[framemode];
2035 346817 : move16();
2036 346817 : bits_lvq = sub( nBits, cumleft );
2037 346817 : nbits0 = CBbits[framemode];
2038 346817 : move16();
2039 346817 : IF( GT_16( nbits0, -1 ) )
2040 : {
2041 152691 : IF( nbits0 > 0 )
2042 : {
2043 152691 : n_stages = 2;
2044 152691 : move16();
2045 152691 : levels0[0] = CBsizes[nbits0];
2046 152691 : move16();
2047 152691 : bits0[0] = nbits0;
2048 152691 : move16();
2049 152691 : bits0[1] = sub( cumleft, nbits0 );
2050 :
2051 152691 : IF( bits0[1] == 0 )
2052 : {
2053 69738 : n_stages = sub( n_stages, 1 );
2054 : }
2055 : ELSE
2056 : {
2057 82953 : levels0[1] = CBsizes[sub( cumleft, nbits0 )];
2058 82953 : move16();
2059 : }
2060 : }
2061 : ELSE /* no bits for VQ stage */
2062 : {
2063 0 : n_stages = 0;
2064 0 : move16();
2065 : }
2066 :
2067 152691 : *stages0 = n_stages;
2068 152691 : move16();
2069 152691 : IF( bits_lvq > 0 )
2070 : {
2071 152691 : bits0[n_stages] = bits_lvq;
2072 152691 : move16();
2073 152691 : levels0[n_stages] = bits_lvq;
2074 152691 : move16(); /* this is number of bits, not levels */
2075 152691 : *stages0 = add( n_stages, 1 );
2076 152691 : move16();
2077 : }
2078 : }
2079 : ELSE
2080 : {
2081 194126 : *stages0 = 0;
2082 194126 : move16();
2083 : }
2084 :
2085 : /*---------------------------------------------------*
2086 : * Calculate bit allocation for predictive quantizer
2087 : *---------------------------------------------------*/
2088 346817 : IF( GT_16( framemode_p, -1 ) )
2089 : {
2090 333724 : cumleft = BitsVQ_p[framemode_p];
2091 333724 : move16();
2092 333724 : bits_lvq = sub( nBits, cumleft );
2093 333724 : nbits0 = CBbits_p[framemode_p];
2094 333724 : move16();
2095 :
2096 333724 : IF( GT_16( nbits0, -1 ) )
2097 : {
2098 333724 : IF( nbits0 > 0 )
2099 : {
2100 263986 : IF( EQ_16( framemode_p, 7 ) )
2101 : {
2102 : /* for UNVOICED_WB only */
2103 1389 : n_stages = 3;
2104 1389 : move16();
2105 5556 : FOR( i = 0; i < n_stages; i++ )
2106 : {
2107 4167 : levels1[i] = CBsizes[nbits0];
2108 4167 : move16();
2109 4167 : bits1[i] = nbits0;
2110 4167 : move16();
2111 : }
2112 1389 : bits1[n_stages] = bits_lvq;
2113 1389 : move16();
2114 1389 : levels1[n_stages] = bits_lvq;
2115 1389 : move16();
2116 1389 : *stages1 = add( n_stages, 1 );
2117 : }
2118 : ELSE
2119 : {
2120 262597 : n_stages = 1;
2121 262597 : move16();
2122 262597 : levels1[0] = CBsizes[nbits0];
2123 262597 : move16();
2124 262597 : bits1[0] = nbits0;
2125 262597 : move16();
2126 262597 : nbits0 = sub( cumleft, nbits0 );
2127 262597 : IF( nbits0 > 0 )
2128 : {
2129 30845 : levels1[1] = CBsizes[nbits0];
2130 30845 : move16();
2131 30845 : bits1[1] = nbits0;
2132 30845 : move16();
2133 30845 : n_stages = 2;
2134 30845 : move16();
2135 : }
2136 :
2137 262597 : levels1[n_stages] = bits_lvq;
2138 262597 : move16(); /* this is number of bits, not levels */
2139 262597 : bits1[n_stages] = bits_lvq;
2140 262597 : move16();
2141 262597 : *stages1 = add( n_stages, 1 );
2142 262597 : move16();
2143 : }
2144 : }
2145 : ELSE
2146 : {
2147 69738 : *stages1 = 1;
2148 69738 : move16();
2149 69738 : bits1[0] = bits_lvq;
2150 69738 : move16();
2151 69738 : levels1[0] = bits_lvq;
2152 69738 : move16();
2153 : }
2154 : }
2155 : #ifdef DEBUGGING
2156 : ELSE
2157 : {
2158 : return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "lsf_allocate(): invalid number of bits in used predictive mode\n" );
2159 : }
2160 : #endif
2161 : }
2162 :
2163 346817 : return error;
2164 : }
2165 :
2166 346751 : ivas_error find_pred_mode(
2167 : Word16 *predmode, /* o: prediction mode */
2168 : const Word16 coder_type, /* i: coding type */
2169 : const Word16 bwidth, /* i: bandwidth index */
2170 : const Word32 int_fs, /* i: sampling frequency */
2171 : Word16 *p_mode_lvq, /* o: index of LSF codebooks in safety net mode */
2172 : Word16 *p_mode_lvq_p, /* o: index of LSF codebooks in predictive mode (AR or MA) */
2173 : Word32 core_brate /* i: core bit rate */
2174 : )
2175 : {
2176 : Word16 idx;
2177 : ivas_error error;
2178 :
2179 346751 : error = IVAS_ERR_OK;
2180 346751 : move16();
2181 :
2182 : /* bwidth = 0(NB), 1 (WB), 2(WB2); line index in predmode_tab[][] */
2183 346751 : idx = bwidth;
2184 346751 : move16();
2185 346751 : if ( GT_16( idx, 1 ) )
2186 : {
2187 115365 : idx = 1;
2188 115365 : move16();
2189 : }
2190 346751 : IF( EQ_32( int_fs, INT_FS_16k ) )
2191 : {
2192 : /* WB2 is actually used if sampling frequency is 16kHz */
2193 209241 : idx = 2;
2194 209241 : move16();
2195 : }
2196 : ELSE
2197 : {
2198 137510 : test();
2199 137510 : test();
2200 137510 : if ( ( GE_32( core_brate, GENERIC_MA_LIMIT ) ) && ( EQ_16( coder_type, GENERIC ) ) && ( EQ_16( idx, 1 ) ) )
2201 : {
2202 39023 : idx = 3;
2203 39023 : move16();
2204 : }
2205 : }
2206 346751 : *predmode = predmode_tab[idx][coder_type];
2207 346751 : move16();
2208 346751 : IF( LE_16( idx, 2 ) )
2209 : {
2210 307728 : *p_mode_lvq = add( i_mult2( NO_CODING_MODES, idx ), coder_type );
2211 307728 : IF( *predmode > 0 )
2212 : {
2213 294635 : *p_mode_lvq_p = *p_mode_lvq;
2214 294635 : move16();
2215 : }
2216 : ELSE
2217 : {
2218 13093 : *p_mode_lvq_p = -1;
2219 13093 : move16();
2220 : }
2221 : }
2222 : ELSE /* WB 12.8 with MA pred in GENERIC*/
2223 : {
2224 39023 : *p_mode_lvq = add( NO_CODING_MODES, coder_type );
2225 39023 : IF( EQ_16( coder_type, GENERIC ) )
2226 : {
2227 39023 : *p_mode_lvq_p = 18;
2228 39023 : move16();
2229 : }
2230 : ELSE
2231 : {
2232 0 : IF( *predmode > 0 )
2233 : {
2234 0 : *p_mode_lvq_p = *p_mode_lvq;
2235 0 : move16();
2236 : }
2237 : ELSE
2238 : {
2239 0 : *p_mode_lvq_p = -1;
2240 0 : move16();
2241 : }
2242 : }
2243 : }
2244 : #ifdef DEBUGGING
2245 : if ( *predmode == -1 )
2246 : {
2247 : return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "\nfind_pred_mode(): incorrect coder_type specification: %d\n", coder_type );
2248 : }
2249 : #endif
2250 :
2251 :
2252 346751 : return error;
2253 : }
2254 :
2255 : /*---------------------------------------------------------------------------*
2256 : * reorder_isf
2257 : *
2258 : * To make sure that the isfs are properly ordered and to keep a certain
2259 : * minimum distance between consecutive isfs.
2260 : *--------------------------------------------------------------------------*/
2261 0 : void reorder_isf_fx(
2262 : Word16 *isf, /* i/o: ISFs in the frequency domain (0..0.5) */
2263 : const Word16 min_dist, /* i : minimum required distance */
2264 : const Word16 n, /* i : LPC order */
2265 : const Word16 fs /* i : sampling frequency */
2266 : )
2267 : {
2268 : Word16 i, isf_min;
2269 : Word16 isf_max;
2270 :
2271 0 : isf_min = min_dist;
2272 0 : move16();
2273 :
2274 : /*-----------------------------------------------------------------------*
2275 : * Verify the ISF ordering and minimum GAP
2276 : *-----------------------------------------------------------------------*/
2277 :
2278 0 : FOR( i = 0; i < n - 1; i++ )
2279 : {
2280 0 : if ( LT_16( isf[i], isf_min ) )
2281 : {
2282 0 : isf[i] = isf_min;
2283 0 : move16();
2284 : }
2285 0 : isf_min = add( isf[i], min_dist );
2286 : }
2287 :
2288 : /*-----------------------------------------------------------------------*
2289 : * Reverify the ISF ordering and minimum GAP in the reverse order (security)
2290 : *-----------------------------------------------------------------------*/
2291 :
2292 : /*isf_max = sub(shr(fs,1), min_dist);*/
2293 0 : isf_max = sub( fs, min_dist ); /* Fs already divide per 2 */
2294 :
2295 0 : IF( GT_16( isf[n - 2], isf_max ) ) /* If danger of unstable filter in case of resonance in HF */
2296 : {
2297 0 : FOR( i = sub( n, 2 ); i >= 0; i-- ) /* Reverify the minimum ISF gap in the reverse direction */
2298 : {
2299 0 : if ( GT_16( isf[i], isf_max ) )
2300 : {
2301 0 : isf[i] = isf_max;
2302 0 : move16();
2303 : }
2304 0 : isf_max = sub( isf[i], min_dist );
2305 : }
2306 : }
2307 0 : }
2308 :
2309 : /*========================================================================*/
2310 : /* FUNCTION : lsf_stab_fx() */
2311 : /*------------------------------------------------------------------------*/
2312 : /* PURPOSE : Check LSF stability (distance between old LSFs and */
2313 : /* current LSFs) */
2314 : /*------------------------------------------------------------------------*/
2315 : /* INPUT ARGUMENTS : */
2316 : /* _ (Word16) Opt_AMR_WB : flag indicating AMR-WB IO mode */
2317 : /* _ (Word16*) lsf : LSPs from past frame Q(x2.56) */
2318 : /* _ (Word16*) lsfold : LSPs from past frame Q(x2.56) */
2319 : /*------------------------------------------------------------------------*/
2320 : /* INPUT/OUTPUT ARGUMENTS : */
2321 : /*------------------------------------------------------------------------*/
2322 : /* OUTPUT ARGUMENTS : */
2323 : /*------------------------------------------------------------------------*/
2324 :
2325 : /*------------------------------------------------------------------------*/
2326 : /* RETURN ARGUMENTS : */
2327 : /* _ (Word16) stab_fac_fx : LP filter stability Q15 */
2328 : /*========================================================================*/
2329 221252 : Word16 lsf_stab_fx( /* o : LP filter stability Q15*/
2330 : const Word16 *lsf, /* i : LSF vector Q(x2.56)*/
2331 : const Word16 *lsfold, /* i : old LSF vector Q(x2.56)*/
2332 : const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */
2333 : const Word16 L_frame /* i : frame length */
2334 : )
2335 : {
2336 : Word16 i, m;
2337 : Word32 L_tmp;
2338 : Word16 tmp, e;
2339 : #ifndef ISSUE_1836_replace_overflow_libcom
2340 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
2341 : Flag Overflow = 0;
2342 : #endif
2343 : #endif
2344 :
2345 : /*-------------------------------------------------------------------*
2346 : * Check stability on lsf: distance between old lsf and current lsf
2347 : *-------------------------------------------------------------------*/
2348 221252 : IF( Opt_AMR_WB )
2349 : {
2350 0 : m = M - 1;
2351 0 : move16();
2352 0 : tmp = sub( lsf[0], lsfold[0] );
2353 0 : L_tmp = L_mult( tmp, tmp ); /* Q1 */
2354 0 : FOR( i = 1; i < m; i++ )
2355 : {
2356 0 : tmp = sub( lsf[i], lsfold[i] );
2357 0 : L_tmp = L_mac( L_tmp, tmp, tmp ); /* Q1 */
2358 : }
2359 : }
2360 : ELSE
2361 : {
2362 221252 : m = M;
2363 221252 : move16();
2364 221252 : L_tmp = 0;
2365 221252 : move32();
2366 3761284 : FOR( i = 0; i < m; i++ )
2367 : {
2368 3540032 : tmp = sub( lsf[i], lsfold[i] );
2369 3540032 : L_tmp = L_mac( L_tmp, tmp, tmp ); /* Q1 */
2370 : }
2371 : }
2372 :
2373 221252 : e = norm_l( L_tmp );
2374 221252 : L_tmp = L_shl( L_tmp, e ); /*Q(1+e)*/
2375 :
2376 221252 : IF( EQ_16( L_frame, L_FRAME16k ) )
2377 : {
2378 : /*stab_fac = (float)(1.25f - (tmp/625000.0f));*/
2379 71558 : L_tmp = Mpy_32_16_1( L_tmp, 16777 ); /* 30-eQ(1+e)*-21Q36 = 30-21-eQ31-9+e */
2380 : }
2381 : ELSE
2382 : {
2383 : /* stab_fac = (float)(1.25f - (tmp1/400000.0f*2.56=1024000)) */
2384 149694 : L_tmp = Mpy_32_16_1( L_tmp, 26214 ); /* 30-eQ(1+e)*-21Q36 = 30-21-eQ31-9+e */
2385 : }
2386 :
2387 221252 : e = sub( 30 - 21 - 1, e );
2388 : #ifdef ISSUE_1836_replace_overflow_libcom
2389 221252 : tmp = round_fx_sat( L_shl_sat( L_tmp, e ) ); /*Q14*/
2390 : #else
2391 : tmp = round_fx_o( L_shl_o( L_tmp, e, &Overflow ), &Overflow ); /*Q14*/
2392 : #endif
2393 :
2394 221252 : tmp = sub( 20480, tmp ); /* 1.25 - tmp in Q14 */
2395 : #ifdef ISSUE_1836_replace_overflow_libcom
2396 221252 : tmp = shl_sat( tmp, 1 ); /* Q14 -> Q15 with saturation */
2397 : #else
2398 : tmp = shl_o( tmp, 1, &Overflow ); /* Q14 -> Q15 with saturation */
2399 : #endif
2400 :
2401 221252 : tmp = s_max( tmp, 0 );
2402 :
2403 221252 : return tmp;
2404 : }
2405 :
2406 : /*========================================================================*/
2407 : /* FUNCTION : lsf_stab_ivas_fx() */
2408 : /*------------------------------------------------------------------------*/
2409 : /* PURPOSE : Check LSF stability (distance between old LSFs and */
2410 : /* current LSFs) */
2411 : /*------------------------------------------------------------------------*/
2412 : /* INPUT ARGUMENTS : */
2413 : /* _ (Word16) Opt_AMR_WB : flag indicating AMR-WB IO mode */
2414 : /* _ (Word16*) lsf : LSPs from past frame Q(x2.56) */
2415 : /* _ (Word16*) lsfold : LSPs from past frame Q(x2.56) */
2416 : /*------------------------------------------------------------------------*/
2417 : /* INPUT/OUTPUT ARGUMENTS : */
2418 : /*------------------------------------------------------------------------*/
2419 : /* OUTPUT ARGUMENTS : */
2420 : /*------------------------------------------------------------------------*/
2421 :
2422 : /*------------------------------------------------------------------------*/
2423 : /* RETURN ARGUMENTS : */
2424 : /* _ (Word16) stab_fac_fx : LP filter stability Q15 */
2425 : /*========================================================================*/
2426 141132 : Word16 lsf_stab_ivas_fx( /* o : LP filter stability Q15*/
2427 : const Word16 *lsf, /* i : LSF vector Q(x2.56)*/
2428 : const Word16 *lsfold, /* i : old LSF vector Q(x2.56)*/
2429 : const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */
2430 : const Word16 L_frame /* i : frame length */
2431 : )
2432 : {
2433 : Word16 i, m;
2434 : Word32 L_tmp;
2435 : Word16 tmp, e;
2436 : #ifndef ISSUE_1836_replace_overflow_libcom
2437 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
2438 : Flag Overflow = 0;
2439 : #endif
2440 : #endif
2441 :
2442 : /*-------------------------------------------------------------------*
2443 : * Check stability on lsf: distance between old lsf and current lsf
2444 : *-------------------------------------------------------------------*/
2445 141132 : IF( Opt_AMR_WB )
2446 : {
2447 0 : m = M - 1;
2448 0 : move16();
2449 : // tmp = sub(lsf[0], lsfold[0]);
2450 0 : tmp = extract_l( L_sub( lsf[0], (UWord16) lsfold[0] ) );
2451 : // L_tmp = L_mult(tmp, tmp); /* Q1 */
2452 0 : L_tmp = L_mult0( shr( tmp, 1 ), tmp ); /* Q-1 */
2453 0 : FOR( i = 1; i < m; i++ )
2454 : {
2455 : // tmp = sub(lsf[i], lsfold[i]);
2456 0 : tmp = extract_l( L_sub( lsf[i], (UWord16) lsfold[i] ) );
2457 : // L_tmp = L_mac(L_tmp, tmp, tmp); /* Q1 */
2458 0 : L_tmp = L_mac0( L_tmp, shr( tmp, 1 ), tmp ); /* Q-1 */
2459 : }
2460 : }
2461 : ELSE
2462 : {
2463 141132 : m = M;
2464 141132 : move16();
2465 141132 : L_tmp = 0;
2466 141132 : move32();
2467 2399244 : FOR( i = 0; i < m; i++ )
2468 : {
2469 : // tmp = sub(lsf[i], lsfold[i]);
2470 2258112 : tmp = extract_l( L_sub( lsf[i], (UWord16) lsfold[i] ) );
2471 : // L_tmp = L_mac(L_tmp, tmp, tmp); /* Q1 */
2472 2258112 : L_tmp = L_mac0( L_tmp, shr( tmp, 1 ), tmp ); /* Q-1 */
2473 : }
2474 : }
2475 :
2476 141132 : e = norm_l( L_tmp );
2477 141132 : L_tmp = L_shl( L_tmp, e ); /*Q(0+e)*/
2478 :
2479 141132 : IF( EQ_16( L_frame, L_FRAME16k ) )
2480 : {
2481 : /*stab_fac = (float)(1.25f - (tmp/625000.0f));*/
2482 68090 : L_tmp = Mpy_32_16_1( L_tmp, 16777 ); /* 30-eQ(-1+e)*-21Q36 = 30-21-eQ31-9+e */
2483 : }
2484 : ELSE
2485 : {
2486 : /* stab_fac = (float)(1.25f - (tmp1/400000.0f*2.56=1024000)) */
2487 73042 : L_tmp = Mpy_32_16_1( L_tmp, 26214 ); /* 30-eQ(-1+e)*-21Q36 = 30-21-eQ31-9+e */
2488 : }
2489 :
2490 141132 : e = sub( 30 - 21 - 1, e );
2491 : #ifdef ISSUE_1836_replace_overflow_libcom
2492 141132 : tmp = round_fx_sat( L_shl_sat( L_tmp, e ) ); /*Q12*/
2493 : #else
2494 : tmp = round_fx_o( L_shl_o( L_tmp, e, &Overflow ), &Overflow ); /*Q12*/
2495 : #endif
2496 :
2497 : // tmp = sub(20480, tmp); /* 1.25 - tmp in Q14 */
2498 141132 : tmp = sub( 5120, tmp ); /* 1.25 - tmp in Q12 */
2499 : // tmp = shl_o(tmcp, 1, &Overflow); /* Q14 -> Q15 with saturation */
2500 141132 : tmp = shl_sat( tmp, 3 ); /* Q12 -> Q15 with saturation */
2501 :
2502 141132 : tmp = s_max( tmp, 0 );
2503 :
2504 141132 : return tmp;
2505 : }
2506 :
2507 : /*-------------------------------------------------------------------*
2508 : * lsp2isp()
2509 : *
2510 : * Convert LSPs to ISPs via predictor coefficients A[]
2511 : *-------------------------------------------------------------------*/
2512 :
2513 0 : void lsp2isp_fx(
2514 : const Word16 *lsp, /* i : LSP vector */
2515 : Word16 *isp, /* o : ISP filter coefficients */
2516 : Word16 *stable_isp, /* i/o: ISP filter coefficients */
2517 : const Word16 m /* i : order of LP analysis */
2518 : )
2519 : {
2520 : Word16 a[M + 1];
2521 :
2522 : /* LSP --> A */
2523 : /*lsp2a_stab( lsp, a, m );*/
2524 0 : E_LPC_f_lsp_a_conversion( lsp, a, m );
2525 :
2526 : /* A --> ISP */
2527 : /*a2isp( a, isp, stable_isp, grid );*/
2528 0 : E_LPC_a_isp_conversion( a, isp, stable_isp, m );
2529 :
2530 : /* Update to latest stable ISP */
2531 0 : Copy( isp, stable_isp, M );
2532 0 : }
2533 : /*-------------------------------------------------------------------*
2534 : * isp2lsp()
2535 : *
2536 : * Convert ISPs to LSPs via predictor coefficients A[]
2537 : *-------------------------------------------------------------------*/
2538 :
2539 0 : void isp2lsp_fx(
2540 : const Word16 *isp, /* i : LSP vector */
2541 : Word16 *lsp, /* o : ISP filter coefficients */
2542 : Word16 *stable_lsp, /* i/o: stable LSP filter coefficients */
2543 : const Word16 m /* i : order of LP analysis */
2544 : )
2545 : {
2546 : Word16 a[M + 1];
2547 :
2548 : /* ISP --> A */
2549 : /*isp2a( isp, a, m );*/
2550 0 : E_LPC_f_isp_a_conversion( isp, a, m );
2551 : /* A --> LSP */
2552 : /*a2lsp_stab( a, lsp, stable_lsp, grid );*/
2553 0 : E_LPC_a_lsp_conversion( a, lsp, stable_lsp, m );
2554 : /* Update to latest stable LSP */
2555 0 : Copy( lsp, stable_lsp, M );
2556 0 : }
2557 :
2558 : /*-------------------------------------------------------------------*
2559 : * lsf2isf()
2560 : *
2561 : * Convert LSPs to ISPs
2562 : *-------------------------------------------------------------------*/
2563 :
2564 0 : void lsf2isf_fx(
2565 : const Word16 *lsf, /* i : LSF vector */
2566 : Word16 *isf, /* o : ISF vector */
2567 : Word16 *stable_isp, /* i/o: stable ISP filter coefficients */
2568 : const Word16 m /* i : order of LP analysis */
2569 : )
2570 : {
2571 : Word16 tmp_lsp[M];
2572 : Word16 tmp_isp[M];
2573 :
2574 : /* LSF --> LSP */
2575 : /*lsf2lsp( lsf, tmp_lsp, m, int_fs );*/
2576 0 : E_LPC_lsf_lsp_conversion( lsf, tmp_lsp, m );
2577 :
2578 : /* LSP --> ISP */
2579 0 : lsp2isp_fx( tmp_lsp, tmp_isp, stable_isp, m );
2580 :
2581 : /* ISP --> ISF */
2582 : /*isp2isf( tmp_isp, isf, m, int_fs );*/
2583 0 : E_LPC_isp_isf_conversion( tmp_isp, isf, m );
2584 :
2585 0 : return;
2586 : }
2587 : /*-------------------------------------------------------------------*
2588 : * isf2lsf()
2589 : *
2590 : * Convert ISFs to LSFs
2591 : *-------------------------------------------------------------------*/
2592 :
2593 0 : void isf2lsf_fx(
2594 : const Word16 *isf, /* i : ISF vector */
2595 : Word16 *lsf, /* o : LSF vector */
2596 : Word16 *stable_lsp /* i/o: stable LSP filter coefficients */
2597 : )
2598 : {
2599 : Word16 tmp_isp[M];
2600 : Word16 tmp_lsp[M];
2601 :
2602 : /* ISF --> ISP */
2603 : /*isf2isp( isf, tmp_isp, m, int_fs );*/
2604 0 : E_LPC_isf_isp_conversion( isf, tmp_isp, M );
2605 : /* ISP --> LSP */
2606 0 : isp2lsp_fx( tmp_isp, tmp_lsp, stable_lsp, M );
2607 :
2608 : /* LSP --> LSF */
2609 : /*lsp2lsf( tmp_lsp, lsf, m, int_fs );*/
2610 0 : E_LPC_lsp_lsf_conversion( tmp_lsp, lsf, M );
2611 0 : return;
2612 : }
2613 : /*==========================================================================*/
2614 : /* FUNCTION : void lsp2lsf_fx () */
2615 : /*--------------------------------------------------------------------------*/
2616 : /* PURPOSE : */
2617 : /* * Transformation of LSPs to LSFs */
2618 : /* * LSP are line spectral pair in cosine domain (-1 to 1). */
2619 : /* * LSF are line spectral frequencies (0 to fs/2). */
2620 : /*--------------------------------------------------------------------------*/
2621 : /* INPUT ARGUMENTS : */
2622 : /* Word16 lsp[] i : lsp[m] (range: -1<=val<1) Q15 */
2623 : /* Word16 m i : LPC order Q0 */
2624 : /*--------------------------------------------------------------------------*/
2625 : /* OUTPUT ARGUMENTS : */
2626 : /* Word16 lsf[] o : lsf[m] normalized (range: 0.0<=val<=0.5) Q(x2.56)*/
2627 : /*--------------------------------------------------------------------------*/
2628 : /* INPUT/OUTPUT ARGUMENTS : */
2629 : /*--------------------------------------------------------------------------*/
2630 : /* RETURN ARGUMENTS : */
2631 : /* _ None */
2632 : /*--------------------------------------------------------------------------*/
2633 : /* CALLED FROM : */
2634 : /*==========================================================================*/
2635 391904 : void lsp2lsf_fx(
2636 : const Word16 lsp[], /* i : lsp[m] (range: -1<=val<1) Q15*/
2637 : Word16 lsf[], /* o : lsf[m] normalized (range: 0.0<=val<=0.5) Q(x2.56)*/
2638 : const Word16 m, /* i : LPC order Q0*/
2639 : const Word32 int_fs /* i : internal sampling frequency */
2640 : )
2641 : {
2642 : Word16 i;
2643 : Word32 L_tmp;
2644 :
2645 6173764 : FOR( i = 0; i < m; i++ )
2646 : {
2647 : /*------------------------------------------------------*
2648 : * find value in table that is just greater than lsp[i]
2649 : *------------------------------------------------------*/
2650 :
2651 : /* Retrieve Index Guess */
2652 : /* Based on lsp[i] */
2653 5781860 : L_tmp = sub_lsp2lsf_fx( lsp[i] );
2654 5781860 : IF( EQ_32( int_fs, INT_FS_16k_FX ) )
2655 : {
2656 2494720 : L_tmp = L_shr( L_mult0( extract_l( L_tmp ), 5 ), 2 );
2657 : }
2658 5781860 : lsf[i] = extract_l( L_tmp );
2659 5781860 : move16();
2660 : }
2661 391904 : }
2662 : /*===========================================================================*/
2663 : /* FUNCTION : lsf2lsp_fx() */
2664 : /*---------------------------------------------------------------------------*/
2665 : /* PURPOSE : Transformation of LSFs to LSPs */
2666 : /* LSP are line spectral pairs in cosine domain (-1 to 1). */
2667 : /* LSF are line spectral frequencies (0 to fs/2). */
2668 : /*---------------------------------------------------------------------------*/
2669 : /* INPUT ARGUMENTS : */
2670 : /* _ (Word16[]) lsf : lsf[m] normalized (range: 0.0<=val<=0.5) Q(x2.56) */
2671 : /* _ (Word16) m : LPC order */
2672 : /*---------------------------------------------------------------------------*/
2673 : /* OUTPUT ARGUMENTS : */
2674 : /* _ (Word16*) lsp : lsp[m] (range: -1<=val<1) Q15 */
2675 : /*---------------------------------------------------------------------------*/
2676 :
2677 : /*---------------------------------------------------------------------------*/
2678 : /* RETURN ARGUMENTS : */
2679 : /* _ None */
2680 : /*===========================================================================*/
2681 423351 : void lsf2lsp_fx(
2682 : const Word16 lsf[], /* i : lsf[m] normalized (range: 0.0<=val<=0.5) x2.56 */
2683 : Word16 lsp[], /* o : lsp[m] (range: -1<=val<1) Q15 */
2684 : const Word16 m, /* i : LPC order Q0 */
2685 : const Word32 int_fs /* i : internal sampling frequency */
2686 : )
2687 : {
2688 : Word16 i, ind, offset;
2689 : Word32 L_tmp;
2690 : Word16 c, ind2;
2691 423351 : Word16 const add_prec = 4;
2692 : Word16 lsf_tmp;
2693 :
2694 :
2695 : /* 0.75 = (1<<add_prec)*T_SIN_PI_2/(2.56f*3200.0f) */
2696 423351 : c = 24576 /*0.75f Q15*/;
2697 423351 : move16();
2698 423351 : if ( EQ_32( int_fs, INT_FS_16k_FX ) )
2699 : {
2700 : /* 0.6 = (1<<add_prec)*T_SIN_PI_2/(2.56f*4000.0f) */
2701 216666 : c = 19661 /*0.6f Q15*/;
2702 216666 : move16();
2703 : }
2704 7196967 : FOR( i = 0; i < m; i++ )
2705 : {
2706 : /* lsp[i] = cos(lsf[i] * EVS_PI / (int_fs/2)); */
2707 6773616 : L_tmp = L_shr( L_mult( lsf[i], c ), add_prec );
2708 6773616 : ind = extract_h( L_tmp );
2709 : /* interpolate cosine table at indexes ind and ind+1 */
2710 6773616 : ind2 = sub( T_SIN_PI_2, ind );
2711 6773616 : lsf_tmp = sincos_t_rad3_fx[s_max( ind2, negate( ind2 ) )];
2712 6773616 : if ( ind2 < 0 )
2713 : {
2714 3206010 : lsf_tmp = negate( lsf_tmp );
2715 : }
2716 6773616 : ind2 = sub( T_SIN_PI_2 - 1, ind );
2717 6773616 : offset = sincos_t_rad3_fx[s_max( ind2, negate( ind2 ) )];
2718 6773616 : if ( ind2 < 0 )
2719 : {
2720 3215137 : offset = negate( offset );
2721 : }
2722 6773616 : L_tmp = L_mult( sub_sat( offset, lsf_tmp ), round_fx( L_shl( L_and( L_tmp, 0xFFFF ), 15 ) ) );
2723 6773616 : L_tmp = L_msu( L_tmp, lsf_tmp, -32768 );
2724 6773616 : lsp[i] = round_fx( L_tmp );
2725 : }
2726 423351 : }
2727 :
2728 574 : void tcvq_Dec_fx(
2729 : Word16 *ind,
2730 : Word16 *d_out_fx,
2731 : const Word16 safety_net )
2732 : {
2733 : Word16 i;
2734 : Word16 index[9];
2735 : Word16 stage, state, branch[N_STAGE], codeword[N_STAGE];
2736 : Word16 fins, iwd;
2737 :
2738 : Word16 pred_fx[N_DIM];
2739 : Word16 D_fx[N_STAGE_VQ][N_DIM];
2740 : const Word16( *TCVQ_CB_SUB1_fx )[128][2], ( *TCVQ_CB_SUB2_fx )[64][2], ( *TCVQ_CB_SUB3_fx )[32][2];
2741 : const Word16( *IntraCoeff_fx )[2][2];
2742 :
2743 : /* mvs2s(ind, index, 9); */
2744 574 : Copy( ind, index, 9 );
2745 :
2746 574 : IF( safety_net )
2747 : {
2748 88 : TCVQ_CB_SUB1_fx = SN_TCVQ_CB_SUB1_fx;
2749 88 : TCVQ_CB_SUB2_fx = SN_TCVQ_CB_SUB2_fx;
2750 88 : TCVQ_CB_SUB3_fx = SN_TCVQ_CB_SUB3_fx;
2751 88 : IntraCoeff_fx = SN_IntraCoeff_fx;
2752 : }
2753 : ELSE
2754 : {
2755 486 : TCVQ_CB_SUB1_fx = AR_TCVQ_CB_SUB1_fx;
2756 486 : TCVQ_CB_SUB2_fx = AR_TCVQ_CB_SUB2_fx;
2757 486 : TCVQ_CB_SUB3_fx = AR_TCVQ_CB_SUB3_fx;
2758 486 : IntraCoeff_fx = AR_IntraCoeff_fx;
2759 : }
2760 :
2761 : /* Decode Final state */
2762 574 : fins = s_and( index[0], 15 );
2763 574 : move16();
2764 :
2765 : /* Decode Branch info */
2766 574 : branch[0] = shr( index[1], 4 );
2767 574 : move16();
2768 574 : branch[1] = shr( index[2], 4 );
2769 574 : move16();
2770 1722 : FOR( stage = 2; stage < N_STAGE_VQ - 4; stage++ )
2771 : {
2772 1148 : branch[stage] = shr( index[stage + 1], 3 );
2773 1148 : move16();
2774 : }
2775 :
2776 574 : branch[4] = s_and( fins, 0x1 );
2777 574 : move16();
2778 574 : branch[5] = s_and( shr( fins, 1 ), 0x1 );
2779 574 : move16();
2780 574 : branch[6] = s_and( shr( fins, 2 ), 0x1 );
2781 574 : move16();
2782 574 : branch[7] = s_and( shr( fins, 3 ), 0x1 );
2783 574 : move16();
2784 :
2785 : /* Decode Codeword info */
2786 1722 : FOR( stage = 0; stage < 2; stage++ )
2787 : {
2788 1148 : codeword[stage] = shl( s_and( index[stage + 1], 15 ), 3 );
2789 1148 : move16();
2790 : }
2791 :
2792 1722 : FOR( stage = 2; stage < N_STAGE_VQ - 4; stage++ )
2793 : {
2794 1148 : codeword[stage] = shl( s_and( index[stage + 1], 7 ), 3 );
2795 1148 : move16();
2796 : }
2797 :
2798 2870 : FOR( stage = N_STAGE_VQ - 4; stage < N_STAGE_VQ; stage++ )
2799 : {
2800 2296 : codeword[stage] = shl( s_and( index[stage + 1], 3 ), 3 );
2801 2296 : move16();
2802 : }
2803 :
2804 574 : state = shl( shr( fins, 2 ), 2 );
2805 :
2806 : /* stage #1 */
2807 574 : iwd = add( NTRANS2[branch[0] + 2][state], codeword[0] );
2808 : /* D[0][0] = TCVQ_CB_SUB1[0][iwd][0]; */
2809 : /* D[0][1] = TCVQ_CB_SUB1[0][iwd][1]; */
2810 574 : D_fx[0][0] = TCVQ_CB_SUB1_fx[0][iwd][0];
2811 574 : move16();
2812 574 : D_fx[0][1] = TCVQ_CB_SUB1_fx[0][iwd][1];
2813 574 : move16();
2814 574 : state = NTRANS2[branch[0]][state];
2815 574 : move16();
2816 :
2817 : /* stage #2 */
2818 : /* pred[0] = IntraCoeff[0][0][0] * D[0][0] + IntraCoeff[0][0][1]*D[0][1]; */
2819 : /* pred[1] = IntraCoeff[0][1][0] * D[0][0] + IntraCoeff[0][1][1]*D[0][1]; */
2820 574 : pred_fx[0] = add( mult_r( IntraCoeff_fx[0][0][0], D_fx[0][0] ), mult_r( IntraCoeff_fx[0][0][1], D_fx[0][1] ) );
2821 574 : move16();
2822 574 : pred_fx[1] = add( mult_r( IntraCoeff_fx[0][1][0], D_fx[0][0] ), mult_r( IntraCoeff_fx[0][1][1], D_fx[0][1] ) );
2823 574 : move16();
2824 :
2825 574 : iwd = add( NTRANS2[branch[1] + 2][state], codeword[1] );
2826 : /* D[1][0] = TCVQ_CB_SUB1[1][iwd][0] + pred[0]; */
2827 : /* D[1][1] = TCVQ_CB_SUB1[1][iwd][1] + pred[1]; */
2828 574 : D_fx[1][0] = add( TCVQ_CB_SUB1_fx[1][iwd][0], pred_fx[0] );
2829 574 : move16();
2830 574 : D_fx[1][1] = add( TCVQ_CB_SUB1_fx[1][iwd][1], pred_fx[1] );
2831 574 : move16();
2832 574 : state = NTRANS2[branch[1]][state];
2833 574 : move16();
2834 :
2835 : /* stage #3 - #4 */
2836 1722 : FOR( stage = 2; stage < N_STAGE_VQ - 4; stage++ )
2837 : {
2838 : /* pred[0] = IntraCoeff[stage-1][0][0] * D[stage-1][0] + IntraCoeff[stage-1][0][1]*D[stage-1][1]; */
2839 : /* pred[1] = IntraCoeff[stage-1][1][0] * D[stage-1][0] + IntraCoeff[stage-1][1][1]*D[stage-1][1]; */
2840 :
2841 1148 : pred_fx[0] = add( mult_r( IntraCoeff_fx[stage - 1][0][0], D_fx[stage - 1][0] ), mult_r( IntraCoeff_fx[stage - 1][0][1], D_fx[stage - 1][1] ) );
2842 1148 : move16();
2843 1148 : pred_fx[1] = add( mult_r( IntraCoeff_fx[stage - 1][1][0], D_fx[stage - 1][0] ), mult_r( IntraCoeff_fx[stage - 1][1][1], D_fx[stage - 1][1] ) );
2844 1148 : move16();
2845 :
2846 1148 : iwd = add( NTRANS2[branch[stage] + 2][state], codeword[stage] );
2847 : /* D[stage][0] = TCVQ_CB_SUB2[stage-2][iwd][0] + pred[0]; */
2848 : /* D[stage][1] = TCVQ_CB_SUB2[stage-2][iwd][1] + pred[1]; */
2849 1148 : D_fx[stage][0] = add( TCVQ_CB_SUB2_fx[stage - 2][iwd][0], pred_fx[0] );
2850 1148 : move16();
2851 1148 : D_fx[stage][1] = add( TCVQ_CB_SUB2_fx[stage - 2][iwd][1], pred_fx[1] );
2852 1148 : move16();
2853 1148 : state = NTRANS2[branch[stage]][state];
2854 1148 : move16();
2855 : }
2856 :
2857 : /* stage #5 - #8 */
2858 2870 : FOR( stage = N_STAGE_VQ - 4; stage < N_STAGE_VQ; stage++ )
2859 : {
2860 : /* pred[0] = IntraCoeff[stage-1][0][0] * D[stage-1][0] + IntraCoeff[stage-1][0][1]*D[stage-1][1]; */
2861 : /* pred[1] = IntraCoeff[stage-1][1][0] * D[stage-1][0] + IntraCoeff[stage-1][1][1]*D[stage-1][1]; */
2862 :
2863 2296 : pred_fx[0] = add( mult_r( IntraCoeff_fx[stage - 1][0][0], D_fx[stage - 1][0] ), mult_r( IntraCoeff_fx[stage - 1][0][1], D_fx[stage - 1][1] ) );
2864 2296 : move16();
2865 2296 : pred_fx[1] = add( mult_r( IntraCoeff_fx[stage - 1][1][0], D_fx[stage - 1][0] ), mult_r( IntraCoeff_fx[stage - 1][1][1], D_fx[stage - 1][1] ) );
2866 2296 : move16();
2867 :
2868 2296 : iwd = add( NTRANS2[branch[stage] + 2][state], codeword[stage] );
2869 : /* D[stage][0] = TCVQ_CB_SUB3[stage-4][iwd][0]; */
2870 : /* D[stage][1] = TCVQ_CB_SUB3[stage-4][iwd][1]; */
2871 2296 : D_fx[stage][0] = add( TCVQ_CB_SUB3_fx[stage - 4][iwd][0], pred_fx[0] );
2872 2296 : move16();
2873 2296 : D_fx[stage][1] = add( TCVQ_CB_SUB3_fx[stage - 4][iwd][1], pred_fx[1] );
2874 2296 : move16();
2875 2296 : state = NTRANS2[branch[stage]][state];
2876 2296 : move16();
2877 : }
2878 :
2879 5166 : FOR( stage = 0; stage < N_STAGE_VQ; stage++ )
2880 : {
2881 13776 : FOR( i = 0; i < N_DIM; i++ )
2882 : {
2883 : /* d_out[(N_DIM*stage) + i] = D[stage][i]; */
2884 9184 : d_out_fx[( N_DIM * stage ) + i] = D_fx[stage][i];
2885 9184 : move16();
2886 : }
2887 : }
2888 574 : return;
2889 : }
2890 :
2891 574 : Word16 qlsf_ARSN_tcvq_Dec_16k_fx(
2892 : Word16 *y_fx, /* o : Quantized LSF vector */
2893 : Word16 *indice, /* i : Indices */
2894 : const Word16 nBits /* i : number of bits */
2895 : )
2896 : {
2897 : Word16 i;
2898 : Word16 safety_net;
2899 :
2900 : Word16 error_svq_q_fx[M];
2901 :
2902 : /* Select Mode */
2903 574 : safety_net = indice[0];
2904 574 : move16();
2905 :
2906 :
2907 574 : IF( EQ_16( safety_net, 1 ) )
2908 : {
2909 88 : tcvq_Dec_fx( &indice[1], /*y, */ y_fx, safety_net );
2910 :
2911 88 : IF( GT_16( nBits, 30 ) )
2912 : {
2913 396 : FOR( i = 0; i < 8; i++ )
2914 : {
2915 352 : error_svq_q_fx[i] = AR_SVQ_CB1_fx[indice[10]][i];
2916 352 : move16();
2917 352 : error_svq_q_fx[i + 8] = AR_SVQ_CB2_fx[indice[11]][i];
2918 352 : move16();
2919 : }
2920 :
2921 748 : FOR( i = 0; i < M; i++ )
2922 : {
2923 704 : y_fx[i] = add( y_fx[i], extract_h( L_shl( L_mult0( error_svq_q_fx[i], scale_ARSN_fx[i] ), 2 ) ) );
2924 704 : move16();
2925 : }
2926 : }
2927 : }
2928 : ELSE
2929 : {
2930 486 : tcvq_Dec_fx( &indice[1], /*y, */ y_fx, safety_net );
2931 :
2932 486 : IF( GT_16( nBits, 30 ) )
2933 : {
2934 2358 : FOR( i = 0; i < 8; i++ )
2935 : {
2936 2096 : error_svq_q_fx[i] = AR_SVQ_CB1_fx[indice[10]][i];
2937 2096 : move16();
2938 2096 : error_svq_q_fx[i + 8] = AR_SVQ_CB2_fx[indice[11]][i];
2939 2096 : move16();
2940 : }
2941 :
2942 4454 : FOR( i = 0; i < M; i++ )
2943 : {
2944 4192 : y_fx[i] = add( y_fx[i], error_svq_q_fx[i] );
2945 4192 : move16();
2946 : }
2947 : }
2948 : }
2949 :
2950 574 : return safety_net;
2951 : }
2952 :
2953 : /*======================================================================*/
2954 : /* FUNCTION : lsf_syn_mem_backup_fx */
2955 : /*----------------------------------------------------------------------*/
2956 : /* PURPOSE : back-up synthesis filter memory and LSF qunatizer memories */
2957 : /*----------------------------------------------------------------------*/
2958 : /* INPUT ARGUMENTS : */
2959 : /* _ (Word16*) lsp_new : LSP vector to quantize */
2960 : /* _ (Word16*) lsf_new : quantized LSF vector */
2961 : /* _ (Word16*) lsp_mid : mid-frame LSP vector */
2962 : /* _ (Encoder_State) st_fx : Encoder state Structure */
2963 : /*----------------------------------------------------------------------*/
2964 : /* INPUT/OUTPUT ARGUMENTS : */
2965 : /* _None */
2966 : /*----------------------------------------------------------------------*/
2967 : /* OUTPUT ARGUMENTS : */
2968 : /* _ (Word16) clip_var : pitch clipping state var */
2969 : /* _ (Word16*) mem_AR : quantizer memory for AR model */
2970 : /* _ (Word16*) mem_MA : quantizer memory for MA model */
2971 : /* _ (Word16*) lsp_new_bck : LSP vector to quantize- backup */
2972 : /* _ (Word16*) lsf_new_bck : quantized LSF vector - backup */
2973 : /* _ (Word16*) lsp_mid_bck : mid-frame LSP vector - backup */
2974 : /* _ (Word16) mCb1 :counter for stationary frame after a transition frame */
2975 : /* _ (Word32*) Bin_E : FFT Bin energy 128 *2 sets */
2976 : /* _ (Word32*) Bin_E_old : FFT Bin energy 128 *2 sets */
2977 : /* _ (Word16*) mem_syn_bck : synthesis filter memory */
2978 : /* _ (Word16) mem_w0_bck : memory of the weighting filter */
2979 : /* _ (Word16) streaklimit : LSF quantizer */
2980 : /* _ (Word16) pstreaklen : LSF quantizer */
2981 : /*----------------------------------------------------------------------*/
2982 : /* _ None */
2983 : /*----------------------------------------------------------------------*/
2984 : /* RETURN ARGUMENTS : */
2985 : /* _ None */
2986 : /*======================================================================*/
2987 :
2988 0 : void lsf_syn_mem_backup_fx(
2989 : Encoder_State *st_fx, /* o: state structure */
2990 : Word16 *btilt_code_fx, /* i: Q15 */
2991 : Word32 *gc_threshold_fx, /* i: Q16 */
2992 : Word16 *clip_var_bck_fx, /* i: Q(2.56), Q14, Q7, Q0, Q14, Q14 */
2993 : Word16 *next_force_sf_bck_fx, /* i: */
2994 : Word16 *lsp_new, /* o: LSP vector to quantize Q15 */
2995 : Word16 *lsf_new, /* i: quantized LSF vector Q15 */
2996 : Word16 *lsp_mid, /* o: mid-frame LSP vector Q15 */
2997 : Word16 *clip_var, /* i: pitch clipping state var Q(2.56) */
2998 : Word16 *mem_AR, /* i: quantizer memory for AR model 2.56 */
2999 : Word16 *mem_MA, /* i: quantizer memory for MA model 2.56 */
3000 : Word16 *lsp_new_bck, /* i: LSP vector to quantize- backup Q15 */
3001 : Word16 *lsf_new_bck, /* o: quantized LSF vector - backup Q15 */
3002 : Word16 *lsp_mid_bck, /* i: mid-frame LSP vector - backup Q15 */
3003 : Word16 *mCb1, /* o: counter for stationary frame after a transition frame */
3004 : Word32 *Bin_E, /* i: FFT Bin energy 128 *2 sets q_bin */
3005 : Word32 *Bin_E_old, /* i: FFT Bin energy 128 sets q_bin */
3006 : Word16 *mem_syn_bck, /* i: synthesis filter memory q */
3007 : Word16 *mem_w0_bck, /* i: memory of the weighting filter q */
3008 : Word16 *streaklimit, /* i:LSF quantizer Q15 */
3009 : Word16 *pstreaklen /* i:LSF quantizer */
3010 : )
3011 : {
3012 : Word16 i;
3013 0 : LPD_state_HANDLE hLPDmem = st_fx->hLPDmem;
3014 :
3015 0 : *clip_var = st_fx->clip_var_fx[0];
3016 0 : move16();
3017 :
3018 0 : FOR( i = 0; i < M; i++ )
3019 : {
3020 0 : mem_AR[i] = st_fx->mem_AR_fx[i];
3021 0 : move16();
3022 0 : mem_MA[i] = st_fx->mem_MA_fx[i];
3023 0 : move16();
3024 0 : lsp_new_bck[i] = lsp_new[i];
3025 0 : move16();
3026 0 : lsf_new_bck[i] = lsf_new[i];
3027 0 : move16();
3028 0 : lsp_mid_bck[i] = lsp_mid[i];
3029 0 : move16();
3030 : }
3031 :
3032 0 : *mCb1 = st_fx->mCb1_fx;
3033 0 : move16();
3034 0 : *streaklimit = st_fx->streaklimit_fx;
3035 0 : move16();
3036 0 : *pstreaklen = st_fx->pstreaklen;
3037 0 : move16();
3038 :
3039 0 : FOR( i = 0; i < L_FFT; i++ )
3040 : {
3041 0 : Bin_E[i] = st_fx->Bin_E_fx[i];
3042 0 : move32();
3043 : }
3044 :
3045 0 : FOR( i = 0; i < ( L_FFT / 2 ); i++ )
3046 : {
3047 0 : Bin_E_old[i] = st_fx->Bin_E_old_fx[i];
3048 0 : move32();
3049 : }
3050 :
3051 : /* back-up memories */
3052 0 : FOR( i = 0; i < M; i++ )
3053 : {
3054 0 : mem_syn_bck[i] = hLPDmem->mem_syn[i];
3055 0 : move16();
3056 : }
3057 :
3058 0 : *mem_w0_bck = hLPDmem->mem_w0;
3059 0 : move16();
3060 :
3061 :
3062 0 : *btilt_code_fx = hLPDmem->tilt_code;
3063 0 : move16();
3064 0 : *gc_threshold_fx = hLPDmem->gc_threshold;
3065 0 : move16();
3066 0 : Copy( st_fx->clip_var_fx, clip_var_bck_fx, 6 );
3067 0 : *next_force_sf_bck_fx = st_fx->next_force_safety_net;
3068 0 : move16();
3069 :
3070 :
3071 0 : return;
3072 : }
3073 :
3074 :
3075 : /*-------------------------------------------------------------------*
3076 : * lsf_syn_mem_backup_fx()
3077 : *
3078 : *
3079 : *--------------------------------------------------------------------*/
3080 :
3081 0 : void lsf_syn_mem_backup_ivas_fx(
3082 : Encoder_State *st_fx, /* i: state structure */
3083 : Word16 *btilt_code_fx, /* i: tilt code Q15 */
3084 : Word32 *gc_threshold_fx, /* i: Q16 */
3085 : Word16 *clip_var_bck_fx, /* o: Q(2.56), Q14, Q7, Q0, Q14, Q14 */
3086 : Word16 *next_force_sf_bck_fx, /* o: */
3087 : Word16 *lsp_new, /* i: LSP vector to quantize Q15 */
3088 : Word16 *lsp_mid, /* i: mid-frame LSP vector Q15 */
3089 : Word16 *clip_var, /* o: pitch clipping state var Q(2.56) */
3090 : Word16 *mem_AR, /* o: quantizer memory for AR model Q(2.56) */
3091 : Word16 *mem_MA, /* o: quantizer memory for AR model Q(2.56) */
3092 : Word16 *lsp_new_bck, /* o: LSP vector to quantize- backup Q15 */
3093 : Word16 *lsp_mid_bck, /* o: mid-frame LSP vector - backup Q15 */
3094 : Word32 *Bin_E, /* o: FFT Bin energy 128 *2 sets Q_new + Q_SCALE - 2 */
3095 : Word32 *Bin_E_old, /* o: FFT Bin energy 128 sets Q_new + Q_SCALE - 2 */
3096 : Word16 *mem_syn_bck, /* o: synthesis filter memory ( 15 - st_fx->hLPDmem->e_mem_syn ) */
3097 : Word16 *mem_w0_bck, /* o: memory of the weighting filter ( 15 - st_fx->hLPDmem->e_mem_syn ) */
3098 : Word16 *streaklimit, /* Q15 */
3099 : Word16 *pstreaklen )
3100 : {
3101 : Word16 i;
3102 0 : LPD_state_HANDLE hLPDmem = st_fx->hLPDmem;
3103 :
3104 0 : *clip_var = st_fx->clip_var_fx[0];
3105 0 : move16();
3106 :
3107 0 : FOR( i = 0; i < M; i++ )
3108 : {
3109 0 : mem_AR[i] = st_fx->mem_AR_fx[i]; // Q2.56
3110 0 : move16();
3111 0 : mem_MA[i] = st_fx->mem_MA_fx[i]; // Q2.56
3112 0 : move16();
3113 0 : lsp_new_bck[i] = lsp_new[i]; // Q15
3114 0 : move16();
3115 0 : lsp_mid_bck[i] = lsp_mid[i]; // Q15
3116 0 : move16();
3117 : }
3118 :
3119 0 : *streaklimit = st_fx->streaklimit_fx; // Q15
3120 0 : move16();
3121 0 : *pstreaklen = st_fx->pstreaklen;
3122 0 : move16();
3123 :
3124 0 : FOR( i = 0; i < L_FFT; i++ )
3125 : {
3126 0 : Bin_E[i] = st_fx->Bin_E_fx[i]; // Q_new + Q_SCALE - 2
3127 0 : move32();
3128 : }
3129 :
3130 0 : FOR( i = 0; i < ( L_FFT / 2 ); i++ )
3131 : {
3132 0 : Bin_E_old[i] = st_fx->Bin_E_old_fx[i]; // Q_new + Q_SCALE - 2
3133 0 : move32();
3134 : }
3135 :
3136 : /* back-up memories */
3137 0 : FOR( i = 0; i < M; i++ )
3138 : {
3139 0 : mem_syn_bck[i] = hLPDmem->mem_syn[i]; // Q( st_fx->hLPDmem->q_mem_syn )
3140 0 : move16();
3141 : }
3142 :
3143 0 : *mem_w0_bck = hLPDmem->mem_w0; // Q( st_fx->hLPDmem->q_mem_syn )
3144 0 : move16();
3145 :
3146 :
3147 0 : *btilt_code_fx = hLPDmem->tilt_code; // Q15
3148 0 : move16();
3149 0 : *gc_threshold_fx = hLPDmem->gc_threshold; // Q16
3150 0 : move16();
3151 0 : Copy( st_fx->clip_var_fx, clip_var_bck_fx, 6 );
3152 0 : *next_force_sf_bck_fx = st_fx->next_force_safety_net;
3153 0 : move16();
3154 :
3155 :
3156 0 : return;
3157 : }
3158 :
3159 14024 : void lsf_update_memory(
3160 : Word16 narrowband, /* i : narrowband flag */
3161 : const Word16 qlsf[], /* i : quantized lsf coefficients */
3162 : Word16 old_mem_MA[], /* i : MA memory */
3163 : Word16 mem_MA[], /* o : updated MA memory */
3164 : Word16 lpcorder /* i : LPC order */
3165 : )
3166 : {
3167 : Word16 i;
3168 :
3169 238408 : FOR( i = 0; i < lpcorder; ++i )
3170 : {
3171 224384 : move16();
3172 224384 : mem_MA[i] = sub( sub( qlsf[i], lsf_means[narrowband][i] ), mult_r( MU_MA_FX, old_mem_MA[i] ) );
3173 : }
3174 :
3175 14024 : return;
3176 : }
3177 :
3178 :
3179 : /*======================================================================*/
3180 : /* FUNCTION : lsf_syn_mem_restore_fx */
3181 : /*----------------------------------------------------------------------*/
3182 : /* PURPOSE : restore synthesis filter memory and LSF quantizer memories*/
3183 : /*----------------------------------------------------------------------*/
3184 : /* INPUT ARGUMENTS : */
3185 : /* _ (Word16) clip_var : pitch clipping state var */
3186 : /* _ (Word16*) mem_AR : quantizer memory for AR model */
3187 : /* _ (Word16*) mem_MA : quantizer memory for MA model */
3188 : /* _ (Word16*) lsp_new_bck : LSP vector to quantize- backup */
3189 : /* _ (Word16*) lsf_new_bck : quantized LSF vector - backup */
3190 : /* _ (Word16*) lsp_mid_bck : mid-frame LSP vector - backup */
3191 : /* _ (Word16) mCb1 :counter for stationary frame after a transition frame */
3192 : /* _ (Word32*) Bin_E : FFT Bin energy 128 *2 sets */
3193 : /* _ (Word32*) Bin_E_old : FFT Bin energy 128 *2 sets */
3194 : /* _ (Word16*) mem_syn_bck : synthesis filter memory */
3195 : /* _ (Word16) mem_w0_bck : memory of the weighting filter */
3196 : /* _ (Word16) streaklimit : LSF quantizer */
3197 : /* _ (Word16) pstreaklen : LSF quantizer */
3198 : /*----------------------------------------------------------------------*/
3199 : /* INPUT/OUTPUT ARGUMENTS : */
3200 : /* _None */
3201 : /*----------------------------------------------------------------------*/
3202 : /* OUTPUT ARGUMENTS : */
3203 : /* _ (Word16*) lsp_new : LSP vector to quantize */
3204 : /* _ (Word16*) lsf_new : quantized LSF vector */
3205 : /* _ (Word16*) lsp_mid : mid-frame LSP vector */
3206 : /* _ (Encoder_State) st_fx : Encoder state Structure */
3207 : /*----------------------------------------------------------------------*/
3208 : /* _ None */
3209 : /*----------------------------------------------------------------------*/
3210 : /* RETURN ARGUMENTS : */
3211 : /* _ None */
3212 : /*======================================================================*/
3213 :
3214 0 : void lsf_syn_mem_restore_fx(
3215 : Encoder_State *st_fx, /* o: state structure */
3216 : Word16 btilt_code_fx, /* i: Q15 */
3217 : Word32 gc_threshold_fx, /* i: Q16 */
3218 : Word16 *clip_var_bck_fx, /* i: Q(2.56), Q14, Q7, Q0, Q14, Q14 */
3219 : Word16 next_force_sf_bck_fx, /* i: */
3220 : Word16 *lsp_new, /* o: LSP vector to quantize Q15 */
3221 : Word16 *lsf_new, /* o: quantized LSF vector Q15 */
3222 : Word16 *lsp_mid, /* o: mid-frame LSP vector Q15 */
3223 : Word16 clip_var, /* i: pitch clipping state var Q(2.56) */
3224 : Word16 *mem_AR, /* i: quantizer memory for AR model Q15 */
3225 : Word16 *mem_MA, /* i: quantizer memory for MA model Q15 */
3226 : Word16 *lsp_new_bck, /* i: LSP vector to quantize- backup Q15 */
3227 : Word16 *lsf_new_bck, /* i: quantized LSF vector - backup Q15 */
3228 : Word16 *lsp_mid_bck, /* i: mid-frame LSP vector - backup Q15 */
3229 : Word16 mCb1, /* i: counter for stationary frame after a transition frame */
3230 : Word32 *Bin_E, /* i: FFT Bin energy 128 *2 sets Q_new + Q_SCALE - 2 */
3231 : Word32 *Bin_E_old, /* i: FFT Bin energy 128 sets Q_new + Q_SCALE - 2 */
3232 : Word16 *mem_syn_bck, /* i: synthesis filter memory ( 15 - st_fx->hLPDmem->e_mem_syn ) */
3233 : Word16 mem_w0_bck, /* i: memory of the weighting filter ( 15 - st_fx->hLPDmem->e_mem_syn ) */
3234 : Word16 streaklimit, /* i:LSF quantizer Q15 */
3235 : Word16 pstreaklen /* i:LSF quantizer */
3236 : )
3237 : {
3238 : Word16 i;
3239 0 : LPD_state_HANDLE hLPDmem = st_fx->hLPDmem;
3240 :
3241 : /* restore lsf memories */
3242 0 : st_fx->clip_var_fx[0] = clip_var;
3243 0 : move16();
3244 :
3245 0 : FOR( i = 0; i < M; i++ )
3246 : {
3247 0 : st_fx->mem_AR_fx[i] = mem_AR[i]; // 2.56
3248 0 : move16();
3249 0 : st_fx->mem_MA_fx[i] = mem_MA[i]; // 2.56
3250 0 : move16();
3251 0 : lsp_new[i] = lsp_new_bck[i]; // Q15
3252 0 : move16();
3253 0 : lsf_new[i] = lsf_new_bck[i]; // Q15
3254 0 : move16();
3255 0 : lsp_mid[i] = lsp_mid_bck[i]; // Q15
3256 0 : move16();
3257 : }
3258 :
3259 0 : st_fx->mCb1_fx = mCb1;
3260 0 : move16();
3261 0 : st_fx->streaklimit_fx = streaklimit; // Q15
3262 0 : move16();
3263 0 : st_fx->pstreaklen = pstreaklen;
3264 0 : move16();
3265 :
3266 0 : FOR( i = 0; i < L_FFT; i++ )
3267 : {
3268 0 : st_fx->Bin_E_fx[i] = Bin_E[i]; // Q_new + Q_SCALE - 2
3269 0 : move16();
3270 : }
3271 :
3272 0 : FOR( i = 0; i < ( L_FFT / 2 ); i++ )
3273 : {
3274 0 : st_fx->Bin_E_old_fx[i] = Bin_E_old[i]; // Q_new + Q_SCALE - 2
3275 0 : move32();
3276 : }
3277 :
3278 : /* restoring memories */
3279 0 : hLPDmem->mem_w0 = mem_w0_bck; // ( 15 - st_fx->hLPDmem->e_mem_syn )
3280 0 : move16();
3281 :
3282 0 : FOR( i = 0; i < M; i++ )
3283 : {
3284 0 : hLPDmem->mem_syn[i] = mem_syn_bck[i]; // ( 15 - st_fx->hLPDmem->e_mem_syn )
3285 0 : move16();
3286 : }
3287 :
3288 0 : move16();
3289 0 : move32();
3290 0 : move16();
3291 0 : hLPDmem->tilt_code = btilt_code_fx; // Q15
3292 0 : hLPDmem->gc_threshold = gc_threshold_fx; // Q16
3293 0 : move16();
3294 0 : move32();
3295 0 : Copy( clip_var_bck_fx, st_fx->clip_var_fx, 6 );
3296 0 : st_fx->next_force_safety_net = next_force_sf_bck_fx;
3297 0 : move16();
3298 :
3299 0 : return;
3300 : }
3301 :
3302 0 : void lsf_syn_mem_restore_ivas_fx(
3303 : Encoder_State *st_fx, /* o: state structure */
3304 : Word16 btilt_code_fx, /* i: Q15 */
3305 : Word32 gc_threshold_fx, /* i: Q16 */
3306 : Word16 *clip_var_bck_fx, /* i: Q(2.56), Q14, Q7, Q0, Q14, Q14 */
3307 : Word16 next_force_sf_bck_fx, /* i: */
3308 : Word16 *lsp_new, /* o: LSP vector to quantize Q15 */
3309 : Word16 *lsp_mid, /* o: mid-frame LSP vector Q15 */
3310 : Word16 clip_var, /* i: pitch clipping state var Q(2.56), Q14, Q7, Q0, Q14, Q14 */
3311 : Word16 *mem_AR, /* i: quantizer memory for AR model 2.56 */
3312 : Word16 *mem_MA, /* i: quantizer memory for MA model 2.56 */
3313 : Word16 *lsp_new_bck, /* i: LSP vector to quantize- backup Q15 */
3314 : Word16 *lsp_mid_bck, /* i: mid-frame LSP vector - backup Q15 */
3315 : Word32 *Bin_E, /* i: FFT Bin energy 128 *2 sets Q_new + Q_SCALE - 2 */
3316 : Word32 *Bin_E_old, /* i: FFT Bin energy 128 sets Q_new + Q_SCALE - 2 */
3317 : Word16 *mem_syn_bck, /* i: synthesis filter memory Q(15 - st_fx->hLPDmem->e_mem_syn ) */
3318 : Word16 mem_w0_bck, /* i: memory of the weighting filter Q(15 - st_fx->hLPDmem->e_mem_syn ) */
3319 : Word16 streaklimit, /* i:LSF quantizer Q15 */
3320 : Word16 pstreaklen /* i:LSF quantizer */
3321 : )
3322 : {
3323 : Word16 i;
3324 0 : LPD_state_HANDLE hLPDmem = st_fx->hLPDmem;
3325 :
3326 : /* restore lsf memories */
3327 0 : st_fx->clip_var_fx[0] = clip_var;
3328 0 : move16();
3329 :
3330 0 : FOR( i = 0; i < M; i++ )
3331 : {
3332 0 : st_fx->mem_AR_fx[i] = mem_AR[i]; // 2.56
3333 0 : move16();
3334 0 : st_fx->mem_MA_fx[i] = mem_MA[i]; // 2.56
3335 0 : move16();
3336 0 : lsp_new[i] = lsp_new_bck[i]; // Q15
3337 0 : move16();
3338 0 : lsp_mid[i] = lsp_mid_bck[i]; // Q15
3339 0 : move16();
3340 : }
3341 :
3342 0 : st_fx->streaklimit_fx = streaklimit; // Q15
3343 0 : move16();
3344 0 : st_fx->pstreaklen = pstreaklen;
3345 0 : move16();
3346 :
3347 0 : FOR( i = 0; i < L_FFT; i++ )
3348 : {
3349 0 : st_fx->Bin_E_fx[i] = Bin_E[i]; // Q_new + Q_SCALE - 2
3350 0 : move16();
3351 : }
3352 :
3353 0 : FOR( i = 0; i < ( L_FFT / 2 ); i++ )
3354 : {
3355 0 : st_fx->Bin_E_old_fx[i] = Bin_E_old[i]; // Q_new + Q_SCALE - 2
3356 0 : move32();
3357 : }
3358 :
3359 : /* restoring memories */
3360 0 : hLPDmem->mem_w0 = mem_w0_bck; // Q( st_fx->hLPDmem->q_mem_syn )
3361 0 : move16();
3362 :
3363 0 : FOR( i = 0; i < M; i++ )
3364 : {
3365 0 : hLPDmem->mem_syn[i] = mem_syn_bck[i]; // Q( st_fx->hLPDmem->q_mem_syn )
3366 0 : move16();
3367 : }
3368 :
3369 0 : move16();
3370 0 : hLPDmem->tilt_code = btilt_code_fx; // Q15
3371 0 : move32();
3372 0 : hLPDmem->gc_threshold = gc_threshold_fx; // Q16
3373 0 : Copy( clip_var_bck_fx, st_fx->clip_var_fx, 6 );
3374 0 : st_fx->next_force_safety_net = next_force_sf_bck_fx;
3375 0 : move16();
3376 :
3377 0 : return;
3378 : }
3379 :
3380 : /* Returns: codebook index */
3381 28048 : Word16 tcxlpc_get_cdk(
3382 : Word16 acelp_ext_mode /* (I) GC/VC indicator */
3383 : )
3384 : {
3385 : Word16 cdk;
3386 :
3387 28048 : move16();
3388 28048 : cdk = 0;
3389 28048 : if ( EQ_16( acelp_ext_mode, VOICED ) )
3390 : {
3391 4550 : cdk = 1;
3392 4550 : move16();
3393 : }
3394 :
3395 28048 : return cdk;
3396 : }
3397 :
3398 32394 : void msvq_dec(
3399 : const Word16 *const *cb, /* i : Codebook (indexed cb[*stages][levels][p]) (14Q1*1.28)*/
3400 : const Word16 dims[], /* i : Dimension of each codebook stage (NULL: full dim.) */
3401 : const Word16 offs[], /* i : Starting dimension of each codebook stage (NULL: 0) */
3402 : const Word16 stages, /* i : Number of stages */
3403 : const Word16 N, /* i : Vector dimension */
3404 : const Word16 maxN, /* i : Codebook dimension */
3405 : const Word16 Idx[], /* i : Indices */
3406 : Word16 *uq /* o : quantized vector (14Q1*1.28)*/
3407 : )
3408 : {
3409 : Word16 i, j, offset;
3410 : Word16 N34;
3411 : Word16 n, maxn, start;
3412 :
3413 :
3414 32394 : set16_fx( uq, 0, N );
3415 :
3416 120884 : FOR( i = 0; i < stages; i++ )
3417 : {
3418 88490 : n = N;
3419 88490 : move16();
3420 88490 : maxn = maxN;
3421 88490 : move16();
3422 88490 : if ( dims )
3423 : {
3424 88490 : n = dims[i];
3425 88490 : move16();
3426 : }
3427 88490 : if ( dims )
3428 : {
3429 88490 : maxn = n;
3430 88490 : move16();
3431 : }
3432 88490 : assert( ( maxn % 4 ) == 0 );
3433 88490 : N34 = mult( maxn, 24576 /*0.75 Q15*/ );
3434 :
3435 88490 : start = 0;
3436 88490 : move16();
3437 88490 : if ( offs )
3438 : {
3439 88490 : start = offs[i];
3440 88490 : move16();
3441 : }
3442 : {
3443 : /*vr_add( uq+start, cb[i]+Idx[i]*maxn, uq+start, n );, where uq = a zero vector*/
3444 88490 : offset = i_mult2( Idx[i], N34 );
3445 :
3446 345268 : FOR( j = 0; j < n; j += 4 )
3447 : {
3448 : Word16 val0, val1, val2, val3;
3449 :
3450 256778 : depack_4_values( cb[i] + offset + i_mult( 3, ( shr( j, 2 ) ) ), val0, val1, val2, val3 );
3451 :
3452 256778 : uq[start + j + 0] = add( uq[start + j + 0], val0 );
3453 256778 : move16(); /*14Q1*1.28*/
3454 256778 : uq[start + j + 1] = add( uq[start + j + 1], val1 );
3455 256778 : move16(); /*14Q1*1.28*/
3456 256778 : uq[start + j + 2] = add( uq[start + j + 2], val2 );
3457 256778 : move16(); /*14Q1*1.28*/
3458 256778 : uq[start + j + 3] = add( uq[start + j + 3], val3 );
3459 256778 : move16(); /*14Q1*1.28*/
3460 : }
3461 : }
3462 : }
3463 :
3464 :
3465 32394 : return;
3466 : }
3467 :
3468 : /*
3469 : * E_LPC_lsp_lsf_conversion
3470 : *
3471 : * Parameters:
3472 : * lsp I: lsp[m] (range: -1 <= val < 1) Q15
3473 : * lsf O: lsf[m] normalized (range: 0 <= val <= 6400)
3474 : * m I: LPC order
3475 : *
3476 : * Function:
3477 : * Transformation lsp to lsf
3478 : *
3479 : * LSP are line spectral pair in cosine domain (-1 to 1). (0Q15)
3480 : * LSF are line spectral pair in frequency domain (0 to 6400).
3481 : *
3482 : * Returns:
3483 : * energy of prediction error
3484 : */
3485 21185 : void E_LPC_lsp_lsf_conversion( const Word16 lsp[], Word16 lsf[], const Word16 m )
3486 : {
3487 : Word16 i;
3488 :
3489 21185 : assert( m == 16 || m == 10 );
3490 :
3491 :
3492 360145 : FOR( i = 0; i < m; i++ )
3493 : {
3494 338960 : lsf[i] = xsp_to_xsf( lsp[i] );
3495 338960 : move16();
3496 : }
3497 :
3498 :
3499 21185 : return;
3500 : }
3501 :
3502 : /*
3503 : * E_LPC_lsf_lsp_conversion
3504 : *
3505 : * Parameters:
3506 : * lsf I: lsf[m] normalized (range: 0 <= val <= 0.5) x2.56
3507 : * lsp O: lsp[m] (range: -1 <= val < 1) Q15
3508 : * m I: LPC order
3509 : *
3510 : * Function:
3511 : * Transformation lsf to lsp
3512 : *
3513 : * LSF are line spectral pair in frequency domain (0 to 6400).
3514 : * LSP are line spectral pair in cosine domain (-1 to 1).
3515 : *
3516 : * Returns:
3517 : * void
3518 : */
3519 256924 : void E_LPC_lsf_lsp_conversion( const Word16 lsf[], Word16 lsp[], const Word16 m )
3520 : {
3521 : Word16 i;
3522 :
3523 256924 : assert( m == 16 || m == 10 );
3524 :
3525 : /* convert ISFs to the cosine domain */
3526 3720296 : FOR( i = 0; i < m; i++ )
3527 : {
3528 3463372 : *lsp++ = xsf_to_xsp( *lsf++ );
3529 3463372 : move16();
3530 : }
3531 :
3532 :
3533 256924 : return;
3534 : }
3535 :
3536 : /*==========================================================================*/
3537 : /* FUNCTION : void sub_lsp2lsf_fx () */
3538 : /*--------------------------------------------------------------------------*/
3539 : /* PURPOSE : */
3540 : /* * Transformation of LSPs to LSFs */
3541 : /* * LSP are line spectral pair in cosine domain (-1 to 1). */
3542 : /* * LSF are line spectral frequencies (0 to fs/2). */
3543 : /*--------------------------------------------------------------------------*/
3544 : /* INPUT ARGUMENTS : */
3545 : /* Word16 lsp_i i : lsp[m] (range: -1<=val<1) Q15 */
3546 : /* Word16 m i : LPC order Q0 */
3547 : /*--------------------------------------------------------------------------*/
3548 : /* OUTPUT ARGUMENTS : */
3549 : /* Word32 lsf[] o : lsf[m] normalized (range: 0.0<=val<=0.5) Q(x2.56)<<16 */
3550 : /*--------------------------------------------------------------------------*/
3551 : /* INPUT/OUTPUT ARGUMENTS : */
3552 : /*--------------------------------------------------------------------------*/
3553 : /* RETURN ARGUMENTS : */
3554 : /* _ None */
3555 : /*--------------------------------------------------------------------------*/
3556 : /* CALLED FROM : */
3557 : /*==========================================================================*/
3558 5781860 : Word32 sub_lsp2lsf_fx(
3559 : const Word16 lsp_i /* i : lsp[m] (range: -1<=val<1) Q15*/
3560 : )
3561 : {
3562 : Word16 ind, tmp;
3563 : Word32 L_tmp;
3564 :
3565 : /*------------------------------------------------------*
3566 : * find value in table that is just greater than lsp[i]
3567 : *------------------------------------------------------*/
3568 :
3569 : /* Retrieve Index Guess */
3570 : /* Based on lsp[i] */
3571 5781860 : ind = mac_r( GUESS_TBL_SZ / 2 * 65536 - 0x8000, lsp_i, GUESS_TBL_SZ / 2 );
3572 5781860 : ind = Ind_Guess[ind];
3573 5781860 : move16();
3574 :
3575 : /* Correct Index so that */
3576 : /* table[ind] > lsp[i] */
3577 5781860 : tmp = sub( lsp_i, cos_table_129[ind] );
3578 : /*
3579 : 69%: (Final Index - Index Guess) is <= 1
3580 : 28%: (Final Index - Index Guess) is 2
3581 : 2%: (Final Index - Index Guess) is >= 3
3582 : <1%: ...
3583 : */
3584 5781860 : IF( tmp > 0 ) /* possible range 0 to -5 (-1-2-2) */
3585 : {
3586 1815162 : ind = sub( ind, 1 );
3587 1815162 : tmp = sub( lsp_i, cos_table_129[ind] );
3588 1815162 : IF( tmp > 0 )
3589 : {
3590 206086 : ind = sub( ind, 2 );
3591 206086 : tmp = sub( lsp_i, cos_table_129[ind] );
3592 206086 : if ( tmp > 0 )
3593 : {
3594 20546 : ind = sub( ind, 2 );
3595 : }
3596 206086 : tmp = sub( lsp_i, cos_table_129[ind + 1] );
3597 206086 : if ( tmp <= 0 )
3598 : {
3599 165947 : ind = add( ind, 1 );
3600 : }
3601 206086 : tmp = sub( lsp_i, cos_table_129[ind] );
3602 : }
3603 : }
3604 :
3605 : /* acos(lsp[i])= ind*128 + (lsp[i]-table[ind]) * acos_slope[ind] / 2048 */
3606 5781860 : L_tmp = L_mac( 1L << 11, tmp, acos_slope[ind] );
3607 5781860 : L_tmp = L_shr( L_tmp, 12 ); /* (lsp[i]-table[ind]) * acos_slope[ind]) >> 11 */
3608 5781860 : L_tmp = L_mac0( L_tmp, ind, 128 );
3609 :
3610 5781860 : return L_tmp;
3611 : }
3612 :
3613 : /*===================================================================*/
3614 : /* FUNCTION : compute_poly_product_fx () */
3615 : /*-------------------------------------------------------------------*/
3616 : /* PURPOSE : Compute polynomial product for P(z) for LSP */
3617 : /* to LPC conversion */
3618 : /*-------------------------------------------------------------------*/
3619 : /* INPUT ARGUMENTS : */
3620 : /* _ (Word16[]) coef : LSP coefficients, Q15 */
3621 : /* _ (Word16 []) order: LPC order */
3622 : /*-------------------------------------------------------------------*/
3623 : /* OUTPUT ARGUMENTS : */
3624 : /* _ (Word32[]) p : output sequence, Q24 */
3625 : /* 1st entry is always 1.0, Q24 */
3626 : /*-------------------------------------------------------------------*/
3627 : /* INPUT/OUTPUT ARGUMENTS : */
3628 : /* _ None */
3629 : /*-------------------------------------------------------------------*/
3630 : /* RETURN ARGUMENTS : */
3631 : /* _ None */
3632 : /*===================================================================*/
3633 : /* NOTE: */
3634 : /* P(z)=(1+z^-1)*PI(j=1to(order/2)) (1 - 2*z^-1*cos(2*pi*w(2j-1)) + z^-2) */
3635 : /* Q(z)=(1-z^-1)*PI(j=1to(order/2)) (1 - 2*z^-1*cos(2*pi*w(2j)) + z^-2) */
3636 : /*===================================================================*/
3637 13818 : void compute_poly_product_fx(
3638 : Word16 *coef, /* i : LSP coefficients, Q15 */
3639 : Word32 *p, /* o : output sequence, Q24 */
3640 : Word16 order /* i : order */
3641 : )
3642 : {
3643 : Word16 i, len;
3644 : Word32 lspcos[LPC_SHB_ORDER];
3645 : Word32 p2[LPC_SHB_ORDER]; /* intermediate product, Q24*/
3646 : Word32 *p_in, *p_out, *p_temp;
3647 :
3648 50392 : FOR( i = 0; i < order / 2; i++ )
3649 : {
3650 36574 : lspcos[i] = poscos_fx( coef[i * 2] );
3651 36574 : move32(); /* lspcos =-cos(lsp) in Q30*/
3652 : }
3653 :
3654 : /* Set up first polynomial for convolution (1 -2cos(w5) 1) */
3655 : /* First element of output is 1, all in Q24 */
3656 13818 : p[0] = L_deposit_h( 0x100 ); /* 1.0 in Q24 */
3657 13818 : p[2] = L_deposit_h( 0x100 ); /* 1.0 in Q24 */
3658 13818 : p[1] = L_shr( lspcos[order / 2 - 1], 5 ); /* p2[1]=-2cos(w5), Q24 */
3659 13818 : p2[0] = L_deposit_h( 0x100 ); /* 1.0 in Q24 */
3660 :
3661 13818 : len = 1;
3662 13818 : move16();
3663 :
3664 13818 : len = 1;
3665 13818 : p_in = p + 1; /* 2nd entry of input sequence */
3666 13818 : p_out = p2 + 1; /* 2nd entry of output sequence */
3667 36574 : FOR( i = 0; i < ( order / 2 - 1 ); i++ )
3668 : {
3669 22756 : lsp_convolve_fx( L_shr( lspcos[i], 5 ), p_in, p_out, len );
3670 :
3671 22756 : p_temp = p_in;
3672 22756 : p_in = p_out;
3673 22756 : p_out = p_temp; /* swap input/output buffer */
3674 22756 : len = add( len, 1 );
3675 : }
3676 :
3677 : /* if((order/2 - 1)%2 != 0) */
3678 13818 : IF( s_and( ( order / 2 - 1 ), 1 ) != 0 )
3679 : {
3680 14640 : FOR( i = 1; i <= order / 2; i++ )
3681 : {
3682 9760 : p[i] = p_in[i - 1];
3683 9760 : move32();
3684 : }
3685 : }
3686 13818 : }
3687 :
3688 : /*===================================================================*/
3689 : /* FUNCTION : lsp_convolve_fx ( ) */
3690 : /*-------------------------------------------------------------------*/
3691 : /* PURPOSE : Convolution of LSP polynomial for LSP to LPC */
3692 : /*-------------------------------------------------------------------*/
3693 : /* INPUT ARGUMENTS : */
3694 : /* _ ( Word32[]) p1 : 2nd entry of input sequence, Q24 */
3695 : /* 1st entry is 1.0, Q24 */
3696 : /* _ ( Word32) x : -2cos( w) in Q24 */
3697 : /* _ ( Word16) len: length of output-2 */
3698 : /*-------------------------------------------------------------------*/
3699 : /* OUTPUT ARGUMENTS : */
3700 : /* _ ( Word32[]) p2 : 2nd entry of output sequence, Q24 */
3701 : /* 1st entry is 1.0, Q24 */
3702 : /*-------------------------------------------------------------------*/
3703 : /* INPUT/OUTPUT ARGUMENTS : */
3704 : /* _ None */
3705 : /*-------------------------------------------------------------------*/
3706 : /* RETURN ARGUMENTS : */
3707 : /* _ None */
3708 : /*===================================================================*/
3709 : /* NOTE: Convolves ( 1 S 1) where S is the -2cos( w) value) with the */
3710 : /* long sequence where the input long sequence on consecutive calls */
3711 : /* is ( 1 X1 1), ( 1 X1 X2 X1), ( 1 X1 X2 X3 X2), ( 1 X1 X2 X3 X4 X3). */
3712 : /* ( Since the sequence is symmetric, we only need to output one */
3713 : /* entry beyond the center point for the next iteration). */
3714 : /* The 1st entry of the convolution is 1, the 2nd is X1+S1, and */
3715 : /* the rest have the form X( i-1) + X( i)*S + X( i+1). */
3716 : /* Final output sequence is ( 1 X1 X2 X3 X4 X5 X4) */
3717 : /*===================================================================*/
3718 22756 : void lsp_convolve_fx(
3719 : Word32 x,
3720 : Word32 *p1,
3721 : Word32 *p2,
3722 : Word16 len )
3723 : {
3724 : Word16 i, d1h, d1l, d2h, d2l;
3725 : Word32 Ltemp;
3726 : Word32 Lacc;
3727 :
3728 22756 : d1h = extract_h( x ); /* d1h in Q8 */
3729 22756 : d1l = extract_l( x ); /* d1l in Q24 */
3730 :
3731 22756 : Ltemp = L_add( x, p1[0] ); /* first output is p1[0]+x, Q24 */
3732 :
3733 22756 : p2[0] = Ltemp;
3734 22756 : move32();
3735 22756 : Ltemp = L_deposit_h( 0x100 ); /* Ltemp=1.0, Q24 */
3736 54450 : FOR( i = 0; i < len; i++ )
3737 : {
3738 31694 : Ltemp = L_add( Ltemp, p1[i + 1] ); /* Ltemp2=p1[i-1]+p1[i+1], Q24 */
3739 31694 : d2h = extract_h( p1[i] );
3740 31694 : d2l = extract_l( p1[i] );
3741 :
3742 : /* Lacc=L_mult_su( d1h,d2l); */
3743 31694 : Lacc = L_mult0( d1h, d2l );
3744 31694 : Lacc = L_mac0( Lacc, d2h, d1l );
3745 31694 : Lacc = L_add( L_shr( Lacc, 16 ), L_shr( L_mult( d1h, d2h ), 1 ) );
3746 : /* Lacc=p1[i]* x, Q16 */
3747 31694 : Lacc = L_add( L_shl( Lacc, 8 ), Ltemp ); /* Lacc=p1[i-1]+p1[i+1]+p1[i]*x, Q24 */
3748 :
3749 31694 : p2[i + 1] = Lacc;
3750 31694 : move32();
3751 :
3752 31694 : Ltemp = p1[i];
3753 31694 : move32();
3754 : } /* end for */
3755 :
3756 22756 : p2[i + 1] = p2[i - 1];
3757 22756 : move32();
3758 22756 : }
3759 :
3760 :
3761 : /*===================================================================*/
3762 : /* FUNCTION : poscos_fx ( ) */
3763 : /*-------------------------------------------------------------------*/
3764 : /* PURPOSE : Compute cosine by approximation */
3765 : /*-------------------------------------------------------------------*/
3766 : /* INPUT ARGUMENTS : */
3767 : /* */
3768 : /* _ ( Word16) w: angle in radians/pi, Q14 ( 0<=w<=16384) */
3769 : /*-------------------------------------------------------------------*/
3770 : /* OUTPUT ARGUMENTS : */
3771 : /* _ None */
3772 : /*-------------------------------------------------------------------*/
3773 : /* INPUT/OUTPUT ARGUMENTS : */
3774 : /* _ None */
3775 : /*-------------------------------------------------------------------*/
3776 : /* RETURN ARGUMENTS : */
3777 : /* _ ( Word32) : -cos( w) in Q30 */
3778 : /*===================================================================*/
3779 : /* NOTE: This function uses 4 coefficients in the approx formula */
3780 : /* Approx Formula: cos( w) = z + c1*z^3 + c2*z^5 + c3*z^7 + c4*z^9 */
3781 : /* where z = pi/2 - w, c1=-.1666665668, c2=.8333025139E-2, */
3782 : /* c3=-.198074182E-3, and c4=.2601903036E-5 */
3783 : /*===================================================================*/
3784 :
3785 :
3786 36574 : Word32 poscos_fx( Word16 w )
3787 : {
3788 : Word16 a, z, z2, z3, z5, z7, z9;
3789 : Word32 Ltemp;
3790 : Word32 Lacc;
3791 :
3792 36574 : IF( w == 0 )
3793 : {
3794 0 : return ( 0xc0000004 ); /* -1.0 in Q30 */
3795 : }
3796 : ELSE
3797 : {
3798 36574 : z = 0x2000;
3799 36574 : move16(); /* z=0.5 in Q14 */
3800 36574 : z = shl( sub( z, w ), 2 ); /* z = 0.5-w in Q16 */
3801 :
3802 36574 : a = 0x6488;
3803 36574 : move16(); /* a=pi in Q13 */
3804 36574 : z = mult_r( z, a ); /* z=pi*( 0.5-w), Q14 */
3805 36574 : z2 = mult_r( z, z ); /* z2=z^2, Q13 */
3806 36574 : z3 = round_fx( L_shl( L_mult0( z, z2 ), 0 ) ); /* z3=z^3, Q11 */
3807 36574 : z5 = mult_r( z2, z3 ); /* z5=z^5, Q9 */
3808 36574 : z7 = round_fx( L_shl( L_mult0( z2, z5 ), 0 ) ); /* z7=z^7, Q6 */
3809 36574 : z9 = round_fx( L_shl( L_mult0( z2, z7 ), 0 ) ); /* z9=z^9, Q3 */
3810 :
3811 36574 : Lacc = L_mult( z9, cos_coef_new[0] ); /* Lacc=c4*z^9, Q31, c4 in Q28 */
3812 36574 : Lacc = L_mac0( Lacc, z7, cos_coef_new[1] ); /* c3 in Q25 */
3813 36574 : Ltemp = L_shl( L_mult( z3, cos_coef_new[3] ), 1 ); /* Ltemp=c1*z^3, Q31, c1 in Q17 */
3814 36574 : Lacc = L_add( L_shr( Lacc, 1 ), Ltemp ); /* Lacc=c1*z^3+c3*z^7+c4*^z9, Q30 */
3815 36574 : Lacc = L_add( Lacc, L_deposit_h( z ) );
3816 36574 : Ltemp = L_mult( z5, cos_coef_new[2] ); /* Ltemp=-c2*z^5, Q29, cos_coef[2]=-c2 in Q19 */
3817 36574 : Lacc = L_sub( Lacc, L_shl( Ltemp, 1 ) ); /* Lacc=cos( w) in Q30 */
3818 :
3819 36574 : return L_negate( Lacc ); /* return -cos( w), Q30 */
3820 : } /* end else */
3821 : }
3822 : /*===================================================================*/
3823 : /* FUNCTION : root_search_fx ( ) */
3824 : /*-------------------------------------------------------------------*/
3825 : /* PURPOSE : Search root of the P or Q polynomial in a given */
3826 : /* interval using binary search */
3827 : /*-------------------------------------------------------------------*/
3828 : /* INPUT ARGUMENTS : */
3829 : /* _ ( Word16) low : Low index of the interval, Q9 ( 0-511) */
3830 : /* _ ( Word16) high : High index of the interval, Q9 ( 0-511) */
3831 : /* _ ( Word32 []) coef: polynomial coefficients, Q26 */
3832 : /* _ ( Word16) order : LPC order */
3833 : /*-------------------------------------------------------------------*/
3834 : /* OUTPUT ARGUMENTS : */
3835 : /* _ None */
3836 : /*-------------------------------------------------------------------*/
3837 : /* INPUT/OUTPUT ARGUMENTS : */
3838 : /* _ ( Word32) v_low: Polynomial value at low index, Q25 */
3839 : /*-------------------------------------------------------------------*/
3840 : /* RETURN ARGUMENTS : */
3841 : /* _ ( Word16) root in Q15, or 0xffff if no root is found */
3842 : /*===================================================================*/
3843 :
3844 0 : Word16 root_search_fx( Word16 low,
3845 : Word16 high,
3846 : Word32 *v_low,
3847 : Word32 *coef,
3848 : Word16 order )
3849 : {
3850 : Word16 f;
3851 : Word32 v_high, vh;
3852 : Word32 Ltemp, L_tmp1, L_tmp, Ltmp;
3853 : Word16 exp1, tmp;
3854 : #ifndef ISSUE_1836_replace_overflow_libcom
3855 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
3856 : Flag Overflow = 0;
3857 : #endif
3858 : #endif
3859 :
3860 0 : v_high = polynomial_eval_fx( high, coef, order ); /* v_high has the value at high index */
3861 :
3862 0 : IF( v_high != 0 )
3863 : {
3864 : /* No exact root found */
3865 0 : test();
3866 0 : IF( ( v_high ^ ( *v_low ) ) >= 0 )
3867 : {
3868 : /* No root in this interval ( low high] */
3869 0 : *v_low = v_high;
3870 0 : move32();
3871 0 : return ( -1 );
3872 : }
3873 : ELSE
3874 : {
3875 : /* there is a root in this interval */
3876 : /* Do binary search for root */
3877 0 : vh = v_high;
3878 0 : move16();
3879 :
3880 0 : WHILE( GE_16( sub( high, low ), 2 ) )
3881 : {
3882 : /* high-low>=2 */
3883 0 : f = shr( add( high, low ), 1 ); /* f=( high+low)/2 */
3884 0 : Ltemp = polynomial_eval_fx( f, coef, order );
3885 0 : IF( Ltemp == 0 )
3886 : {
3887 0 : *v_low = v_high;
3888 0 : move32(); /* Set low value for next root search call */
3889 0 : return ( shl( f, 6 ) );
3890 : }
3891 : ELSE
3892 : {
3893 0 : test();
3894 0 : IF( ( Ltemp ^ ( *v_low ) ) < 0 )
3895 : {
3896 : /* root between f & low */
3897 0 : high = f;
3898 0 : move16();
3899 0 : vh = Ltemp;
3900 0 : move32();
3901 : }
3902 : ELSE
3903 : {
3904 0 : *v_low = Ltemp;
3905 0 : move32();
3906 0 : low = f;
3907 0 : move16();
3908 : }
3909 : }
3910 : } /* end while */
3911 :
3912 : /* do interpolation for root in between high and low */
3913 : /* Lacc=divide_dp( *v_low, L_sub( *v_low,vh),2,1); // Lacc in Q31 */
3914 0 : L_tmp = L_sub( *v_low, vh );
3915 :
3916 0 : if ( LT_32( *v_low, vh ) )
3917 : {
3918 0 : L_tmp = L_negate( L_tmp );
3919 : }
3920 :
3921 0 : exp1 = norm_l( L_tmp );
3922 0 : L_tmp1 = L_shl( L_tmp, exp1 );
3923 0 : tmp = extract_h( L_tmp1 );
3924 0 : exp1 = sub( 30 - 25, exp1 );
3925 0 : tmp = div_s( 16384, tmp ); /* 15+exp1 */
3926 0 : Ltmp = Mult_32_16( *v_low, tmp ); /* 15+exp1+25-15 */
3927 : #ifdef ISSUE_1836_replace_overflow_libcom
3928 0 : Ltemp = L_shl_sat( Ltmp, ( 6 - exp1 ) ); /* Q31 */
3929 : #else
3930 : Ltemp = L_shl_o( Ltmp, ( 6 - exp1 ), &Overflow ); /* Q31 */
3931 : #endif
3932 0 : if ( LT_32( *v_low, vh ) )
3933 : {
3934 0 : Ltemp = L_negate( Ltemp );
3935 : }
3936 0 : Ltemp = L_shr( Ltemp, 9 ); /* Ltemp =quotient*1.0 in Q31 */
3937 :
3938 0 : *v_low = v_high;
3939 0 : move16();
3940 0 : return ( add( round_fx( Ltemp ), shl( low, 6 ) ) );
3941 : } /* end else ( root in interval) */
3942 : } /* end else ( exact root at high) */
3943 :
3944 : /* find the exact root */
3945 0 : *v_low = v_high;
3946 0 : move32(); /* Set low value for next root search call */
3947 0 : return ( shl( high, 6 ) ); /* return exact root at high in Q15 */
3948 : }
3949 :
3950 : /*===================================================================*/
3951 : /* FUNCTION : calc_weight( ) */
3952 : /*-------------------------------------------------------------------*/
3953 : /* PURPOSE : This function computes the weight given delta1
3954 : and delta2 */
3955 : /*-------------------------------------------------------------------*/
3956 : /* INPUT ARGUMENTS : */
3957 : /* _ (Word16) delta1: (Q15) */
3958 : /* _ (Word16) delta2: (Q15) */
3959 : /*-------------------------------------------------------------------*/
3960 : /* OUTPUT ARGUMENTS : */
3961 : /* _ (Word16 *) n1: o/p weight is Q(31-n1) */
3962 : /*-------------------------------------------------------------------*/
3963 : /* INPUT/OUTPUT ARGUMENTS : */
3964 : /* _ None. */
3965 : /*-------------------------------------------------------------------*/
3966 : /* RETURN ARGUMENTS : */
3967 : /* _ (Word32) Lsum1: computed weight Q(31-n1) */
3968 : /* (alpha/(sqrt(delta1*delta2)) */
3969 : /*===================================================================*/
3970 :
3971 0 : Word32 calc_weight(
3972 : Word16 delta1,
3973 : Word16 delta2,
3974 : Word16 *n1 )
3975 : {
3976 : Word16 n;
3977 : Word32 L_tmp;
3978 0 : Word16 alpha = 0x4F94;
3979 0 : move16(); /* ( 0.5*250/( 2*pi)) in Q10*/
3980 :
3981 0 : L_tmp = L_mult0( delta1, delta2 ); /* Q30 */
3982 0 : n = norm_l( L_tmp );
3983 0 : L_tmp = L_shl( L_tmp, n );
3984 0 : n = sub( 1, n );
3985 0 : L_tmp = Isqrt_lc( L_tmp, &n ); /* Q( 31-n)*/
3986 :
3987 0 : L_tmp = Mult_32_16( L_tmp, alpha ); /* Q( 26-n) */
3988 :
3989 0 : *n1 = n;
3990 0 : move16();
3991 :
3992 0 : return L_tmp;
3993 : }
3994 :
3995 : /*===================================================================*/
3996 : /* FUNCTION : polynomial_eval_fx ( ) */
3997 : /*-------------------------------------------------------------------*/
3998 : /* PURPOSE : Evaluate P or Q polynomial at given frequency */
3999 : /*-------------------------------------------------------------------*/
4000 : /* INPUT ARGUMENTS : */
4001 : /* _ (Word16) f : frequency used as index for cosine table lookup */
4002 : /* Q9 */
4003 : /* _ (Word32 []) coef: polynomial coefficients, Q26 */
4004 : /* _ (Word16 []) order: LPC order */
4005 : /*-------------------------------------------------------------------*/
4006 : /* OUTPUT ARGUMENTS : */
4007 : /* _ None */
4008 : /*-------------------------------------------------------------------*/
4009 : /* INPUT/OUTPUT ARGUMENTS : */
4010 : /* _ None */
4011 : /*-------------------------------------------------------------------*/
4012 : /* RETURN ARGUMENTS : */
4013 : /* _ (Word32) polynomial value at given frequency f, Q25 */
4014 : /*===================================================================*/
4015 : /* Note: This function uses 512 entry cosine table cos_table[], Q15 */
4016 : /*===================================================================*/
4017 : /* if (K = order/2) */
4018 : /* P(w)=cos(Kw)+p[1]*cos((K-1)w)+p[2]*cos((K-2)w)+...+p[(K-1)]*cos(w)+p[K]/2 */
4019 : /* Q(w)=cos(Kw)+q[1]*cos((K-1)w)+q[2]*cos((K-2)w)+...+q[(K-1)]*cos(w)+q[K]/2 */
4020 : /*===================================================================*/
4021 :
4022 : /* 40-32 bit conversion */
4023 0 : Word32 polynomial_eval_fx( Word16 f,
4024 : Word32 *coef,
4025 : Word16 order )
4026 : {
4027 : Word16 i, idx;
4028 : Word16 dh, dl, coslut;
4029 : Word32 Ltemp, L_tmp1, L_tmp;
4030 : Word32 Lacc;
4031 0 : idx = f;
4032 0 : move16();
4033 0 : dh = extract_h( coef[order / 2] ); /* Q10 */
4034 0 : dl = extract_l( coef[order / 2] ); /* Q16 */
4035 :
4036 0 : coslut = 0x4000;
4037 0 : move16(); /* coslut=0.5 in Q15 */
4038 0 : Ltemp = L_mult0( coslut, dh ); /* Ltemp=MSW, coef[5]/2 in Q25 */
4039 :
4040 0 : Lacc = L_mult0( coslut, dl ); /* Lacc=LSW, coef[5]/2 in Q41 //Q31 */
4041 0 : Lacc = L_shr( Lacc, 1 ); /* Q30 */
4042 0 : FOR( i = ( order / 2 ) - 1; i > 0; i-- )
4043 : {
4044 0 : coslut = cos_table[idx];
4045 0 : move16(); /* coslut=cos( ( ( order/2)-i)f), Q15 */
4046 0 : dh = extract_h( coef[i] ); /* Q10 */
4047 0 : dl = extract_l( coef[i] ); /* Q16 */
4048 :
4049 0 : Ltemp = L_add( Ltemp, L_mult0( dh, coslut ) ); /* Q25 */
4050 0 : IF( dl < 0 )
4051 : {
4052 0 : L_tmp1 = L_shl( L_add( 65536, dl ), 14 );
4053 0 : L_tmp = Mult_32_16( L_tmp1, coslut );
4054 0 : Lacc = L_add( Lacc, L_tmp );
4055 : }
4056 : ELSE
4057 : {
4058 0 : Lacc = L_add( Lacc, L_shr( L_mult0( coslut, dl ), 1 ) ); /* Q30 */
4059 : }
4060 :
4061 0 : idx += f;
4062 0 : if ( GE_16( idx, 512 ) )
4063 0 : idx = sub( idx, 512 ); /* modulo of 512 */
4064 : }
4065 :
4066 0 : coslut = cos_table[idx];
4067 0 : move16(); /* coslut=cos( 5f), Q15 */
4068 0 : Ltemp = L_add( Ltemp, L_mult0( 0x400, coslut ) ); /* coef[0]=1.0, Q25 */
4069 :
4070 0 : return ( L_add( Ltemp, L_shr( Lacc, 15 ) ) ); /* Q25 */
4071 : }
4072 :
4073 : /*----------------------------------------------------------------------------------*
4074 : * v_sort:
4075 : *
4076 : * This is very fast with almost ordered vectors. The first 15 ISF values
4077 : * are almost always sorted.
4078 : *----------------------------------------------------------------------------------*/
4079 3119 : void v_sort(
4080 : Word16 *r, /* i/o: Vector to be sorted in place */
4081 : const Word16 lo, /* i : Low limit of sorting range */
4082 : const Word16 up /* I : High limit of sorting range */
4083 : )
4084 : {
4085 : Word16 i, j;
4086 : Word16 tempr;
4087 :
4088 :
4089 31190 : FOR( i = sub( up, 1 ); i >= lo; i-- )
4090 : {
4091 28071 : tempr = r[i];
4092 28071 : move16();
4093 28078 : FOR( j = i; j < up; j++ )
4094 : {
4095 28078 : IF( LE_16( tempr, r[j + 1] ) )
4096 : {
4097 28071 : BREAK;
4098 : }
4099 7 : r[j] = r[j + 1];
4100 7 : move16();
4101 : }
4102 28071 : r[j] = tempr;
4103 28071 : move16();
4104 : }
4105 :
4106 :
4107 3119 : return;
4108 : }
4109 :
4110 2900 : void dec_FDCNG_MSVQ_stage1_fx(
4111 : Word16 j_full, /* i : index full range */
4112 : Word16 n, /* i : dimension to generate */
4113 : const Word32 *invTrfMatrix, /* i : IDCT matrix for synthesis Q31 */
4114 : const DCTTYPE idcttype, /* i : specify which IDCT */
4115 : Word32 *uq, /* o : synthesized stage1 vector Q20 */
4116 : Word16 *uq_ind /* o : synthesized stage1 vector in BASOP */
4117 : )
4118 : {
4119 : Word16 col, segm_ind, j, i;
4120 : Word32 dct_vec[FDCNG_VQ_MAX_LEN];
4121 : const Word8 *cbpW8;
4122 : const Word16 *dct_col_shift_tab;
4123 : Word32 dct_vec_fx[FDCNG_VQ_MAX_LEN];
4124 : Word32 idct_vec_fx[FDCNG_VQ_MAX_LEN];
4125 2900 : assert( n <= FDCNG_VQ_MAX_LEN );
4126 2900 : assert( n >= FDCNG_VQ_DCT_MINTRUNC );
4127 :
4128 2900 : segm_ind = 0;
4129 2900 : move16();
4130 14500 : FOR( col = 1; col <= FDCNG_VQ_DCT_NSEGM; col++ )
4131 : {
4132 11600 : if ( GE_16( j_full, cdk1_ivas_cum_entries_per_segment[col] ) )
4133 : {
4134 5715 : segm_ind = add( segm_ind, 1 );
4135 : }
4136 : }
4137 :
4138 2900 : j = sub( j_full, cdk1_ivas_cum_entries_per_segment[segm_ind] ); /* j is the local segment index */
4139 :
4140 :
4141 : /* Word8 column variable Qx storage*/
4142 2900 : cbpW8 = cdk_37bits_ivas_stage1_W8Qx_dct_sections[segm_ind]; /* Word8 storage fixed ptr_init */
4143 2900 : cbpW8 += imult1616( j, cdk1_ivas_cols_per_segment[segm_ind] ); /* adaptive ptr init */
4144 2900 : dct_col_shift_tab = stage1_dct_col_syn_shift[segm_ind];
4145 :
4146 44386 : FOR( col = 0; col < cdk1_ivas_cols_per_segment[segm_ind]; col++ )
4147 : {
4148 41486 : dct_vec[col] = shl( cbpW8[col], dct_col_shift_tab[col] ); // Q0
4149 41486 : move32();
4150 : /* LOGIC( 1 ) , SHIFT( 1 );
4151 : in BASOP: s_and(for W8->W16), shl()
4152 : */
4153 : }
4154 2900 : assert( j < cdk1_ivas_entries_per_segment[segm_ind] );
4155 :
4156 2900 : Word16 norm = 20;
4157 2900 : move16();
4158 :
4159 44386 : FOR( i = 0; i < cdk1_ivas_cols_per_segment[segm_ind]; i++ )
4160 : {
4161 41486 : dct_vec_fx[i] = L_shl( dct_vec[i], norm ); // Q20
4162 41486 : move32();
4163 : }
4164 :
4165 2900 : dctT2_N_apply_matrix_fx( (const Word32 *) dct_vec_fx, idct_vec_fx, cdk1_ivas_cols_per_segment[segm_ind], n, invTrfMatrix, FDCNG_VQ_DCT_MAXTRUNC, idcttype );
4166 :
4167 :
4168 : /*scale down to original fdcngvq domain and move to Q0 */
4169 : /* fdcng_dct_scaleF[1] --> Q15 conversion --> 860 */
4170 : // v_multc_att32( idct_vec_fx, 860, idct_vec_fx, n );
4171 70233 : FOR( i = 0; i < n; i++ )
4172 : {
4173 67333 : idct_vec_fx[i] = Mpy_32_32( idct_vec_fx[i], 56410112 ); /* norm + 31 - 31 = norm*/
4174 : // fdcng_dct_scaleF[1] -> 0.420288085937500f / 16.0f -> in Q31 -> 56410112
4175 67333 : move32();
4176 : }
4177 : /* fdcng_dct_scaleF[1] --> 0.0625-->scale down from search Q4 domain to Q0 ,
4178 : not really relevant for BASOP loop */
4179 :
4180 : /*add common mid fdcng vector, in fdcng bands domain */
4181 70233 : FOR( i = 0; i < n; i++ )
4182 : {
4183 67333 : uq[i] = L_add( idct_vec_fx[i], L_lshl( cdk1r_tr_midQ_truncQ_fx[i], sub( norm, Q10 ) ) ); // making the Q factors equal
4184 67333 : move32();
4185 : }
4186 2900 : assert( uq_ind == NULL );
4187 :
4188 2900 : return;
4189 : }
4190 :
4191 89061 : void msvq_dec_fx(
4192 : const Word16 *const *cb, /* i : Codebook (indexed cb[*stages][levels][p]) Q: (Q_cb) */
4193 : const Word16 dims[], /* i : Dimension of each codebook stage (NULL: full dim.) */
4194 : const Word16 offs[], /* i : Starting dimension of each codebook stage (NULL: 0) */
4195 : const Word16 stages, /* i : Number of stages */
4196 : const Word16 N, /* i : Vector dimension */
4197 : const Word16 maxN, /* i : Codebook dimension */
4198 : const Word16 Idx[], /* i : Indices */
4199 : const Word16 applyIDCT_flag, /* i : applyIDCT flag */
4200 : const Word32 *invTrfMatrix, /* i : matrix for IDCT synthesis Q31 */
4201 : Word32 *uq, /* o : quantized vector */
4202 : Word16 *uq_ind, /* o : quantized vector (fixed point) Q0 */
4203 : Word16 Q_cb )
4204 : {
4205 : Word16 i, n, maxn, start, k;
4206 89061 : Word16 j, max_size = 0;
4207 89061 : move16();
4208 :
4209 378227 : FOR( i = 0; i < stages; i++ )
4210 : {
4211 289166 : IF( dims )
4212 : {
4213 0 : if ( LT_16( max_size, dims[i] ) )
4214 : {
4215 0 : max_size = dims[i];
4216 0 : move16();
4217 : }
4218 : }
4219 : ELSE
4220 : {
4221 289166 : max_size = N;
4222 289166 : move16();
4223 : }
4224 : }
4225 :
4226 89061 : set32_fx( uq, 0, N );
4227 89061 : IF( uq_ind )
4228 : {
4229 0 : FOR( i = 0; i < N; ++i )
4230 : {
4231 0 : uq_ind[i] = 0;
4232 0 : move16();
4233 : }
4234 : }
4235 :
4236 378227 : FOR( i = 0; i < stages; i++ )
4237 : {
4238 289166 : IF( dims )
4239 : {
4240 0 : n = dims[i];
4241 0 : move16();
4242 0 : maxn = n;
4243 0 : move16();
4244 : }
4245 : ELSE
4246 : {
4247 289166 : n = N;
4248 289166 : move16();
4249 289166 : maxn = maxN;
4250 289166 : move16();
4251 : }
4252 289166 : IF( offs )
4253 : {
4254 0 : start = offs[i];
4255 0 : move16();
4256 : }
4257 : ELSE
4258 : {
4259 289166 : start = 0;
4260 289166 : move16();
4261 : }
4262 :
4263 289166 : Word16 guard_bits = find_guarded_bits_fx( max_size );
4264 289166 : IF( i == 0 )
4265 : {
4266 1534970 : FOR( k = 0; k < N; k++ )
4267 : {
4268 1445909 : uq[k] = L_shr( uq[k], guard_bits ); // 20 - guard_bits
4269 1445909 : move32();
4270 : }
4271 : }
4272 :
4273 289166 : test();
4274 289166 : IF( i == 0 && applyIDCT_flag != 0 )
4275 : {
4276 2900 : assert( start == 0 );
4277 2900 : dec_FDCNG_MSVQ_stage1_fx( Idx[0], N, invTrfMatrix, IDCT_T2_XX_24, uq, uq_ind ); /* IDCT_T2 N=24 used for all synthesis */
4278 70233 : FOR( k = 0; k < N; k++ )
4279 : {
4280 67333 : uq[k] = L_shr( uq[k], guard_bits ); // 20 - guard_bits
4281 67333 : move32();
4282 : }
4283 : }
4284 : ELSE
4285 : {
4286 : // v_add( uq + start, cb[i] + Idx[i] * maxn, uq + start, n );
4287 :
4288 4965623 : FOR( k = 0; k < n; k++ )
4289 : {
4290 4679357 : uq[start + k] = L_add( uq[start + k], L_lshl( cb[i][Idx[i] * maxn + k], sub( sub( 20, Q_cb ), guard_bits ) ) ); // 20 - guard_bits
4291 4679357 : move32();
4292 : }
4293 : }
4294 :
4295 : #define WMC_TOOL_SKIP
4296 289166 : IF( uq_ind != NULL )
4297 : {
4298 0 : FOR( j = 0; j < n; ++j )
4299 : {
4300 0 : uq_ind[start + j] = add( uq_ind[start + j], shl( mult( cb[i][Idx[i] * maxn + j], 20971 ), sub( add( 13, Q_cb ), 15 ) ) ); // Q0
4301 : // 2 * 1.28 in Q13 -> 20971
4302 0 : move16();
4303 : }
4304 : }
4305 : #undef WMC_TOOL_SKIP
4306 : }
4307 :
4308 89061 : return;
4309 : }
4310 :
4311 2900 : void dctT2_N_apply_matrix_fx(
4312 : const Word32 *input, /* i : input in fdcng or DCT(fdcng) domain Q20 */
4313 : Word32 *output, /* o : output in DCT(fdcng) or fdcng ordomain Q20 */
4314 : const Word16 dct_dim, /* i : dct processing dim possibly truncated */
4315 : const Word16 fdcngvq_dim, /* i : fdcng domain length */
4316 : const Word32 *matrix, /* i : IDCT matrix Q31 */
4317 : const Word16 matrix_row_dim, /* i : */
4318 : const DCTTYPE dcttype /* i : matrix operation type */
4319 : )
4320 : {
4321 : Word16 i, j, dim_in, dim_out;
4322 : Word16 mat_step_col, mat_step_row, mat_step_col_flag;
4323 : const Word32 *pt_x, *pt_A;
4324 : Word32 tmp_y[FDCNG_VQ_MAX_LEN];
4325 : Word32 *pt_y;
4326 :
4327 : /* non-square DCT_N and IDCT_N matrix application,
4328 : using a stored format of an IDCT_Nx(FDCNG_VQ_DCT_MAXTRUNC) matrix */
4329 : /* efficiently parallelized in SIMD */
4330 :
4331 2900 : assert( dct_dim <= FDCNG_VQ_DCT_MAXTRUNC );
4332 2900 : assert( fdcngvq_dim <= FDCNG_VQ_MAX_LEN );
4333 :
4334 2900 : IF( L_and( dcttype, 1 ) == 0 ) /* even entries are DCTs */
4335 : {
4336 : /* DCT_typeII 24,21 -> XX in worst case */
4337 0 : dim_in = fdcngvq_dim;
4338 0 : move16();
4339 0 : dim_out = dct_dim;
4340 0 : move16();
4341 0 : mat_step_col = matrix_row_dim; /* matrix maximum storage size dependent, width of first row in matrix */
4342 0 : move16();
4343 0 : mat_step_row = 0;
4344 0 : move16();
4345 0 : mat_step_col_flag = 1;
4346 0 : move16();
4347 0 : assert( dcttype == DCT_T2_21_XX || dcttype == DCT_T2_24_XX );
4348 : }
4349 : ELSE
4350 : {
4351 2900 : assert( ( dcttype & 1 ) != 0 ); /* idct */
4352 2900 : dim_in = dct_dim;
4353 2900 : move16();
4354 2900 : dim_out = fdcngvq_dim;
4355 2900 : move16();
4356 2900 : mat_step_col = 1;
4357 2900 : move16();
4358 2900 : mat_step_row = matrix_row_dim;
4359 2900 : move16();
4360 2900 : mat_step_col_flag = 0;
4361 2900 : move16();
4362 2900 : assert( dcttype == IDCT_T2_XX_24 );
4363 : }
4364 :
4365 2900 : pt_y = tmp_y;
4366 70233 : FOR( i = 0; i < dim_out; i++ )
4367 : {
4368 67333 : pt_x = input;
4369 67333 : *pt_y = 0;
4370 67333 : move32();
4371 :
4372 : /* +i(DCT) or +i*maxTrunc(IDCT) */
4373 : #define WMC_TOOL_SKIP
4374 67333 : pt_A = &( matrix[i * ( mat_step_row + mat_step_col_flag )] ); /* ptr indexing */
4375 : PTR_INIT( 1 );
4376 : #undef WMC_TOOL_SKIP
4377 1028197 : FOR( j = 0; j < dim_in; j++ )
4378 : {
4379 : #define WMC_TOOL_SKIP
4380 960864 : *pt_y = L_add( *pt_y, Mpy_32_32( ( *pt_x++ ), ( *pt_A ) ) );
4381 960864 : move32();
4382 960864 : pt_A += mat_step_col; /* step +maxtrunc or +1 */ /* ptr indexing*/
4383 : MAC_C( 1 );
4384 : #undef WMC_TOOL_SKIP
4385 : }
4386 67333 : pt_y++;
4387 : }
4388 :
4389 2900 : Copy32( tmp_y, output, dim_out );
4390 :
4391 2900 : return;
4392 : }
4393 :
4394 0 : void extend_dctN_input_fx(
4395 : const Word32 *input, /* i : input in fdcng domain Q */
4396 : const Word32 *dct_input, /* i : input in dctN(fdcng) domain Q */
4397 : const Word16 in_dim, /* i : in_dim == N */
4398 : Word32 *ext_sig, /* o : extended output in fdcng domain Q */
4399 : const Word16 out_dim, /* i : output total dim */
4400 : Word32 *matrix, /* i : idct synthesis matrix N rows, n_cols columns 31 */
4401 : const Word16 n_cols, /* i : number of columns == DCT truncation length */
4402 : const DCTTYPE dcttype /* i : matrix operation type */
4403 : )
4404 : {
4405 : Word16 i, j, i_rev;
4406 0 : const Word32( *ptr )[FDCNG_VQ_DCT_MAXTRUNC] = (void *) matrix;
4407 :
4408 : /* stored format is an IDCT_Nx(FDCNG_VQ_DCT_MAXTRUNC) matrix */
4409 0 : assert( in_dim < FDCNG_VQ_MAX_LEN );
4410 0 : assert( out_dim <= FDCNG_VQ_MAX_LEN );
4411 0 : assert( out_dim > in_dim );
4412 0 : assert( n_cols == FDCNG_VQ_DCT_MAXTRUNC ); /* for *ptr[MAX_TRUNC] adressing*/
4413 0 : assert( ( dcttype & 1 ) != 0 ); /* idct tables always in use for this basis vector extension */
4414 :
4415 0 : Copy32( input, ext_sig, in_dim ); /* copy initial part, i.e. only last/tail parts are extended q: Q */
4416 0 : set32_fx( &( ext_sig[in_dim] ), 0, sub( out_dim, in_dim ) );
4417 :
4418 0 : i_rev = in_dim; /*ptr init*/
4419 0 : move16();
4420 0 : FOR( i = in_dim; i < out_dim; i++ )
4421 : { /* for each extension sample */
4422 : /* i = 21 22 23;
4423 : i_rev = 20 19 18; for odd dctII reflect basis vector
4424 : */
4425 0 : i_rev = sub( i_rev, 1 );
4426 :
4427 0 : FOR( j = 0; j < n_cols; j++ ) /* for each available DCT coeff */
4428 : {
4429 : /* DCTcoeff * reflected basis vector */
4430 : #define WMC_TOOL_SKIP
4431 : /* pure ptr MAC operations */
4432 0 : ext_sig[i] = L_add( ext_sig[i], Mpy_32_32( dct_input[j], ptr[i_rev][j] ) ); /* sum up scaled and extended basis vector */
4433 : // Q31 + Q - Q31 -> Q
4434 0 : move32();
4435 : MAC_C( 1 );
4436 : #undef WMC_TOOL_SKIP
4437 : }
4438 : }
4439 :
4440 0 : return;
4441 : }
4442 :
4443 :
4444 2490 : void create_IDCT_N_Matrix_fx(
4445 : Word32 *inv_matrixFloatQ, /* i/o: RAM buffer Q31 */
4446 : const Word16 N, /* i : DCT length, number of time samples */
4447 : const Word16 n_cols, /* i : number of dct coeffs (as DCT may be truncated) */
4448 : const Word16 alloc_size /* i : RAM buffer size in elements */
4449 : )
4450 : {
4451 : Word16 c, c1, r, r_flip, W16_val, tmp16;
4452 : Word16 len;
4453 : Word16 mat_cpy_size;
4454 : const Word16 *absval_ptr;
4455 : const Word8 *idx_ptr;
4456 : Word16 idx;
4457 2490 : Word32( *ptr )[FDCNG_VQ_DCT_MAXTRUNC] = (void *) inv_matrixFloatQ; /* fixed number of columns pointers, to simplifies adressing in ANSIC */
4458 :
4459 2490 : absval_ptr = unique_idctT2_24coeffsQ16; // Q16
4460 2490 : idx_ptr = idctT2_24_compressed_idx;
4461 2490 : len = FDCNG_VQ_MAX_LEN;
4462 2490 : move16();
4463 :
4464 2490 : IF( EQ_16( N, FDCNG_VQ_MAX_LEN_WB ) )
4465 : {
4466 0 : absval_ptr = unique_idctT2_21coeffsQ16; // Q16
4467 0 : idx_ptr = idctT2_21_compressed_idx;
4468 0 : len = N;
4469 0 : move16();
4470 : }
4471 :
4472 2490 : assert( alloc_size >= ( n_cols * len ) ); /* enough space for the full expanded IDCT matrix */
4473 2490 : assert( N <= len );
4474 :
4475 : // mat_cpy_size = ( n_cols ) * ( len >> 1 ); /* NB integer division of "len" */
4476 2490 : mat_cpy_size = imult1616( n_cols, shr( len, 1 ) ); /* NB integer division of "len" */
4477 :
4478 2490 : IF( s_and( len, 1 ) != 0 )
4479 : { /* odd sized DCT with a non-reflected center row */
4480 0 : mat_cpy_size = add( mat_cpy_size, n_cols );
4481 : }
4482 :
4483 540330 : FOR( c = 0; c < mat_cpy_size; c++ )
4484 : {
4485 537840 : idx = (Word16) ( idx_ptr[c] );
4486 537840 : W16_val = absval_ptr[abs( idx )]; // Q16
4487 537840 : move16();
4488 :
4489 537840 : IF( idx < 0 )
4490 : {
4491 231570 : W16_val = negate( W16_val );
4492 : }
4493 : /* (+1.52587890625e-05f) * 2 ^ 31 is equal to 32768 */
4494 537840 : inv_matrixFloatQ[c] = L_shl( W16_val, Q15 ); /* scaling to 2 ^ 31*/
4495 537840 : move32();
4496 : }
4497 :
4498 : /* for even number of coeffs DCT24,
4499 : flip symmetry for odd, even is used to save 50% IDCT Table ROM */
4500 : /* for an odd DCT center is not flipped e.g for DCT21 */
4501 :
4502 2490 : assert( n_cols == FDCNG_VQ_DCT_MAXTRUNC );
4503 2490 : assert( ( n_cols & 1 ) == 0 );
4504 :
4505 24900 : FOR( c = 0; c < ( n_cols ); c += 2 )
4506 : {
4507 22410 : c1 = add( c, 1 );
4508 22410 : r_flip = sub( len, 1 );
4509 22410 : tmp16 = shr( len, 1 );
4510 291330 : FOR( r = 0; r < tmp16; r_flip-- )
4511 : {
4512 : #define WMC_TOOL_SKIP
4513 268920 : ptr[r_flip][c] = ptr[r][c]; /* flipped: Q31*/
4514 268920 : ptr[r_flip][c1] = L_negate( ptr[r][c1] ); /* flipped and sign swapped: Q31 */
4515 : MOVE( 2 );
4516 : MULT( 1 ); /* for negate */
4517 : #undef WMC_TOOL_SKIP
4518 268920 : r++;
4519 : }
4520 : }
4521 :
4522 2490 : return;
4523 : }
|