00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "arm_math.h"
00027
00058 void arm_cfft_mag_q15(
00059 const arm_cfft_radix4_instance_q15 * S,
00060 q15_t * pSrc)
00061 {
00062
00063 arm_cfft_mag_butterfly_q15(pSrc, S->fftLen, S->pTwiddle,
00064 S->twidCoefModifier);
00065
00066 if(S->bitReverseFlag == 1u)
00067 {
00068
00069 arm_cfft_mag_bitreversal_q15(pSrc, S->fftLen, S->bitRevFactor, S->pBitRevTable);
00070 }
00071
00072 }
00073
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00121 void arm_cfft_mag_butterfly_q15(
00122 q15_t * pSrc16,
00123 uint32_t fftLen,
00124 q15_t * pCoef16,
00125 uint32_t twidCoefModifier)
00126 {
00127 q31_t R, S, T, U;
00128 q31_t C1, C2, C3, out1, out2;
00129 q31_t *pSrc, *pCoeff;
00130 uint32_t n1, n2, ic, i0, i1, i2, i3, j, k;
00131 q31_t in;
00132 q31_t cmplxm1, cmplxm2;
00133
00134 q15_t *ptr1, *pDst = &pSrc16[0];
00135
00136
00137
00138 q31_t xaya, xbyb, xcyc, xdyd;
00139
00140
00141
00142
00143
00144
00145 pSrc = (q31_t *) pSrc16;
00146 pCoeff = (q31_t *) pCoef16;
00147
00148
00149 n2 = fftLen;
00150 n1 = n2;
00151
00152
00153 n2 >>= 2u;
00154
00155
00156 ic = 0u;
00157
00158
00159 i0 = 0u;
00160 j = n2;
00161
00162
00163
00164
00165 do
00166 {
00167
00168
00169
00170
00171 i1 = i0 + n2;
00172 i2 = i1 + n2;
00173 i3 = i2 + n2;
00174
00175
00176
00177 T = pSrc[i0];
00178 in = ((int16_t) (T & 0xFFFF)) >> 2;
00179 T = ((T >> 2) & 0xFFFF0000) | (in & 0xFFFF);
00180
00181 S = pSrc[i2];
00182 in = ((int16_t) (S & 0xFFFF)) >> 2;
00183 S = ((S >> 2) & 0xFFFF0000) | (in & 0xFFFF);
00184
00185 R = __QADD16(T, S);
00186
00187 S = __QSUB16(T, S);
00188
00189
00190
00191 T = pSrc[i1];
00192 in = ((int16_t) (T & 0xFFFF)) >> 2;
00193 T = ((T >> 2) & 0xFFFF0000) | (in & 0xFFFF);
00194
00195 U = pSrc[i3];
00196 in = ((int16_t) (U & 0xFFFF)) >> 2;
00197 U = ((U >> 2) & 0xFFFF0000) | (in & 0xFFFF);
00198
00199 T = __QADD16(T, U);
00200
00201
00202
00203
00204 pSrc[i0] = __SHADD16(R, T);
00205
00206
00207 R = __QSUB16(R, T);
00208
00209
00210 C2 = pCoeff[2u * ic];
00211
00212 #ifndef ARM_MATH_BIG_ENDIAN
00213
00214
00215 out1 = __SMUAD(C2, R) >> 16u;
00216
00217 out2 = __SMUSDX(C2, R);
00218
00219 #else
00220
00221
00222 out1 = __SMUSDX(R, C2) >> 16u;
00223
00224 out2 = __SMUAD(C2, R);
00225
00226 #endif
00227
00228
00229
00230 T = pSrc[i1];
00231 in = ((int16_t) (T & 0xFFFF)) >> 2;
00232 T = ((T >> 2) & 0xFFFF0000) | (in & 0xFFFF);
00233
00234
00235
00236 pSrc[i1] = (q31_t) ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
00237
00238
00239
00240 U = pSrc[i3];
00241 in = ((int16_t) (U & 0xFFFF)) >> 2;
00242 U = ((U >> 2) & 0xFFFF0000) | (in & 0xFFFF);
00243
00244 T = __QSUB16(T, U);
00245
00246 #ifndef ARM_MATH_BIG_ENDIAN
00247
00248
00249 R = __QASX(S, T);
00250
00251 S = __QSAX(S, T);
00252
00253 #else
00254
00255
00256 R = __QSAX(S, T);
00257
00258 S = __QASX(S, T);
00259
00260 #endif
00261
00262
00263 C1 = pCoeff[ic];
00264
00265
00266 #ifndef ARM_MATH_BIG_ENDIAN
00267
00268
00269 out1 = __SMUAD(C1, S) >> 16u;
00270
00271 out2 = __SMUSDX(C1, S);
00272
00273 #else
00274
00275
00276 out1 = __SMUSDX(S, C1) >> 16u;
00277
00278 out2 = __SMUAD(C1, S);
00279
00280 #endif
00281
00282
00283 pSrc[i2] = ((out2) & 0xFFFF0000) | ((out1) & 0x0000FFFF);
00284
00285
00286
00287 C3 = pCoeff[3u * ic];
00288
00289
00290 #ifndef ARM_MATH_BIG_ENDIAN
00291
00292
00293 out1 = __SMUAD(C3, R) >> 16u;
00294
00295 out2 = __SMUSDX(C3, R);
00296
00297 #else
00298
00299
00300 out1 = __SMUSDX(R, C3) >> 16u;
00301
00302 out2 = __SMUAD(C3, R);
00303
00304 #endif
00305
00306
00307 pSrc[i3] = ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
00308
00309
00310 ic = ic + twidCoefModifier;
00311
00312
00313 i0 = i0 + 1u;
00314
00315 } while(--j);
00316
00317
00318
00319
00320
00321
00322
00323
00324 twidCoefModifier <<= 2u;
00325
00326
00327 for (k = fftLen / 4u; k > 4u; k >>= 2u)
00328 {
00329
00330 n1 = n2;
00331 n2 >>= 2u;
00332 ic = 0u;
00333
00334 for (j = 0u; j <= (n2 - 1u); j++)
00335 {
00336
00337 C1 = pCoeff[ic];
00338 C2 = pCoeff[2u * ic];
00339 C3 = pCoeff[3u * ic];
00340
00341
00342 ic = ic + twidCoefModifier;
00343
00344
00345 for (i0 = j; i0 < fftLen; i0 += n1)
00346 {
00347
00348
00349 i1 = i0 + n2;
00350 i2 = i1 + n2;
00351 i3 = i2 + n2;
00352
00353
00354
00355 T = pSrc[i0];
00356
00357
00358 S = pSrc[i2];
00359
00360
00361 R = __QADD16(T, S);
00362
00363
00364 S = __QSUB16(T, S);
00365
00366
00367
00368 T = pSrc[i1];
00369
00370
00371 U = pSrc[i3];
00372
00373
00374
00375 T = __QADD16(T, U);
00376
00377
00378
00379
00380
00381
00382 out1 = __SHADD16(R, T);
00383 in = ((int16_t) (out1 & 0xFFFF)) >> 1;
00384 out1 = ((out1 >> 1) & 0xFFFF0000) | (in & 0xFFFF);
00385 pSrc[i0] = out1;
00386
00387
00388 R = __SHSUB16(R, T);
00389
00390 #ifndef ARM_MATH_BIG_ENDIAN
00391
00392
00393 out1 = __SMUAD(C2, R) >> 16u;
00394
00395
00396 out2 = __SMUSDX(C2, R);
00397
00398 #else
00399
00400
00401 out1 = __SMUSDX(R, C2) >> 16u;
00402
00403
00404 out2 = __SMUAD(C2, R);
00405
00406 #endif
00407
00408
00409
00410 T = pSrc[i1];
00411
00412
00413
00414
00415 pSrc[i1] = ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
00416
00417
00418
00419
00420 U = pSrc[i3];
00421
00422
00423 T = __QSUB16(T, U);
00424
00425 #ifndef ARM_MATH_BIG_ENDIAN
00426
00427
00428 R = __SHASX(S, T);
00429
00430
00431 S = __SHSAX(S, T);
00432
00433
00434
00435 out1 = __SMUAD(C1, S) >> 16u;
00436 out2 = __SMUSDX(C1, S);
00437
00438 #else
00439
00440
00441 R = __SHSAX(S, T);
00442
00443
00444 S = __SHASX(S, T);
00445
00446
00447
00448 out1 = __SMUSDX(S, C1) >> 16u;
00449 out2 = __SMUAD(C1, S);
00450
00451 #endif
00452
00453
00454
00455 pSrc[i2] = ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
00456
00457
00458
00459 #ifndef ARM_MATH_BIG_ENDIAN
00460
00461 out1 = __SMUAD(C3, R) >> 16u;
00462 out2 = __SMUSDX(C3, R);
00463
00464 #else
00465
00466 out1 = __SMUSDX(R, C3) >> 16u;
00467 out2 = __SMUAD(C3, R);
00468
00469 #endif
00470
00471
00472
00473 pSrc[i3] = ((out2) & 0xFFFF0000) | (out1 & 0x0000FFFF);
00474 }
00475 }
00476
00477 twidCoefModifier <<= 2u;
00478 }
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488 j = fftLen >> 2;
00489
00490 ptr1 = &pSrc16[0];
00491
00492
00493
00494
00495 do
00496 {
00497
00498 xaya = *__SIMD32(ptr1)++;
00499
00500
00501 xbyb = *__SIMD32(ptr1)++;
00502
00503
00504 xcyc = *__SIMD32(ptr1)++;
00505
00506
00507 xdyd = *__SIMD32(ptr1)++;
00508
00509
00510 R = __QADD16(xaya, xcyc);
00511
00512
00513 T = __QADD16(xbyb, xdyd);
00514
00515
00516
00517 in = __SHADD16(R,T);
00518
00519
00520 T = __QADD16(xbyb, xdyd);
00521
00522 cmplxm1 = __SMUAD((q15_t)in, (q15_t)in);
00523 cmplxm2 = __SMUAD((q15_t)(in>>16), (q15_t)(in>>16));
00524
00525
00526
00527
00528 in = __SHSUB16(R, T);
00529
00530 arm_sqrt_q15((q15_t) (((q63_t) cmplxm1 + cmplxm2) >> 17), pDst++);
00531
00532
00533 S = __QSUB16(xaya, xcyc);
00534
00535 cmplxm1 = __SMUAD((q15_t)in, (q15_t)in);
00536 cmplxm2 = __SMUAD((q15_t)(in>>16), (q15_t)(in>>16));
00537
00538
00539
00540 U = __QSUB16(xbyb, xdyd);
00541
00542 arm_sqrt_q15((q15_t) (((q63_t) cmplxm1 + cmplxm2) >> 17), pDst++);
00543
00544 #ifndef ARM_MATH_BIG_ENDIAN
00545
00546 in = __SHSAX(S, U);
00547 cmplxm1 = __SMUAD((q15_t)in, (q15_t)in);
00548 cmplxm2 = __SMUAD((q15_t)(in>>16), (q15_t)(in>>16));
00549
00550 arm_sqrt_q15((q15_t) (((q63_t) cmplxm1 + cmplxm2) >> 17), pDst++);
00551
00552
00553
00554
00555
00556 in = __SHASX(S, U);
00557 cmplxm1 = __SMUAD((q15_t)in, (q15_t)in);
00558 cmplxm2 = __SMUAD((q15_t)(in>>16), (q15_t)(in>>16));
00559
00560 arm_sqrt_q15((q15_t) (((q63_t) cmplxm1 + cmplxm2) >> 17), pDst++);
00561
00562
00563
00564
00565 #else
00566
00567
00568 in = __SHASX(S, U);
00569 cmplxm1 = __SMUAD((q15_t)in, (q15_t)in);
00570 cmplxm2 = __SMUAD((q15_t)(in>>16), (q15_t)(in>>16));
00571
00572 arm_sqrt_q15((q15_t) (((q63_t) cmplxm1 + cmplxm2) >> 17), pDst++);
00573
00574
00575
00576
00577 in = __SHSAX(S, U);
00578 cmplxm1 = __SMUAD((q15_t)in, (q15_t)in);
00579 cmplxm2 = __SMUAD((q15_t)(in>>16), (q15_t)(in>>16));
00580
00581 arm_sqrt_q15((q15_t) (((q63_t) cmplxm1 + cmplxm2) >> 17), pDst++);
00582
00583 #endif
00584
00585 }while(--j);
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597 }
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609 void arm_cfft_mag_bitreversal_q15(
00610 q15_t * pSrc16,
00611 uint32_t fftLen,
00612 uint16_t bitRevFactor,
00613 uint16_t * pBitRevTab)
00614 {
00615 q15_t *pSrc = pSrc16;
00616 q15_t in;
00617 uint32_t fftLenBy2, fftLenBy2p1;
00618 uint32_t i, j;
00619
00620
00621 j = 0u;
00622 fftLenBy2 = fftLen / 2u;
00623 fftLenBy2p1 = (fftLen / 2u) + 1u;
00624
00625
00626 for (i = 0u; i <= (fftLenBy2 - 2u); i += 2u)
00627 {
00628 if(i < j)
00629 {
00630
00631
00632 in = pSrc[i];
00633 pSrc[i] = pSrc[j];
00634 pSrc[j] = in;
00635
00636
00637
00638 in = pSrc[i + fftLenBy2p1];
00639 pSrc[i + fftLenBy2p1] = pSrc[j + fftLenBy2p1];
00640 pSrc[j + fftLenBy2p1] = in;
00641 }
00642
00643
00644
00645 in = pSrc[i + 1u];
00646 pSrc[i + 1u] = pSrc[j + fftLenBy2];
00647 pSrc[j + fftLenBy2] = in;
00648
00649
00650 j = *pBitRevTab;
00651
00652
00653 pBitRevTab += bitRevFactor;
00654 }
00655 }