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 #include "arm_math.h"
00026
00165 void arm_cfft_radix4_f32(
00166 const arm_cfft_radix4_instance_f32 * S,
00167 float32_t * pSrc)
00168 {
00169
00170 if(S->ifftFlag == 1u)
00171 {
00172
00173 arm_radix4_butterfly_inverse_f32(pSrc, S->fftLen, S->pTwiddle,
00174 S->twidCoefModifier, S->onebyfftLen);
00175 }
00176 else
00177 {
00178
00179 arm_radix4_butterfly_f32(pSrc, S->fftLen, S->pTwiddle,
00180 S->twidCoefModifier);
00181 }
00182
00183 if(S->bitReverseFlag == 1u)
00184 {
00185
00186 arm_bitreversal_f32(pSrc, S->fftLen, S->bitRevFactor, S->pBitRevTable);
00187 }
00188
00189 }
00190
00191
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211 void arm_radix4_butterfly_f32(
00212 float32_t * pSrc,
00213 uint16_t fftLen,
00214 float32_t * pCoef,
00215 uint16_t twidCoefModifier)
00216 {
00217
00218 float32_t co1, co2, co3, si1, si2, si3;
00219 uint32_t ia1, ia2, ia3;
00220 uint32_t i0, i1, i2, i3;
00221 uint32_t n1, n2, j, k;
00222
00223 float32_t xaIn, yaIn, xbIn, ybIn, xcIn, ycIn, xdIn, ydIn;
00224 float32_t Xaplusc, Xbplusd, Yaplusc, Ybplusd, Xaminusc, Xbminusd, Yaminusc, Ybminusd;
00225 float32_t Xb12C_out, Yb12C_out, Xc12C_out, Yc12C_out, Xd12C_out, Yd12C_out;
00226 float32_t Xb12_out, Yb12_out, Xc12_out, Yc12_out, Xd12_out, Yd12_out;
00227 float32_t *ptr1;
00228
00229
00230 n2 = fftLen;
00231 n1 = n2;
00232
00233
00234 n2 >>= 2u;
00235 i0 = 0u;
00236 ia1 = 0u;
00237
00238 j = n2;
00239
00240
00241 do
00242 {
00243
00244
00245 i1 = i0 + n2;
00246 i2 = i1 + n2;
00247 i3 = i2 + n2;
00248
00249 xaIn = pSrc[(2u * i0)];
00250 yaIn = pSrc[(2u * i0) + 1u];
00251
00252 xcIn = pSrc[(2u * i2)];
00253 ycIn = pSrc[(2u * i2) + 1u];
00254
00255 xbIn = pSrc[(2u * i1)];
00256 ybIn = pSrc[(2u * i1) + 1u];
00257
00258 xdIn = pSrc[(2u * i3)];
00259 ydIn = pSrc[(2u * i3) + 1u];
00260
00261
00262 Xaplusc = xaIn + xcIn;
00263
00264 Xbplusd = xbIn + xdIn;
00265
00266 Yaplusc = yaIn + ycIn;
00267
00268 Ybplusd = ybIn + ydIn;
00269
00270
00271 ia2 = ia1 + ia1;
00272 co2 = pCoef[ia2 * 2u];
00273 si2 = pCoef[(ia2 * 2u) + 1u];
00274
00275
00276 Xaminusc = xaIn - xcIn;
00277
00278 Xbminusd = xbIn - xdIn;
00279
00280 Yaminusc = yaIn - ycIn;
00281
00282 Ybminusd = ybIn - ydIn;
00283
00284
00285 pSrc[(2u * i0)] = Xaplusc + Xbplusd;
00286
00287 pSrc[(2u * i0) + 1u] = Yaplusc + Ybplusd;
00288
00289
00290 Xb12C_out = (Xaminusc + Ybminusd);
00291
00292 Yb12C_out = (Yaminusc - Xbminusd);
00293
00294 Xc12C_out = (Xaplusc - Xbplusd);
00295
00296 Yc12C_out = (Yaplusc - Ybplusd);
00297
00298 Xd12C_out = (Xaminusc - Ybminusd);
00299
00300 Yd12C_out = (Xbminusd + Yaminusc);
00301
00302 co1 = pCoef[ia1 * 2u];
00303 si1 = pCoef[(ia1 * 2u) + 1u];
00304
00305
00306 ia3 = ia2 + ia1;
00307 co3 = pCoef[ia3 * 2u];
00308 si3 = pCoef[(ia3 * 2u) + 1u];
00309
00310 Xb12_out = Xb12C_out * co1;
00311 Yb12_out = Yb12C_out * co1;
00312 Xc12_out = Xc12C_out * co2;
00313 Yc12_out = Yc12C_out * co2;
00314 Xd12_out = Xd12C_out * co3;
00315 Yd12_out = Yd12C_out * co3;
00316
00317
00318 Xb12_out += Yb12C_out * si1;
00319
00320 Yb12_out -= Xb12C_out * si1;
00321
00322 Xc12_out += Yc12C_out * si2;
00323
00324 Yc12_out -= Xc12C_out * si2;
00325
00326 Xd12_out += Yd12C_out * si3;
00327
00328 Yd12_out -= Xd12C_out * si3;
00329
00330
00331
00332 pSrc[2u * i1] = Xc12_out;
00333
00334
00335 pSrc[(2u * i1) + 1u] = Yc12_out;
00336
00337
00338 pSrc[2u * i2] = Xb12_out;
00339
00340
00341 pSrc[(2u * i2) + 1u] = Yb12_out;
00342
00343
00344 pSrc[2u * i3] = Xd12_out;
00345
00346
00347 pSrc[(2u * i3) + 1u] = Yd12_out;
00348
00349
00350 ia1 = ia1 + twidCoefModifier;
00351
00352
00353 i0 = i0 + 1u;
00354
00355 }
00356 while(--j);
00357
00358 twidCoefModifier <<= 2u;
00359
00360
00361 for (k = fftLen / 4; k > 4u; k >>= 2u)
00362 {
00363
00364 n1 = n2;
00365 n2 >>= 2u;
00366 ia1 = 0u;
00367
00368
00369 for (j = 0u; j <= (n2 - 1u); j++)
00370 {
00371
00372 ia2 = ia1 + ia1;
00373 ia3 = ia2 + ia1;
00374 co1 = pCoef[ia1 * 2u];
00375 si1 = pCoef[(ia1 * 2u) + 1u];
00376 co2 = pCoef[ia2 * 2u];
00377 si2 = pCoef[(ia2 * 2u) + 1u];
00378 co3 = pCoef[ia3 * 2u];
00379 si3 = pCoef[(ia3 * 2u) + 1u];
00380
00381
00382 ia1 = ia1 + twidCoefModifier;
00383
00384 for (i0 = j; i0 < fftLen; i0 += n1)
00385 {
00386
00387
00388 i1 = i0 + n2;
00389 i2 = i1 + n2;
00390 i3 = i2 + n2;
00391
00392 xaIn = pSrc[(2u * i0)];
00393 yaIn = pSrc[(2u * i0) + 1u];
00394
00395 xbIn = pSrc[(2u * i1)];
00396 ybIn = pSrc[(2u * i1) + 1u];
00397
00398 xcIn = pSrc[(2u * i2)];
00399 ycIn = pSrc[(2u * i2) + 1u];
00400
00401 xdIn = pSrc[(2u * i3)];
00402 ydIn = pSrc[(2u * i3) + 1u];
00403
00404
00405 Xaminusc = xaIn - xcIn;
00406
00407 Xbminusd = xbIn - xdIn;
00408
00409 Yaminusc = yaIn - ycIn;
00410
00411 Ybminusd = ybIn - ydIn;
00412
00413
00414 Xaplusc = xaIn + xcIn;
00415
00416 Xbplusd = xbIn + xdIn;
00417
00418 Yaplusc = yaIn + ycIn;
00419
00420 Ybplusd = ybIn + ydIn;
00421
00422
00423 Xb12C_out = (Xaminusc + Ybminusd);
00424
00425 Yb12C_out = (Yaminusc - Xbminusd);
00426
00427 Xc12C_out = (Xaplusc - Xbplusd);
00428
00429 Yc12C_out = (Yaplusc - Ybplusd);
00430
00431 Xd12C_out = (Xaminusc - Ybminusd);
00432
00433 Yd12C_out = (Xbminusd + Yaminusc);
00434
00435 pSrc[(2u * i0)] = Xaplusc + Xbplusd;
00436 pSrc[(2u * i0) + 1u] = Yaplusc + Ybplusd;
00437
00438 Xb12_out = Xb12C_out * co1;
00439 Yb12_out = Yb12C_out * co1;
00440 Xc12_out = Xc12C_out * co2;
00441 Yc12_out = Yc12C_out * co2;
00442 Xd12_out = Xd12C_out * co3;
00443 Yd12_out = Yd12C_out * co3;
00444
00445
00446 Xb12_out += Yb12C_out * si1;
00447
00448 Yb12_out -= Xb12C_out * si1;
00449
00450 Xc12_out += Yc12C_out * si2;
00451
00452 Yc12_out -= Xc12C_out * si2;
00453
00454 Xd12_out += Yd12C_out * si3;
00455
00456 Yd12_out -= Xd12C_out * si3;
00457
00458
00459 pSrc[2u * i1] = Xc12_out;
00460
00461
00462 pSrc[(2u * i1) + 1u] = Yc12_out;
00463
00464
00465 pSrc[2u * i2] = Xb12_out;
00466
00467
00468 pSrc[(2u * i2) + 1u] = Yb12_out;
00469
00470
00471 pSrc[2u * i3] = Xd12_out;
00472
00473
00474 pSrc[(2u * i3) + 1u] = Yd12_out;
00475
00476 }
00477 }
00478 twidCoefModifier <<= 2u;
00479 }
00480
00481 j = fftLen >> 2;
00482 ptr1 = &pSrc[0];
00483
00484
00485 do
00486 {
00487
00488 xaIn = ptr1[0];
00489 xcIn = ptr1[4];
00490 yaIn = ptr1[1];
00491 ycIn = ptr1[5];
00492
00493
00494 Xaplusc = xaIn + xcIn;
00495
00496 xbIn = ptr1[2];
00497
00498
00499 Xaminusc = xaIn - xcIn;
00500
00501 xdIn = ptr1[6];
00502
00503
00504 Yaplusc = yaIn + ycIn;
00505
00506 ybIn = ptr1[3];
00507
00508
00509 Yaminusc = yaIn - ycIn;
00510
00511 ydIn = ptr1[7];
00512
00513
00514 Xbplusd = xbIn + xdIn;
00515
00516
00517 Ybplusd = ybIn + ydIn;
00518
00519
00520 ptr1[0] = (Xaplusc + Xbplusd);
00521
00522
00523 Xbminusd = xbIn - xdIn;
00524
00525
00526 ptr1[1] = (Yaplusc + Ybplusd);
00527
00528
00529 Ybminusd = ybIn - ydIn;
00530
00531
00532 ptr1[2] = (Xaplusc - Xbplusd);
00533
00534 ptr1[3] = (Yaplusc - Ybplusd);
00535
00536 ptr1[4] = (Xaminusc + Ybminusd);
00537
00538 ptr1[5] = (Yaminusc - Xbminusd);
00539
00540 ptr1[6] = (Xaminusc - Ybminusd);
00541
00542 ptr1[7] = (Xbminusd + Yaminusc);
00543
00544
00545 ptr1 = ptr1 + 8u;
00546
00547 }while(--j);
00548
00549 }
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561 void arm_radix4_butterfly_inverse_f32(
00562 float32_t * pSrc,
00563 uint16_t fftLen,
00564 float32_t * pCoef,
00565 uint16_t twidCoefModifier,
00566 float32_t onebyfftLen)
00567 {
00568 float32_t co1, co2, co3, si1, si2, si3;
00569 uint32_t ia1, ia2, ia3;
00570 uint32_t i0, i1, i2, i3;
00571 uint32_t n1, n2, j, k;
00572
00573 float32_t xaIn, yaIn, xbIn, ybIn, xcIn, ycIn, xdIn, ydIn;
00574 float32_t Xaplusc, Xbplusd, Yaplusc, Ybplusd, Xaminusc, Xbminusd, Yaminusc, Ybminusd;
00575 float32_t Xb12C_out, Yb12C_out, Xc12C_out, Yc12C_out, Xd12C_out, Yd12C_out;
00576 float32_t Xb12_out, Yb12_out, Xc12_out, Yc12_out, Xd12_out, Yd12_out;
00577 float32_t *ptr1;
00578
00579
00580
00581 n2 = fftLen;
00582 n1 = n2;
00583
00584
00585 n2 >>= 2u;
00586 i0 = 0u;
00587 ia1 = 0u;
00588
00589 j = n2;
00590
00591
00592 do
00593 {
00594
00595
00596 i1 = i0 + n2;
00597 i2 = i1 + n2;
00598 i3 = i2 + n2;
00599
00600
00601 xaIn = pSrc[(2u * i0)];
00602 yaIn = pSrc[(2u * i0) + 1u];
00603
00604 xcIn = pSrc[(2u * i2)];
00605 ycIn = pSrc[(2u * i2) + 1u];
00606
00607 xbIn = pSrc[(2u * i1)];
00608 ybIn = pSrc[(2u * i1) + 1u];
00609
00610 xdIn = pSrc[(2u * i3)];
00611 ydIn = pSrc[(2u * i3) + 1u];
00612
00613
00614 Xaplusc = xaIn + xcIn;
00615
00616 Xbplusd = xbIn + xdIn;
00617
00618 Yaplusc = yaIn + ycIn;
00619
00620 Ybplusd = ybIn + ydIn;
00621
00622
00623 ia2 = ia1 + ia1;
00624 co2 = pCoef[ia2 * 2u];
00625 si2 = pCoef[(ia2 * 2u) + 1u];
00626
00627
00628 Xaminusc = xaIn - xcIn;
00629
00630 Xbminusd = xbIn - xdIn;
00631
00632 Yaminusc = yaIn - ycIn;
00633
00634 Ybminusd = ybIn - ydIn;
00635
00636
00637 pSrc[(2u * i0)] = Xaplusc + Xbplusd;
00638
00639
00640 pSrc[(2u * i0) + 1u] = Yaplusc + Ybplusd;
00641
00642
00643 Xb12C_out = (Xaminusc - Ybminusd);
00644
00645 Yb12C_out = (Yaminusc + Xbminusd);
00646
00647 Xc12C_out = (Xaplusc - Xbplusd);
00648
00649 Yc12C_out = (Yaplusc - Ybplusd);
00650
00651 Xd12C_out = (Xaminusc + Ybminusd);
00652
00653 Yd12C_out = (Yaminusc - Xbminusd);
00654
00655 co1 = pCoef[ia1 * 2u];
00656 si1 = pCoef[(ia1 * 2u) + 1u];
00657
00658
00659 ia3 = ia2 + ia1;
00660 co3 = pCoef[ia3 * 2u];
00661 si3 = pCoef[(ia3 * 2u) + 1u];
00662
00663 Xb12_out = Xb12C_out * co1;
00664 Yb12_out = Yb12C_out * co1;
00665 Xc12_out = Xc12C_out * co2;
00666 Yc12_out = Yc12C_out * co2;
00667 Xd12_out = Xd12C_out * co3;
00668 Yd12_out = Yd12C_out * co3;
00669
00670
00671 Xb12_out -= Yb12C_out * si1;
00672
00673 Yb12_out += Xb12C_out * si1;
00674
00675 Xc12_out -= Yc12C_out * si2;
00676
00677 Yc12_out += Xc12C_out * si2;
00678
00679 Xd12_out -= Yd12C_out * si3;
00680
00681 Yd12_out += Xd12C_out * si3;
00682
00683
00684 pSrc[2u * i1] = Xc12_out;
00685
00686
00687 pSrc[(2u * i1) + 1u] = Yc12_out;
00688
00689
00690 pSrc[2u * i2] = Xb12_out;
00691
00692
00693 pSrc[(2u * i2) + 1u] = Yb12_out;
00694
00695
00696 pSrc[2u * i3] = Xd12_out;
00697
00698
00699 pSrc[(2u * i3) + 1u] = Yd12_out;
00700
00701
00702 ia1 = ia1 + twidCoefModifier;
00703
00704
00705 i0 = i0 + 1u;
00706
00707 }
00708 while(--j);
00709 twidCoefModifier <<= 2u;
00710
00711
00712 for (k = fftLen / 4; k > 4u; k >>= 2u)
00713 {
00714
00715 n1 = n2;
00716 n2 >>= 2u;
00717 ia1 = 0u;
00718
00719
00720 for (j = 0u; j <= (n2 - 1u); j++)
00721 {
00722
00723 ia2 = ia1 + ia1;
00724 ia3 = ia2 + ia1;
00725 co1 = pCoef[ia1 * 2u];
00726 si1 = pCoef[(ia1 * 2u) + 1u];
00727 co2 = pCoef[ia2 * 2u];
00728 si2 = pCoef[(ia2 * 2u) + 1u];
00729 co3 = pCoef[ia3 * 2u];
00730 si3 = pCoef[(ia3 * 2u) + 1u];
00731
00732
00733 ia1 = ia1 + twidCoefModifier;
00734
00735 for (i0 = j; i0 < fftLen; i0 += n1)
00736 {
00737
00738
00739 i1 = i0 + n2;
00740 i2 = i1 + n2;
00741 i3 = i2 + n2;
00742
00743 xaIn = pSrc[(2u * i0)];
00744 yaIn = pSrc[(2u * i0) + 1u];
00745
00746 xbIn = pSrc[(2u * i1)];
00747 ybIn = pSrc[(2u * i1) + 1u];
00748
00749 xcIn = pSrc[(2u * i2)];
00750 ycIn = pSrc[(2u * i2) + 1u];
00751
00752 xdIn = pSrc[(2u * i3)];
00753 ydIn = pSrc[(2u * i3) + 1u];
00754
00755
00756 Xaminusc = xaIn - xcIn;
00757
00758 Xbminusd = xbIn - xdIn;
00759
00760 Yaminusc = yaIn - ycIn;
00761
00762 Ybminusd = ybIn - ydIn;
00763
00764
00765 Xaplusc = xaIn + xcIn;
00766
00767 Xbplusd = xbIn + xdIn;
00768
00769 Yaplusc = yaIn + ycIn;
00770
00771 Ybplusd = ybIn + ydIn;
00772
00773
00774 Xb12C_out = (Xaminusc - Ybminusd);
00775
00776 Yb12C_out = (Yaminusc + Xbminusd);
00777
00778 Xc12C_out = (Xaplusc - Xbplusd);
00779
00780 Yc12C_out = (Yaplusc - Ybplusd);
00781
00782 Xd12C_out = (Xaminusc + Ybminusd);
00783
00784 Yd12C_out = (Yaminusc - Xbminusd);
00785
00786 pSrc[(2u * i0)] = Xaplusc + Xbplusd;
00787 pSrc[(2u * i0) + 1u] = Yaplusc + Ybplusd;
00788
00789 Xb12_out = Xb12C_out * co1;
00790 Yb12_out = Yb12C_out * co1;
00791 Xc12_out = Xc12C_out * co2;
00792 Yc12_out = Yc12C_out * co2;
00793 Xd12_out = Xd12C_out * co3;
00794 Yd12_out = Yd12C_out * co3;
00795
00796
00797 Xb12_out -= Yb12C_out * si1;
00798
00799 Yb12_out += Xb12C_out * si1;
00800
00801 Xc12_out -= Yc12C_out * si2;
00802
00803 Yc12_out += Xc12C_out * si2;
00804
00805 Xd12_out -= Yd12C_out * si3;
00806
00807 Yd12_out += Xd12C_out * si3;
00808
00809
00810 pSrc[2u * i1] = Xc12_out;
00811
00812
00813 pSrc[(2u * i1) + 1u] = Yc12_out;
00814
00815
00816 pSrc[2u * i2] = Xb12_out;
00817
00818
00819 pSrc[(2u * i2) + 1u] = Yb12_out;
00820
00821
00822 pSrc[2u * i3] = Xd12_out;
00823
00824
00825 pSrc[(2u * i3) + 1u] = Yd12_out;
00826
00827 }
00828 }
00829 twidCoefModifier <<= 2u;
00830 }
00831
00832
00833 j = fftLen >> 2;
00834 ptr1 = &pSrc[0];
00835
00836
00837 do
00838 {
00839
00840 xaIn = ptr1[0];
00841 xcIn = ptr1[4];
00842 yaIn = ptr1[1];
00843 ycIn = ptr1[5];
00844
00845
00846
00847 Xaplusc = xaIn + xcIn;
00848
00849 xbIn = ptr1[2];
00850
00851
00852 Xaminusc = xaIn - xcIn;
00853
00854 xdIn = ptr1[6];
00855
00856
00857 Yaplusc = yaIn + ycIn;
00858
00859 ybIn = ptr1[3];
00860
00861
00862 Yaminusc = yaIn - ycIn;
00863
00864 ydIn = ptr1[7];
00865
00866
00867 Xbplusd = xbIn + xdIn;
00868
00869
00870 Ybplusd = ybIn + ydIn;
00871
00872
00873 ptr1[0] = (Xaplusc + Xbplusd) * onebyfftLen;
00874
00875
00876 Xbminusd = xbIn - xdIn;
00877
00878
00879 ptr1[1] = (Yaplusc + Ybplusd) * onebyfftLen;
00880
00881
00882 Ybminusd = ybIn - ydIn;
00883
00884
00885 ptr1[2] = (Xaplusc - Xbplusd) * onebyfftLen;
00886
00887
00888 ptr1[3] = (Yaplusc - Ybplusd) * onebyfftLen;
00889
00890
00891 ptr1[4] = (Xaminusc - Ybminusd) * onebyfftLen;
00892
00893
00894 ptr1[5] = (Yaminusc + Xbminusd) * onebyfftLen;
00895
00896
00897 ptr1[6] = (Xaminusc + Ybminusd) * onebyfftLen;
00898
00899
00900 ptr1[7] = (Yaminusc - Xbminusd) * onebyfftLen;
00901
00902
00903 ptr1 = ptr1 + 8u;
00904
00905 }while(--j);
00906 }
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917 void arm_bitreversal_f32(
00918 float32_t * pSrc,
00919 uint16_t fftSize,
00920 uint16_t bitRevFactor,
00921 uint16_t * pBitRevTab)
00922 {
00923 uint16_t fftLenBy2, fftLenBy2p1;
00924 uint16_t i, j;
00925 float32_t in;
00926
00927
00928 j = 0u;
00929 fftLenBy2 = fftSize >> 1u;
00930 fftLenBy2p1 = (fftSize >> 1u) + 1u;
00931
00932
00933 for (i = 0u; i <= (fftLenBy2 - 2u); i += 2u)
00934 {
00935 if(i < j)
00936 {
00937
00938 in = pSrc[2u * i];
00939 pSrc[2u * i] = pSrc[2u * j];
00940 pSrc[2u * j] = in;
00941
00942
00943 in = pSrc[(2u * i) + 1u];
00944 pSrc[(2u * i) + 1u] = pSrc[(2u * j) + 1u];
00945 pSrc[(2u * j) + 1u] = in;
00946
00947
00948 in = pSrc[2u * (i + fftLenBy2p1)];
00949 pSrc[2u * (i + fftLenBy2p1)] = pSrc[2u * (j + fftLenBy2p1)];
00950 pSrc[2u * (j + fftLenBy2p1)] = in;
00951
00952
00953 in = pSrc[(2u * (i + fftLenBy2p1)) + 1u];
00954 pSrc[(2u * (i + fftLenBy2p1)) + 1u] =
00955 pSrc[(2u * (j + fftLenBy2p1)) + 1u];
00956 pSrc[(2u * (j + fftLenBy2p1)) + 1u] = in;
00957
00958 }
00959
00960
00961 in = pSrc[2u * (i + 1u)];
00962 pSrc[2u * (i + 1u)] = pSrc[2u * (j + fftLenBy2)];
00963 pSrc[2u * (j + fftLenBy2)] = in;
00964
00965
00966 in = pSrc[(2u * (i + 1u)) + 1u];
00967 pSrc[(2u * (i + 1u)) + 1u] = pSrc[(2u * (j + fftLenBy2)) + 1u];
00968 pSrc[(2u * (j + fftLenBy2)) + 1u] = in;
00969
00970
00971 j = *pBitRevTab;
00972
00973
00974 pBitRevTab += bitRevFactor;
00975 }
00976 }