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