Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
4 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
5 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
6 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
7 : contributors to this repository. All Rights Reserved.
8 :
9 : This software is protected by copyright law and by international treaties.
10 : The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
11 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
12 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
13 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
14 : contributors to this repository retain full ownership rights in their respective contributions in
15 : the software. This notice grants no license of any kind, including but not limited to patent
16 : license, nor is any license granted by implication, estoppel or otherwise.
17 :
18 : Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
19 : contributions.
20 :
21 : This software is provided "AS IS", without any express or implied warranties. The software is in the
22 : development stage. It is intended exclusively for experts who have experience with such software and
23 : solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
24 : and fitness for a particular purpose are hereby disclaimed and excluded.
25 :
26 : Any dispute, controversy or claim arising under or in relation to providing this software shall be
27 : submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
28 : accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
29 : the United Nations Convention on Contracts on the International Sales of Goods.
30 :
31 : *******************************************************************************************************/
32 :
33 : /*====================================================================================
34 : EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
35 : ====================================================================================*/
36 :
37 : #include <stdint.h>
38 : #include "options.h"
39 : #include "prot_fx.h"
40 : #include "rom_com.h"
41 : #include "wmc_auto.h"
42 :
43 : /*-----------------------------------------------------------------*
44 : * Local constants
45 : *-----------------------------------------------------------------*/
46 :
47 : #define N_MAX_FFT 1024
48 : #define INV_SQR2_FX 23170 /*Q15*/
49 : #define N_MAX_SAS 256
50 : /*---------------------------------------------------------------------*
51 : * ifft_rel()
52 : *
53 : * Calculate the inverse FFT of a real signal
54 : *
55 : * Based on the FORTRAN code from the article "Real-valued Fast Fourier Transform Algorithms"
56 : * by Sorensen, ... in IEEE Trans. on ASSP, Vol. ASSP-35, No. June 6th 1987.
57 : *
58 : * Input: the io[] signal containing the spectrum in the following order :
59 : *
60 : * Re[0], Re[1], .. Re[n/2], Im[n/2-1], .. Im[1]
61 : *---------------------------------------------------------------------*/
62 :
63 14286 : void ifft_rel_fx(
64 : Word16 io[], /* Qx i/o: input/output vector */
65 : const Word16 n, /* Q0 i : vector length */
66 : const Word16 m /* Q0 i : log2 of vector length */
67 : )
68 : {
69 : Word16 i, j, k;
70 : Word16 step;
71 : Word16 n2, n4, n8, i0;
72 : Word16 is, id;
73 : Word16 *x, *xi0, *xi1, *xi2, *xi3, *xi4, *xup1, *xdn6, *xup3, *xdn8;
74 : Word16 xt;
75 : Word16 r1;
76 : Word16 t1, t2, t3, t4, t5;
77 : const Word16 *s, *c, *s3, *c3;
78 :
79 : Word16 cc1, cc3, ss1, ss3;
80 : Word16 tmp;
81 : #ifndef ISSUE_1836_replace_overflow_libcom
82 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
83 : Flag Overflow = 0;
84 : move16();
85 : #endif
86 : #endif
87 :
88 :
89 : /*-----------------------------------------------------------------*
90 : * ifft
91 : *-----------------------------------------------------------------*/
92 :
93 14286 : x = &io[-1];
94 14286 : n2 = shl( n, 1 );
95 48563 : FOR( k = 1; k < m; k++ )
96 : {
97 34277 : is = 0;
98 34277 : move16();
99 34277 : id = n2;
100 34277 : move16();
101 34277 : n2 = shr( n2, 1 );
102 34277 : n4 = shr( n2, 2 );
103 34277 : n8 = shr( n4, 1 );
104 34277 : tmp = sub( n, 1 );
105 78823 : WHILE( LT_16( is, tmp ) )
106 : {
107 44546 : xi1 = x + is + 1; /*Qx*/
108 44546 : xi2 = xi1 + n4; /*Qx*/
109 44546 : xi3 = xi2 + n4; /*Qx*/
110 44546 : xi4 = xi3 + n4; /*Qx*/
111 :
112 167821 : FOR( i = is; i < n; i += id )
113 : {
114 : #ifdef ISSUE_1836_replace_overflow_libcom
115 123275 : t1 = sub_sat( *xi1, *xi3 ); /*Qx*/
116 123275 : *xi1 = add_sat( *xi1, *xi3 ); /*Qx*/
117 123275 : move16();
118 123275 : *xi2 = shl_sat( *xi2, 1 ); /*Qx*/
119 123275 : move16();
120 123275 : *xi3 = sub_sat( t1, shl_sat( *xi4, 1 ) ); /*Qx*/
121 123275 : move16();
122 123275 : *xi4 = add_sat( t1, shl_sat( *xi4, 1 ) ); /*Qx*/
123 123275 : move16();
124 : #else
125 : t1 = sub_o( *xi1, *xi3, &Overflow ); /*Qx*/
126 : *xi1 = add_o( *xi1, *xi3, &Overflow ); /*Qx*/
127 : move16();
128 : *xi2 = shl_o( *xi2, 1, &Overflow ); /*Qx*/
129 : move16();
130 : *xi3 = sub_o( t1, shl_o( *xi4, 1, &Overflow ), &Overflow ); /*Qx*/
131 : move16();
132 : *xi4 = add_o( t1, shl_o( *xi4, 1, &Overflow ), &Overflow ); /*Qx*/
133 : move16();
134 : #endif
135 :
136 123275 : IF( NE_16( n4, 1 ) )
137 : {
138 : #ifdef ISSUE_1836_replace_overflow_libcom
139 61067 : t1 = mult_r( sub_sat( *( xi2 + n8 ), *( xi1 + n8 ) ), INV_SQR2_FX /*Q15*/ ); /*Qx*/
140 61067 : t2 = mult_r( add_sat( *( xi4 + n8 ), *( xi3 + n8 ) ), INV_SQR2_FX /*Q15*/ ); /*Qx*/
141 :
142 61067 : *( xi1 + n8 ) = add_sat( *( xi1 + n8 ), *( xi2 + n8 ) ); /*Qx*/
143 61067 : move16();
144 61067 : *( xi2 + n8 ) = sub_sat( *( xi4 + n8 ), *( xi3 + n8 ) ); /*Qx*/
145 61067 : move16();
146 61067 : *( xi3 + n8 ) = negate( shl_sat( add_sat( t2, t1 ), 1 ) ); /*Qx*/
147 61067 : move16();
148 61067 : *( xi4 + n8 ) = shl_sat( sub_sat( t1, t2 ), 1 ); /*Qx*/
149 61067 : move16();
150 : #else
151 : t1 = mult_r( sub_o( *( xi2 + n8 ), *( xi1 + n8 ), &Overflow ), INV_SQR2_FX /*Q15*/ ); /*Qx*/
152 : t2 = mult_r( add_o( *( xi4 + n8 ), *( xi3 + n8 ), &Overflow ), INV_SQR2_FX /*Q15*/ ); /*Qx*/
153 :
154 : *( xi1 + n8 ) = add_o( *( xi1 + n8 ), *( xi2 + n8 ), &Overflow ); /*Qx*/
155 : move16();
156 : *( xi2 + n8 ) = sub_o( *( xi4 + n8 ), *( xi3 + n8 ), &Overflow ); /*Qx*/
157 : move16();
158 : *( xi3 + n8 ) = negate( shl_o( add_o( t2, t1, &Overflow ), 1, &Overflow ) ); /*Qx*/
159 : move16();
160 : *( xi4 + n8 ) = shl_o( sub_o( t1, t2, &Overflow ), 1, &Overflow ); /*Qx*/
161 : move16();
162 : #endif
163 : }
164 123275 : xi1 += id;
165 123275 : xi2 += id;
166 123275 : xi3 += id;
167 123275 : xi4 += id;
168 : }
169 44546 : is = sub( shl( id, 1 ), n2 );
170 44546 : id = shl( id, 2 );
171 : }
172 : /*Can be acheived with a shr */
173 34277 : step = idiv1616( N_MAX_SAS, n2 );
174 34277 : move16();
175 :
176 34277 : s = sincos_t_fx + step; /*Q15 */
177 34277 : c = s + 64; /*Q15 */
178 34277 : s3 = sincos_t_fx + i_mult2( step, 3 ); /*Q15 */
179 34277 : c3 = s3 + 64; /*Q15 */
180 99314 : FOR( j = 2; j <= n8; j++ )
181 : {
182 65037 : cc1 = *c; /*Q15 */
183 65037 : move16();
184 65037 : ss1 = *s; /*Q15 */
185 65037 : move16();
186 65037 : cc3 = *c3; /*Q15 */
187 65037 : move16();
188 65037 : ss3 = *s3; /*Q15 */
189 65037 : move16();
190 :
191 65037 : is = 0;
192 65037 : move16();
193 65037 : id = shl( n2, 1 );
194 :
195 65037 : c += step;
196 65037 : s += step;
197 :
198 65037 : c3 += imult1616( 3, step );
199 65037 : s3 += imult1616( 3, step );
200 143766 : WHILE( LT_16( is, sub( n, 1 ) ) )
201 : {
202 78729 : xup1 = x + j + is; /*Qx*/
203 78729 : xup3 = xup1 + shl( n4, 1 ); /*Qx*/
204 78729 : xdn6 = xup3 - shl( j, 1 ) + 2; /*Qx*/
205 :
206 78729 : xdn8 = xdn6 + shl( n4, 1 ); /*Qx*/
207 :
208 184842 : FOR( i = is; i < n; i += id )
209 : {
210 : #ifdef ISSUE_1836_replace_overflow_libcom
211 106113 : t1 = sub_sat( *xup1, *xdn6 ); /*Qx*/
212 106113 : *xup1 = add_sat( *xup1, *xdn6 ); /*Qx*/
213 106113 : move16();
214 106113 : xup1 += n4;
215 106113 : xdn6 -= n4;
216 :
217 106113 : t2 = sub_sat( *xdn6, *xup1 ); /*Qx*/
218 106113 : *xdn6 = add_sat( *xup1, *xdn6 ); /*Qx*/
219 106113 : move16();
220 :
221 106113 : xdn6 += n4;
222 106113 : t3 = add_sat( *xdn8, *xup3 ); /*Qx*/
223 106113 : *xdn6 = sub_sat( *xdn8, *xup3 ); /*Qx*/
224 106113 : move16();
225 :
226 106113 : xup3 += n4;
227 106113 : xdn8 -= n4;
228 :
229 106113 : t4 = add_sat( *xup3, *xdn8 ); /*Qx*/
230 106113 : *xup1 = sub_sat( *xup3, *xdn8 ); /*Qx*/
231 106113 : move16();
232 :
233 106113 : t5 = sub_sat( t1, t4 ); /*Qx*/
234 106113 : t1 = add_sat( t1, t4 ); /*Qx*/
235 106113 : t4 = sub_sat( t2, t3 ); /*Qx*/
236 106113 : t2 = add_sat( t2, t3 ); /*Qx*/
237 106113 : *xup3 = sub_sat( mult_r( t1, cc3 ), mult_r( t2, ss3 ) ); /*Qx*/
238 106113 : move16();
239 106113 : xup3 -= n4;
240 106113 : *xup3 = add_sat( mult_r( t5, cc1 ), mult_r( t4, ss1 ) ); /*Qx*/
241 106113 : move16();
242 106113 : *xdn8 = sub_sat( mult_r( t5, ss1 ), mult_r( t4, cc1 ) ); /*Qx*/
243 106113 : move16();
244 :
245 106113 : xdn8 += n4;
246 106113 : *xdn8 = add_sat( mult_r( t2, cc3 ), mult_r( t1, ss3 ) ); /*Qx*/
247 106113 : move16();
248 : #else
249 : t1 = sub_o( *xup1, *xdn6, &Overflow ); /*Qx*/
250 : *xup1 = add_o( *xup1, *xdn6, &Overflow ); /*Qx*/
251 : move16();
252 : xup1 += n4;
253 : xdn6 -= n4;
254 :
255 : t2 = sub_o( *xdn6, *xup1, &Overflow ); /*Qx*/
256 : *xdn6 = add_o( *xup1, *xdn6, &Overflow ); /*Qx*/
257 : move16();
258 :
259 : xdn6 += n4;
260 : t3 = add_o( *xdn8, *xup3, &Overflow ); /*Qx*/
261 : *xdn6 = sub_o( *xdn8, *xup3, &Overflow ); /*Qx*/
262 : move16();
263 :
264 : xup3 += n4;
265 : xdn8 -= n4;
266 :
267 : t4 = add_o( *xup3, *xdn8, &Overflow ); /*Qx*/
268 : *xup1 = sub_o( *xup3, *xdn8, &Overflow ); /*Qx*/
269 : move16();
270 :
271 : t5 = sub_o( t1, t4, &Overflow ); /*Qx*/
272 : t1 = add_o( t1, t4, &Overflow ); /*Qx*/
273 : t4 = sub_o( t2, t3, &Overflow ); /*Qx*/
274 : t2 = add_o( t2, t3, &Overflow ); /*Qx*/
275 : *xup3 = sub_o( mult_r( t1, cc3 ), mult_r( t2, ss3 ), &Overflow ); /*Qx*/
276 : move16();
277 : xup3 -= n4;
278 : *xup3 = add_o( mult_r( t5, cc1 ), mult_r( t4, ss1 ), &Overflow ); /*Qx*/
279 : move16();
280 : *xdn8 = sub_o( mult_r( t5, ss1 ), mult_r( t4, cc1 ), &Overflow ); /*Qx*/
281 : move16();
282 :
283 : xdn8 += n4;
284 : *xdn8 = add_o( mult_r( t2, cc3 ), mult_r( t1, ss3 ), &Overflow ); /*Qx*/
285 : move16();
286 : #endif
287 :
288 106113 : xup1 -= n4;
289 106113 : xup1 += id;
290 106113 : xup3 += id;
291 106113 : xdn6 += id;
292 106113 : xdn8 += id;
293 : }
294 78729 : is = sub( shl( id, 1 ), n2 );
295 78729 : id = shl( id, 2 );
296 : }
297 : }
298 : }
299 :
300 : /*-----------------------------------------------------------------*
301 : * Length two butterflies
302 : *-----------------------------------------------------------------*/
303 :
304 14286 : is = 1;
305 14286 : move16();
306 14286 : id = 4;
307 14286 : move16();
308 45140 : WHILE( is < n )
309 : {
310 30854 : xi0 = x + is;
311 30854 : xi1 = xi0 + 1;
312 :
313 167274 : FOR( i0 = is; i0 <= n; i0 += id )
314 : {
315 136420 : r1 = *xi0;
316 136420 : move16();
317 : #ifdef ISSUE_1836_replace_overflow_libcom
318 136420 : *xi0 = add_sat( r1, *xi1 ); /*Qx*/
319 136420 : move16();
320 136420 : *xi1 = sub_sat( r1, *xi1 ); /*Qx*/
321 136420 : move16();
322 : #else
323 : *xi0 = add_o( r1, *xi1, &Overflow ); /*Qx*/
324 : move16();
325 : *xi1 = sub_o( r1, *xi1, &Overflow ); /*Qx*/
326 : move16();
327 : #endif
328 136420 : xi0 += id;
329 136420 : xi1 += id;
330 : }
331 30854 : is = sub( shl( id, 1 ), 1 );
332 30854 : id = shl( id, 2 );
333 : }
334 :
335 : /*-----------------------------------------------------------------*
336 : * Digit reverse counter
337 : *-----------------------------------------------------------------*/
338 :
339 14286 : j = 1;
340 14286 : move16();
341 397256 : FOR( i = 1; i < n; i++ )
342 : {
343 382970 : IF( LT_16( i, j ) )
344 : {
345 163210 : xt = x[j]; /*Qx*/
346 163210 : move16();
347 163210 : x[j] = x[i]; /*Qx*/
348 163210 : move16();
349 163210 : x[i] = xt; /*Qx*/
350 163210 : move16();
351 : }
352 382970 : k = shr( n, 1 );
353 717377 : WHILE( LT_16( k, j ) )
354 : {
355 334407 : j = sub( j, k );
356 334407 : k = shr( k, 1 );
357 : }
358 382970 : j = add( j, k );
359 : }
360 :
361 : /*-----------------------------------------------------------------*
362 : * Normalization
363 : *-----------------------------------------------------------------*/
364 :
365 14286 : tmp = div_s( 1, n ); /*Q15 */
366 411542 : FOR( i = 1; i <= n; i++ )
367 : {
368 397256 : x[i] = mult_r( x[i], tmp ); /*Qx*/
369 397256 : move16();
370 : }
371 :
372 14286 : return;
373 : }
374 :
375 : #define INV_SQRT_2_16 ( Word16 )( 0x5A82 ) /*Q15*/
376 34502 : void ifft_rel_fx32(
377 : Word32 io[], /* Qx i/o: input/output vector */
378 : const Word16 n, /* Q0 i : vector length */
379 : const Word16 m /* Q0 i : log2 of vector length */
380 : )
381 : {
382 : Word16 i, j, k;
383 : Word16 step;
384 : Word16 n2, n4, n8, i0;
385 : Word16 is, id;
386 : Word32 *x, *xi0, *xi1, *xi2, *xi3, *xi4, *xup1, *xdn6, *xup3, *xdn8;
387 : Word32 xt;
388 : Word32 r1;
389 : Word32 t1, t2, t3, t4, t5;
390 : Word16 cc1, cc3, ss1, ss3;
391 : const Word16 *s, *s3, *c, *c3;
392 : const Word16 *idx;
393 : Word32 temp[512];
394 34502 : Word16 n_inv = 128; /*1/256 in Q15*/
395 34502 : move16();
396 :
397 34502 : SWITCH( n )
398 : {
399 0 : case 128:
400 0 : n_inv = 256; /*1/128 in Q15*/
401 0 : BREAK;
402 244 : case 256:
403 244 : n_inv = 128; /*1/256 in Q15*/
404 244 : BREAK;
405 34258 : case 512:
406 34258 : n_inv = 64; /*1/512 in Q15*/
407 34258 : BREAK;
408 0 : default:
409 0 : assert( 0 );
410 : BREAK;
411 : }
412 34502 : move16();
413 :
414 : /*-----------------------------------------------------------------*
415 : * IFFT
416 : *-----------------------------------------------------------------*/
417 :
418 34502 : x = &io[-1];
419 34502 : n2 = shl( n, 1 ); /*Q0*/
420 310274 : FOR( k = 1; k < m; k++ )
421 : {
422 275772 : is = 0;
423 275772 : move16();
424 275772 : id = n2;
425 275772 : move16();
426 275772 : n2 = shr( n2, 1 ); /*Q0*/
427 275772 : n4 = shr( n2, 2 ); /*Q0*/
428 275772 : n8 = shr( n4, 1 ); /*Q0*/
429 964836 : WHILE( LT_16( is, sub( n, 1 ) ) )
430 : {
431 689064 : xi1 = x + is + 1; /*Qx*/
432 689064 : xi2 = xi1 + n4; /*Qx*/
433 689064 : xi3 = xi2 + n4; /*Qx*/
434 689064 : xi4 = xi3 + n4; /*Qx*/
435 :
436 6533664 : FOR( i = is; i < n; i += id )
437 : {
438 5844600 : t1 = L_sub( *xi1, *xi3 ); /*Qx*/
439 5844600 : *xi1 = L_add( *xi1, *xi3 ); /*Qx*/
440 5844600 : move32();
441 5844600 : *xi2 = L_shl( *xi2, 1 ); /*Qx*/
442 5844600 : move32();
443 5844600 : *xi3 = L_sub( t1, L_shl( *xi4, 1 ) ); /*Qx*/
444 5844600 : move32();
445 5844600 : *xi4 = L_add( t1, L_shl( *xi4, 1 ) ); /*Qx*/
446 5844600 : move32();
447 5844600 : IF( NE_16( n4, 1 ) )
448 : {
449 2922178 : t1 = Mpy_32_16_1( L_sub( *( xi2 + n8 ), *( xi1 + n8 ) ), INV_SQRT_2_16 ); /*Qx*/
450 2922178 : t2 = Mpy_32_16_1( L_add( *( xi4 + n8 ), *( xi3 + n8 ) ), INV_SQRT_2_16 ); /*Qx*/
451 :
452 2922178 : *( xi1 + n8 ) = L_add( *( xi1 + n8 ), *( xi2 + n8 ) ); /*Qx*/
453 2922178 : move32();
454 2922178 : *( xi2 + n8 ) = L_sub( *( xi4 + n8 ), *( xi3 + n8 ) ); /*Qx*/
455 2922178 : move32();
456 2922178 : *( xi3 + n8 ) = L_shl( L_negate( L_add( t2, t1 ) ), 1 ); /*Qx*/
457 2922178 : move32();
458 2922178 : *( xi4 + n8 ) = L_shl( L_sub( t1, t2 ), 1 ); /*Qx*/
459 2922178 : move32();
460 : }
461 5844600 : xi1 += id;
462 5844600 : xi2 += id;
463 5844600 : xi3 += id;
464 5844600 : xi4 += id;
465 : }
466 689064 : is = sub( shl( id, 1 ), n2 ); /*Q0*/
467 689064 : id = shl( id, 2 ); /*Q0*/
468 : }
469 : /*Can be acheived with a shr */
470 275772 : step = idiv1616( N_MAX_FFT, n2 );
471 275772 : move16();
472 :
473 275772 : s = sincos_t_ext_fx + step; /*Q15*/
474 275772 : c = s + shr( N_MAX_FFT, 2 ); /*Q15*/
475 275772 : s3 = sincos_t_ext_fx + imult1616( 3, step ); /*Q15*/
476 275772 : c3 = s3 + shr( N_MAX_FFT, 2 ); /*Q15*/
477 4400640 : FOR( j = 2; j <= n8; j++ )
478 : {
479 4124868 : cc1 = *c; /*Q15*/
480 4124868 : ss1 = *s; /*Q15*/
481 4124868 : cc3 = *c3; /*Q15*/
482 4124868 : ss3 = *s3; /*Q15*/
483 4124868 : move16();
484 4124868 : move16();
485 4124868 : move16();
486 4124868 : move16();
487 :
488 4124868 : is = 0;
489 4124868 : move16();
490 4124868 : id = shl( n2, 1 );
491 4124868 : move16();
492 :
493 4124868 : c += step;
494 4124868 : s += step;
495 :
496 4124868 : c3 += imult1616( 3, step ); /*Q15*/
497 4124868 : s3 += imult1616( 3, step ); /*Q15*/
498 9280404 : WHILE( LT_16( is, sub( n, 1 ) ) )
499 : {
500 5155536 : xup1 = x + add( j, is ); /*Qx*/
501 5155536 : xup3 = xup1 + shl( n4, 1 ); /*Qx*/
502 5155536 : xdn6 = xup3 - sub( shl( j, 1 ), 2 ); /*Qx*/
503 5155536 : xdn8 = xdn6 + shl( n4, 1 ); /*Qx*/
504 :
505 12989052 : FOR( i = is; i < n; i += id )
506 : {
507 7833516 : t1 = L_sub( *xup1, *xdn6 ); /*Qx*/
508 7833516 : *xup1 = L_add( *xup1, *xdn6 ); /*Qx*/
509 7833516 : move32();
510 7833516 : xup1 += n4;
511 7833516 : xdn6 -= n4;
512 :
513 7833516 : t2 = L_sub( *xdn6, *xup1 ); /*Qx*/
514 7833516 : *xdn6 = L_add( *xup1, *xdn6 ); /*Qx*/
515 7833516 : move32();
516 :
517 7833516 : xdn6 += n4;
518 7833516 : t3 = L_add( *xdn8, *xup3 ); /*Qx*/
519 7833516 : *xdn6 = L_sub( *xdn8, *xup3 ); /*Qx*/
520 7833516 : move32();
521 :
522 7833516 : xup3 += n4;
523 7833516 : xdn8 -= n4;
524 :
525 7833516 : t4 = L_add( *xup3, *xdn8 ); /*Qx*/
526 7833516 : *xup1 = L_sub( *xup3, *xdn8 ); /*Qx*/
527 7833516 : move32();
528 :
529 7833516 : t5 = L_sub( t1, t4 ); /*Qx*/
530 7833516 : t1 = L_add( t1, t4 ); /*Qx*/
531 7833516 : t4 = L_sub( t2, t3 ); /*Qx*/
532 7833516 : t2 = L_add( t2, t3 ); /*Qx*/
533 7833516 : *xup3 = L_sub( Mpy_32_16_1( t1, cc3 ), Mpy_32_16_1( t2, ss3 ) ); /*Qx*/
534 7833516 : move32();
535 7833516 : xup3 -= n4;
536 7833516 : *xup3 = L_add( Mpy_32_16_1( t5, cc1 ), Mpy_32_16_1( t4, ss1 ) ); /*Qx*/
537 7833516 : move32();
538 7833516 : *xdn8 = L_sub( Mpy_32_16_1( t5, ss1 ), Mpy_32_16_1( t4, cc1 ) ); /*Qx*/
539 7833516 : move32();
540 :
541 7833516 : xdn8 += n4;
542 7833516 : *xdn8 = L_add( Mpy_32_16_1( t2, cc3 ), Mpy_32_16_1( t1, ss3 ) ); /*Qx*/
543 7833516 : move32();
544 :
545 7833516 : xup1 -= n4;
546 7833516 : xup1 += id;
547 7833516 : xup3 += id;
548 7833516 : xdn6 += id;
549 7833516 : xdn8 += id;
550 : }
551 5155536 : is = sub( shl( id, 1 ), n2 ); /*Q0*/
552 5155536 : id = shl( id, 2 ); /*Q0*/
553 : }
554 : }
555 : }
556 :
557 : /*-----------------------------------------------------------------*
558 : * Length two butterflies
559 : *-----------------------------------------------------------------*/
560 :
561 34502 : is = 1;
562 34502 : move16();
563 34502 : id = 4;
564 34502 : move16();
565 206768 : WHILE( LT_16( is, n ) )
566 : {
567 172266 : xi0 = x + is;
568 172266 : xi1 = xi0 + 1;
569 :
570 6051124 : FOR( i0 = is; i0 <= n; i0 += id )
571 : {
572 5878858 : r1 = *xi0; /*Qx*/
573 5878858 : move32();
574 5878858 : *xi0 = L_add( r1, *xi1 ); /*Qx*/
575 5878858 : move32();
576 5878858 : *xi1 = L_sub( r1, *xi1 ); /*Qx*/
577 5878858 : move32();
578 5878858 : xi0 += id;
579 5878858 : xi1 += id;
580 : }
581 172266 : is = sub( shl( id, 1 ), 1 );
582 172266 : id = shl( id, 2 );
583 : }
584 :
585 : /*-----------------------------------------------------------------*
586 : * Digit reverse counter
587 : *-----------------------------------------------------------------*/
588 :
589 34502 : idx = fft256_read_indexes;
590 34502 : xi0 = &temp[0] - 1;
591 34502 : IF( EQ_16( n, 128 ) )
592 : {
593 0 : FOR( i = 0; i < n; i++ )
594 : {
595 0 : j = *idx++;
596 0 : move16();
597 0 : temp[i] = x[1 + shr( j, 1 )]; /*Qx*/
598 0 : move32();
599 : }
600 : }
601 34502 : ELSE IF( EQ_16( n, 256 ) )
602 : {
603 62708 : FOR( i = 0; i < n; i++ )
604 : {
605 62464 : j = *idx++;
606 62464 : temp[i] = x[1 + j]; /*Qx*/
607 62464 : move32();
608 : }
609 : }
610 34258 : ELSE IF( EQ_16( n, 512 ) )
611 : {
612 8804306 : FOR( i = 0; i < 256; i++ )
613 : {
614 8770048 : j = *idx++;
615 8770048 : temp[i] = x[1 + 2 * j]; /*Qx*/
616 8770048 : move32();
617 8770048 : temp[i + 256] = x[2 + 2 * j]; /*Qx*/
618 8770048 : move32();
619 : }
620 : }
621 : ELSE
622 : {
623 0 : xi0 = x;
624 0 : j = 1;
625 0 : move16();
626 0 : FOR( i = 1; i < n; i++ )
627 : {
628 0 : IF( LT_16( i, j ) )
629 : {
630 0 : xt = x[j]; /*Qx*/
631 0 : x[j] = x[i]; /*Qx*/
632 0 : x[i] = xt; /*Qx*/
633 0 : move32();
634 0 : move32();
635 0 : move32();
636 : }
637 0 : k = shr( n, 1 );
638 0 : WHILE( LT_16( k, j ) )
639 : {
640 0 : j = sub( j, k );
641 0 : k = shr( k, 1 );
642 : }
643 0 : j = add( j, k );
644 : }
645 : }
646 :
647 : /*-----------------------------------------------------------------*
648 : * Normalization
649 : *-----------------------------------------------------------------*/
650 :
651 17637062 : FOR( i = 1; i <= n; i++ )
652 : {
653 17602560 : x[i] = Mpy_32_16_1( xi0[i], n_inv ); /*Qx*/
654 17602560 : move32();
655 : }
656 :
657 34502 : return;
658 : }
|