Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 : #include <stdint.h>
6 : #include <assert.h>
7 : #include <math.h>
8 : #include "options.h"
9 : #include "prot_fx.h"
10 : #include "basop_util.h"
11 : #include "rom_basop_util.h"
12 : #include "rom_com.h"
13 :
14 : #define inv_int InvIntTable
15 :
16 812577 : Word16 tcxGetNoiseFillingTilt(
17 : const Word16 A[],
18 : const Word16 lpcorder,
19 : const Word16 L_frame,
20 : const Word16 mode,
21 : Word16 *noiseTiltFactor /*Q15*/
22 : )
23 : {
24 : Word16 firstLine;
25 : Word32 tmp;
26 : Word16 As[M + 1];
27 :
28 :
29 812577 : IF( mode != 0 )
30 : {
31 786009 : firstLine = idiv1616U( L_frame, 6 );
32 786009 : *noiseTiltFactor = 18432 /*0.5625f Q15*/;
33 786009 : move16();
34 : }
35 : ELSE
36 : {
37 26568 : firstLine = shr( L_frame, 3 );
38 :
39 26568 : Copy_Scale_sig( A, As, add( lpcorder, 1 ), sub( norm_s( A[0] ), 2 ) ); // Q(12)
40 26568 : tmp = get_gain( As + 1, As, lpcorder );
41 : BASOP_SATURATE_WARNING_OFF_EVS;
42 26568 : *noiseTiltFactor = add_sat( round_fx_sat( L_shl_sat( tmp, 15 ) ), 3072 /*0.09375f Q15*/ );
43 26568 : move16();
44 : BASOP_SATURATE_WARNING_ON_EVS;
45 : }
46 :
47 :
48 812577 : return firstLine;
49 : }
50 :
51 :
52 0 : void tcxFormantEnhancement(
53 : Word16 xn_buf[], // Q(15-xn_buf_e)
54 : const Word16 gainlpc[], // Q(15-gainlpc_e)
55 : const Word16 gainlpc_e[],
56 : Word32 spectrum[], // Q(31-spectrum_e)
57 : Word16 *spectrum_e,
58 : const Word16 L_frame,
59 : const Word16 L_frameTCX )
60 : {
61 : Word16 i, j, k, l, n;
62 : Word16 fac, fac0, fac1, fac_e, d, tmp;
63 : Word16 xn_buf_e, xn_one, m, e;
64 : #ifndef ISSUE_1836_replace_overflow_libcom
65 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
66 : Flag Overflow = 0;
67 : move32();
68 : #endif
69 : #endif
70 :
71 0 : k = shr( L_frame, 6 ); /* FDNS_NPTS = 64 */
72 0 : l = 0;
73 0 : move16();
74 :
75 : /* get exponent */
76 0 : xn_buf_e = 0;
77 0 : move16();
78 0 : FOR( i = 0; i < FDNS_NPTS; i++ )
79 : {
80 0 : xn_buf_e = s_max( xn_buf_e, gainlpc_e[i] );
81 : }
82 0 : xn_buf_e = shr( add( xn_buf_e, 1 ), 1 ); /* max exponent after sqrt */
83 0 : xn_one = shr( 0x4000, sub( xn_buf_e, 1 ) ); /* 1.0 scaled to xn_buf_e */
84 :
85 : /* Formant enhancement via square root of the LPC gains */
86 0 : e = gainlpc_e[0];
87 0 : move16();
88 0 : m = Sqrt16( gainlpc[0], &e );
89 0 : xn_buf[0] = shl( m, sub( e, xn_buf_e ) ); // Q(15-xn_buf_e)
90 0 : move16();
91 :
92 0 : e = gainlpc_e[1];
93 0 : move16();
94 0 : m = Sqrt16( gainlpc[1], &e );
95 0 : xn_buf[1] = shl( m, sub( e, xn_buf_e ) ); // Q(15-xn_buf_e)
96 0 : move16();
97 :
98 0 : fac0 = s_min( xn_buf[0], xn_buf[1] );
99 0 : fac_e = xn_buf_e;
100 0 : move16();
101 0 : fac0 = Inv16( fac0, &fac_e );
102 :
103 0 : FOR( i = 1; i < FDNS_NPTS - 1; i++ )
104 : {
105 0 : e = gainlpc_e[i + 1];
106 0 : move16();
107 0 : m = Sqrt16( gainlpc[i + 1], &e );
108 0 : xn_buf[i + 1] = shl( m, sub( e, xn_buf_e ) ); // Q(15-xn_buf_e)
109 0 : move16();
110 :
111 0 : test();
112 0 : IF( ( LE_16( xn_buf[i - 1], xn_buf[i] ) ) && ( LE_16( xn_buf[i + 1], xn_buf[i] ) ) )
113 : {
114 0 : m = s_max( xn_buf[i - 1], xn_buf[i + 1] );
115 0 : e = xn_buf_e;
116 0 : move16();
117 0 : m = Inv16( m, &e );
118 :
119 0 : fac1 = m;
120 0 : move16();
121 0 : tmp = sub( e, fac_e );
122 :
123 0 : IF( tmp > 0 )
124 0 : fac0 = shr( fac0, tmp );
125 0 : IF( tmp < 0 )
126 0 : fac1 = shl( fac1, tmp );
127 :
128 0 : if ( tmp > 0 )
129 : {
130 0 : fac_e = e;
131 0 : move16();
132 : }
133 :
134 0 : d = sub( fac1, fac0 );
135 0 : n = sub( i, l );
136 0 : assert( n <= 64 );
137 :
138 0 : xn_buf[l] = xn_one;
139 0 : move16();
140 0 : FOR( j = 1; j < n; j++ )
141 : {
142 0 : fac = add( fac0, mult( d, extract_l( L_mult0( j, inv_int[n] ) ) ) );
143 : BASOP_SATURATE_WARNING_OFF_EVS;
144 : #ifdef ISSUE_1836_replace_overflow_libcom
145 0 : xn_buf[l + j] = s_min( xn_one, shl_sat( mult( xn_buf[l + j], fac ), fac_e ) );
146 : #else
147 : xn_buf[l + j] = s_min( xn_one, shl_o( mult( xn_buf[l + j], fac ), fac_e, &Overflow ) );
148 : #endif
149 0 : move16();
150 : BASOP_SATURATE_WARNING_ON_EVS;
151 : }
152 :
153 0 : l = i;
154 0 : move16();
155 :
156 0 : fac0 = m;
157 0 : move16();
158 0 : fac_e = e;
159 0 : move16();
160 : }
161 : }
162 : /* i = FDNS_NPTS - 1; Completing changes to gains */
163 0 : m = s_min( xn_buf[i - 1], xn_buf[i] );
164 0 : e = xn_buf_e;
165 0 : move16();
166 0 : m = Inv16( m, &e );
167 :
168 0 : fac1 = m;
169 0 : move16();
170 0 : tmp = sub( e, fac_e );
171 :
172 0 : IF( tmp > 0 )
173 0 : fac0 = shr( fac0, tmp );
174 0 : IF( tmp < 0 )
175 0 : fac1 = shl( fac1, tmp );
176 :
177 0 : if ( tmp > 0 )
178 : {
179 0 : fac_e = e;
180 0 : move16();
181 : }
182 :
183 0 : d = sub( fac1, fac0 );
184 0 : n = sub( i, l );
185 0 : assert( n <= 64 );
186 :
187 0 : xn_buf[l] = xn_one;
188 0 : move16();
189 0 : FOR( j = 1; j < n; j++ )
190 : {
191 0 : fac = add( fac0, mult( d, extract_l( L_mult0( j, inv_int[n] ) ) ) );
192 : BASOP_SATURATE_WARNING_OFF_EVS;
193 0 : xn_buf[l + j] = s_min( xn_one, shl_sat( mult( xn_buf[l + j], fac ), fac_e ) );
194 0 : move16();
195 : BASOP_SATURATE_WARNING_ON_EVS;
196 : }
197 :
198 0 : xn_buf[i] = xn_one;
199 0 : move16();
200 :
201 : /* Application of changed gains onto decoded MDCT lines */
202 0 : FOR( i = 0; i < L_frame; i += k )
203 : {
204 0 : FOR( l = 0; l < k; l++ )
205 : {
206 0 : *spectrum = Mpy_32_16_1( *spectrum, *xn_buf ); // Q(15-xn_buf_e)+Q(31-spectrum_e)+1 -16
207 0 : move32();
208 0 : spectrum++;
209 : }
210 0 : xn_buf++;
211 : }
212 :
213 0 : tmp = sub( L_frameTCX, L_frame );
214 0 : FOR( i = 0; i < tmp; i++ )
215 : {
216 0 : spectrum[i] = L_shr( spectrum[i], xn_buf_e ); // Q(31-(specturm_e+xn_buf_e))
217 0 : move32();
218 : }
219 0 : *spectrum_e = add( *spectrum_e, xn_buf_e );
220 0 : move16();
221 0 : }
222 :
223 26443 : void tcxFormantEnhancement_with_shift(
224 : Word16 xn_buf[], // Q(15-xn_buf_e_out)
225 : Word16 *xn_buf_e_out,
226 : const Word16 gainlpc[], // Q(15-gainlpc_e)
227 : const Word16 gainlpc_e[],
228 : Word32 spectrum[], // Q(31-spectrum_e)
229 : Word16 *spectrum_e,
230 : const Word16 L_frame,
231 : const Word16 L_frameTCX )
232 : {
233 : Word16 i, j, k, l, n;
234 : Word16 fac, fac0, fac1, fac_e, d, tmp;
235 : Word16 xn_buf_e, xn_one, m, e;
236 : #ifndef ISSUE_1836_replace_overflow_libcom
237 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
238 : Flag Overflow = 0;
239 : move32();
240 : #endif
241 : #endif
242 :
243 26443 : k = shr( L_frame, 6 ); /* FDNS_NPTS = 64 */
244 26443 : l = 0;
245 26443 : move16();
246 :
247 : /* get exponent */
248 26443 : xn_buf_e = 0;
249 26443 : move16();
250 1718795 : FOR( i = 0; i < FDNS_NPTS; i++ )
251 : {
252 1692352 : xn_buf_e = s_max( xn_buf_e, gainlpc_e[i] );
253 : }
254 26443 : xn_buf_e = shr( add( xn_buf_e, 1 ), 1 ); /* max exponent after sqrt */
255 26443 : xn_one = shr( 0x4000, sub( xn_buf_e, 1 ) ); /* 1.0 scaled to xn_buf_e */
256 :
257 : /* Formant enhancement via square root of the LPC gains */
258 26443 : e = gainlpc_e[0];
259 26443 : move16();
260 26443 : m = Sqrt16( gainlpc[0], &e );
261 26443 : xn_buf[0] = shl( m, sub( e, xn_buf_e ) ); // Q(15-xn_buf_e)
262 26443 : move16();
263 :
264 26443 : e = gainlpc_e[1];
265 26443 : move16();
266 26443 : m = Sqrt16( gainlpc[1], &e );
267 26443 : xn_buf[1] = shl( m, sub( e, xn_buf_e ) ); // Q(15-xn_buf_e)
268 26443 : move16();
269 :
270 26443 : fac0 = s_min( xn_buf[0], xn_buf[1] );
271 26443 : fac_e = xn_buf_e;
272 26443 : move16();
273 26443 : fac0 = Inv16( fac0, &fac_e );
274 :
275 1665909 : FOR( i = 1; i < FDNS_NPTS - 1; i++ )
276 : {
277 1639466 : e = gainlpc_e[i + 1];
278 1639466 : move16();
279 1639466 : m = Sqrt16( gainlpc[i + 1], &e );
280 1639466 : xn_buf[i + 1] = shl( m, sub( e, xn_buf_e ) ); // Q(15-xn_buf_e)
281 1639466 : move16();
282 :
283 1639466 : test();
284 1639466 : IF( ( LE_16( xn_buf[i - 1], xn_buf[i] ) ) && ( LE_16( xn_buf[i + 1], xn_buf[i] ) ) )
285 : {
286 79759 : m = s_max( xn_buf[i - 1], xn_buf[i + 1] );
287 79759 : e = xn_buf_e;
288 79759 : move16();
289 79759 : m = Inv16( m, &e );
290 :
291 79759 : fac1 = m;
292 79759 : move16();
293 79759 : tmp = sub( e, fac_e );
294 :
295 79759 : IF( tmp > 0 )
296 : {
297 26406 : fac0 = shr( fac0, tmp );
298 : }
299 79759 : IF( tmp < 0 )
300 : {
301 6775 : fac1 = shl( fac1, tmp );
302 : }
303 :
304 79759 : IF( tmp > 0 )
305 : {
306 26406 : fac_e = e;
307 26406 : move16();
308 : }
309 :
310 79759 : d = sub( fac1, fac0 );
311 79759 : n = sub( i, l );
312 79759 : assert( n <= 64 );
313 :
314 79759 : xn_buf[l] = xn_one;
315 79759 : move16();
316 1179820 : FOR( j = 1; j < n; j++ )
317 : {
318 1100061 : fac = add( fac0, mult( d, extract_l( L_mult0( j, inv_int[n] ) ) ) );
319 : BASOP_SATURATE_WARNING_OFF_EVS;
320 : #ifdef ISSUE_1836_replace_overflow_libcom
321 1100061 : xn_buf[l + j] = s_min( xn_one, shl_sat( mult( xn_buf[l + j], fac ), fac_e ) );
322 : #else
323 : xn_buf[l + j] = s_min( xn_one, shl_o( mult( xn_buf[l + j], fac ), fac_e, &Overflow ) );
324 : #endif
325 1100061 : move16();
326 : BASOP_SATURATE_WARNING_ON_EVS;
327 : }
328 :
329 79759 : l = i;
330 79759 : move16();
331 :
332 79759 : fac0 = m;
333 79759 : move16();
334 79759 : fac_e = e;
335 79759 : move16();
336 : }
337 : }
338 : /* i = FDNS_NPTS - 1; Completing changes to gains */
339 26443 : m = s_min( xn_buf[i - 1], xn_buf[i] );
340 26443 : e = xn_buf_e;
341 26443 : move16();
342 26443 : m = Inv16( m, &e );
343 :
344 26443 : fac1 = m;
345 26443 : move16();
346 26443 : tmp = sub( e, fac_e );
347 :
348 26443 : IF( tmp > 0 )
349 12216 : fac0 = shr( fac0, tmp );
350 26443 : IF( tmp < 0 )
351 154 : fac1 = shl( fac1, tmp );
352 :
353 26443 : if ( tmp > 0 )
354 : {
355 12216 : fac_e = e;
356 12216 : move16();
357 : }
358 :
359 26443 : d = sub( fac1, fac0 );
360 26443 : n = sub( i, l );
361 26443 : assert( n <= 64 );
362 :
363 26443 : xn_buf[l] = xn_one;
364 26443 : move16();
365 486089 : FOR( j = 1; j < n; j++ )
366 : {
367 459646 : fac = add( fac0, mult( d, extract_l( L_mult0( j, inv_int[n] ) ) ) );
368 : BASOP_SATURATE_WARNING_OFF_EVS;
369 : #ifdef ISSUE_1836_replace_overflow_libcom
370 459646 : xn_buf[l + j] = s_min( xn_one, shl_sat( mult( xn_buf[l + j], fac ), fac_e ) );
371 : #else
372 : xn_buf[l + j] = s_min( xn_one, shl_o( mult( xn_buf[l + j], fac ), fac_e, &Overflow ) );
373 : #endif
374 459646 : move16();
375 : BASOP_SATURATE_WARNING_ON_EVS;
376 : }
377 :
378 26443 : xn_buf[i] = xn_one;
379 26443 : move16();
380 :
381 : /* Application of changed gains onto decoded MDCT lines */
382 1718795 : FOR( i = 0; i < L_frame; i += k )
383 : {
384 8574208 : FOR( l = 0; l < k; l++ )
385 : {
386 6881856 : *spectrum = Mpy_32_16_1( *spectrum, *xn_buf ); // Q(15-xn_buf_e)+Q(31-spectrum_e)+1 -16
387 6881856 : move32();
388 6881856 : spectrum++;
389 : }
390 1692352 : xn_buf++;
391 : }
392 :
393 26443 : tmp = sub( L_frameTCX, L_frame );
394 17279947 : FOR( i = 0; i < tmp; i++ )
395 : {
396 17253504 : spectrum[i] = L_shr( spectrum[i], xn_buf_e ); // Q(31-(specturm_e+xn_buf_e))
397 17253504 : move32();
398 : }
399 26443 : *spectrum_e = add( *spectrum_e, xn_buf_e );
400 26443 : move16();
401 :
402 26443 : *xn_buf_e_out = xn_buf_e;
403 26443 : move16();
404 26443 : }
405 :
406 0 : void tcxInvertWindowGrouping(
407 : TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */
408 : Word32 xn_buf[], // Qx
409 : Word32 spectrum[], // Qx
410 : const Word16 L_frame,
411 : const Word8 fUseTns,
412 : const Word16 last_core,
413 : const Word16 index,
414 : const Word16 frame_cnt,
415 : const Word16 bfi )
416 : {
417 : Word16 i, L_win, L_spec;
418 : Word32 *p;
419 :
420 :
421 0 : L_win = shr( L_frame, 1 );
422 0 : L_spec = hTcxCfg->tnsConfig[0][0].iFilterBorders[0];
423 0 : move16();
424 :
425 0 : test();
426 0 : test();
427 0 : if ( ( frame_cnt != 0 ) && ( bfi == 0 ) && ( last_core != ACELP_CORE ) ) /* fix sub-window overlap */
428 : {
429 0 : hTcxCfg->tcx_last_overlap_mode = hTcxCfg->tcx_curr_overlap_mode;
430 0 : move16();
431 : }
432 0 : test();
433 0 : test();
434 0 : test();
435 0 : test();
436 0 : test();
437 0 : test();
438 0 : test();
439 0 : IF( ( ( bfi == 0 ) && ( ( hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) ||
440 : ( ( hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) && ( frame_cnt == 0 ) && ( index == 0 ) ) ) ) ||
441 : ( ( bfi != 0 ) && ( ( hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) &&
442 : !( hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) ) ) )
443 : {
444 : /* ungroup sub-windows: deinterleave MDCT bins into separate windows */
445 0 : p = xn_buf;
446 0 : FOR( i = 1; i < L_win; i += 2 )
447 : {
448 0 : *p++ = spectrum[i];
449 0 : move32();
450 : }
451 :
452 0 : p = spectrum;
453 0 : FOR( i = 0; i < L_frame; i += 2 )
454 : {
455 0 : *p++ = spectrum[i];
456 0 : move32();
457 : }
458 :
459 0 : p = spectrum + sub( L_frame, 1 );
460 0 : FOR( i = L_frame - 1; i > L_win; i -= 2 )
461 : {
462 0 : *p-- = spectrum[i];
463 0 : move32();
464 : }
465 0 : Copy32( xn_buf, spectrum + L_win, shr( L_win, 1 ) );
466 :
467 0 : test();
468 0 : test();
469 0 : IF( ( hTcxCfg->fIsTNSAllowed != 0 ) && ( bfi == 0 ) && ( fUseTns != 0 ) )
470 : {
471 : /* rearrange LF sub-window lines prior to TNS synthesis filtering */
472 0 : IF( LT_16( L_spec, L_frame ) )
473 : {
474 0 : Copy32( spectrum + 8, spectrum + 16, sub( shr( L_spec, 1 ), 8 ) );
475 0 : Copy32( spectrum + shr( L_frame, 1 ), spectrum + 8, 8 );
476 0 : Copy32( spectrum + add( shr( L_frame, 1 ), 8 ), spectrum + add( shr( L_spec, 1 ), 8 ), sub( shr( L_spec, 1 ), 8 ) );
477 : }
478 : ELSE
479 : {
480 0 : Copy32( spectrum + L_win, xn_buf, 8 );
481 0 : Copy32( spectrum + 8, spectrum + 16, sub( L_win, 8 ) );
482 0 : Copy32( xn_buf, spectrum + 8, 8 );
483 : }
484 : }
485 : }
486 0 : }
487 :
488 : /*-------------------------------------------------------------------*
489 : * tcx5SpectrumInterleaving()
490 : *
491 : *
492 : *-------------------------------------------------------------------*/
493 :
494 :
495 16825 : void tcx5SpectrumInterleaving_fx(
496 : const Word16 tcx5Size,
497 : Word32 *spectrum // Qx
498 : )
499 : {
500 : Word16 i;
501 : Word32 interleaveBuf[N_TCX10_MAX];
502 :
503 16825 : set32_fx( interleaveBuf, 0, N_TCX10_MAX );
504 :
505 : /* group sub-windows: interleave bins according to their frequencies */
506 3550185 : FOR( i = 0; i < tcx5Size; i++ )
507 : {
508 3533360 : interleaveBuf[2 * i] = spectrum[i];
509 3533360 : interleaveBuf[2 * i + 1] = spectrum[tcx5Size + i];
510 3533360 : move32();
511 3533360 : move32();
512 : }
513 :
514 16825 : Copy32( interleaveBuf, spectrum, shl( tcx5Size, 1 ) );
515 :
516 16825 : return;
517 : }
518 :
519 : /*-------------------------------------------------------------------*
520 : * tcx5SpectrumDeinterleaving_fx()
521 : *
522 : *
523 : *-------------------------------------------------------------------*/
524 :
525 33570 : void tcx5SpectrumDeinterleaving_fx(
526 : const Word16 tcx5Size,
527 : Word32 *spectrum // Qx
528 : )
529 : {
530 : Word16 i;
531 : Word32 interleaveBuf[N_TCX10_MAX];
532 :
533 33570 : set32_fx( interleaveBuf, 0, N_TCX10_MAX );
534 :
535 : /* ungroup sub-windows: interleave bins according to their frequencies */
536 7208930 : FOR( i = 0; i < tcx5Size; i++ )
537 : {
538 7175360 : interleaveBuf[i] = spectrum[2 * i];
539 7175360 : interleaveBuf[tcx5Size + i] = spectrum[2 * i + 1];
540 7175360 : move32();
541 7175360 : move32();
542 : }
543 :
544 33570 : Copy32( interleaveBuf, spectrum, shl( tcx5Size, 1 ) );
545 :
546 33570 : return;
547 : }
548 :
549 : /*-------------------------------------------------------------------*
550 : * tcx5TnsGrouping()
551 : *
552 : *
553 : *-------------------------------------------------------------------*/
554 :
555 12820 : void tcx5TnsGrouping_fx(
556 : const Word16 L_frame, /* i : frame length (TCX5) */
557 : const Word16 L_spec, /* i : coded spec length (TCX5, derived from filter borders*/
558 : Word32 *spectrum /*Qx*/
559 : )
560 : {
561 : /* rearrange LF sub-window lines prior to TNS synthesis filtering */
562 12820 : IF( LT_16( L_spec, L_frame ) )
563 : {
564 8337 : Copy32( spectrum + 8, spectrum + 16, sub( L_spec, 8 ) );
565 8337 : Copy32( spectrum + L_frame, spectrum + 8, 8 );
566 8337 : Copy32( spectrum + add( L_frame, 8 ), spectrum + add( L_spec, 8 ), sub( L_spec, 8 ) );
567 : }
568 : ELSE
569 : {
570 : Word32 buff[8]; /* Buffer for the rearrangement of LF TCX5 */
571 4483 : Copy32( spectrum + L_spec, buff, 8 );
572 4483 : Copy32( spectrum + 8, spectrum + 16, sub( L_spec, 8 ) );
573 4483 : Copy32( buff, spectrum + 8, 8 );
574 : }
575 :
576 12820 : return;
577 : }
578 :
579 : /*-------------------------------------------------------------------*
580 : * tcx5TnsUngrouping()
581 : *
582 : *
583 : *-------------------------------------------------------------------*/
584 :
585 12820 : void tcx5TnsUngrouping_fx(
586 : const Word16 L_frame, /* i : frame length (TCX5) */
587 : const Word16 L_spec, /* i : coded spec length (TCX5, derived from filter borders*/
588 : Word32 *spectrum, /*Qx*/
589 : const Word16 enc_dec /* i : 0: encoder, else decoder */
590 : )
591 : {
592 : /* undo rearrangement of LF sub-window lines prior to TNS analysis */
593 12820 : IF( LT_16( L_spec, L_frame ) )
594 : {
595 8337 : Copy32( spectrum + L_spec + 8, spectrum + add( L_frame, 8 ), sub( L_spec, 8 ) );
596 8337 : Copy32( spectrum + 8, spectrum + L_frame, 8 );
597 8337 : Copy32( spectrum + 16, spectrum + 8, sub( L_spec, 8 ) );
598 8337 : set32_fx( spectrum + L_spec, 0, sub( L_frame, L_spec ) );
599 8337 : set32_fx( spectrum + add( L_frame, L_spec ), 0, sub( L_frame, L_spec ) );
600 : }
601 : ELSE
602 : {
603 : Word32 buff[8]; /* Buffer for the rearrangement of LF TCX5 */
604 :
605 4483 : Copy32( spectrum + 8, buff, 8 );
606 :
607 4483 : IF( enc_dec == ENC )
608 : {
609 0 : Copy32( spectrum + 16, spectrum + 8, sub( L_frame, 8 ) );
610 0 : Copy32( buff, spectrum + L_frame, 8 );
611 : }
612 : ELSE
613 : {
614 4483 : Copy32( spectrum + 16, spectrum + 8, sub( L_spec, 8 ) );
615 4483 : Copy32( buff, spectrum + L_spec, 8 );
616 : }
617 : }
618 :
619 12820 : return;
620 : }
|