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