LCOV - code coverage report
Current view: top level - lib_lc3plus/fft - cfft.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 0 151 0.0 %
Date: 2025-05-23 08:37:30 Functions: 0 7 0.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             : *                        ETSI TS 103 634 V1.5.1                               *
       3             : *              Low Complexity Communication Codec Plus (LC3plus)              *
       4             : *                                                                             *
       5             : * Copyright licence is solely granted through ETSI Intellectual Property      *
       6             : * Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
       7             : * estoppel or otherwise.                                                      *
       8             : ******************************************************************************/
       9             : 
      10             : #include "options.h"
      11             : #include "wmc_auto.h"
      12             : #include "cfft.h"
      13             : #include "iisfft.h" /* for M_PIl  */
      14             : #include <stdlib.h> /* for abs() */
      15             : #include <assert.h>
      16             : 
      17             : #define MAX_FFT_SIZE 1024
      18             : #define MAX_TRIGDATA_SIZE (MAX_FFT_SIZE / 2)
      19             : 
      20             : /**
      21             :  * \brief table aTrigData
      22             : 
      23             :           Generate table:  aTrigData[i] = sin( pi * i / (2*MAX_TRIGDATA_SIZE) );   i = 0, ... MAX_TRIGDATA_SIZE
      24             :  */
      25             : static const LC3_FLOAT static_table[MAX_TRIGDATA_SIZE + 1] = {
      26             :     0.0000000000e+000, 3.0679567717e-003, 6.1358846724e-003, 9.2037543654e-003, 1.2271538377e-002, 1.5339205973e-002,
      27             :     1.8406730145e-002, 2.1474080160e-002, 2.4541229010e-002, 2.7608145028e-002, 3.0674804002e-002, 3.3741172403e-002,
      28             :     3.6807224154e-002, 3.9872925729e-002, 4.2938258499e-002, 4.6003181487e-002, 4.9067676067e-002, 5.2131704986e-002,
      29             :     5.5195245892e-002, 5.8258265257e-002, 6.1320737004e-002, 6.4382627606e-002, 6.7443922162e-002, 7.0504575968e-002,
      30             :     7.3564566672e-002, 7.6623864472e-002, 7.9682439566e-002, 8.2740262151e-002, 8.5797309875e-002, 8.8853552938e-002,
      31             :     9.1908954084e-002, 9.4963498414e-002, 9.8017141223e-002, 1.0106986016e-001, 1.0412163287e-001, 1.0717242211e-001,
      32             :     1.1022220552e-001, 1.1327095330e-001, 1.1631862819e-001, 1.1936521530e-001, 1.2241067737e-001, 1.2545497715e-001,
      33             :     1.2849810719e-001, 1.3154003024e-001, 1.3458070159e-001, 1.3762012124e-001, 1.4065824449e-001, 1.4369502664e-001,
      34             :     1.4673046768e-001, 1.4976453781e-001, 1.5279719234e-001, 1.5582840145e-001, 1.5885815024e-001, 1.6188639402e-001,
      35             :     1.6491311789e-001, 1.6793829203e-001, 1.7096188664e-001, 1.7398387194e-001, 1.7700421810e-001, 1.8002289534e-001,
      36             :     1.8303988874e-001, 1.8605515361e-001, 1.8906866014e-001, 1.9208039343e-001, 1.9509032369e-001, 1.9809840620e-001,
      37             :     2.0110464096e-001, 2.0410896838e-001, 2.0711137354e-001, 2.1011184156e-001, 2.1311031282e-001, 2.1610680223e-001,
      38             :     2.1910123527e-001, 2.2209362686e-001, 2.2508391738e-001, 2.2807207704e-001, 2.3105810583e-001, 2.3404195905e-001,
      39             :     2.3702360690e-001, 2.4000301957e-001, 2.4298018217e-001, 2.4595504999e-001, 2.4892760813e-001, 2.5189781189e-001,
      40             :     2.5486564636e-001, 2.5783109665e-001, 2.6079410315e-001, 2.6375466585e-001, 2.6671275496e-001, 2.6966831088e-001,
      41             :     2.7262136340e-001, 2.7557182312e-001, 2.7851969004e-001, 2.8146493435e-001, 2.8440752625e-001, 2.8734746575e-001,
      42             :     2.9028466344e-001, 2.9321914911e-001, 2.9615089297e-001, 2.9907983541e-001, 3.0200594664e-001, 3.0492922664e-001,
      43             :     3.0784964561e-001, 3.1076714396e-001, 3.1368175149e-001, 3.1659337878e-001, 3.1950202584e-001, 3.2240769267e-001,
      44             :     3.2531028986e-001, 3.2820984721e-001, 3.3110630512e-001, 3.3399966359e-001, 3.3688986301e-001, 3.3977687359e-001,
      45             :     3.4266072512e-001, 3.4554132819e-001, 3.4841868281e-001, 3.5129275918e-001, 3.5416352749e-001, 3.5703095794e-001,
      46             :     3.5989505053e-001, 3.6275571585e-001, 3.6561298370e-001, 3.6846682429e-001, 3.7131720781e-001, 3.7416407466e-001,
      47             :     3.7700742483e-001, 3.7984719872e-001, 3.8268342614e-001, 3.8551604748e-001, 3.8834503293e-001, 3.9117038250e-001,
      48             :     3.9399203658e-001, 3.9680999517e-001, 3.9962419868e-001, 4.0243464708e-001, 4.0524131060e-001, 4.0804415941e-001,
      49             :     4.1084316373e-001, 4.1363832355e-001, 4.1642954946e-001, 4.1921690106e-001, 4.2200025916e-001, 4.2477968335e-001,
      50             :     4.2755508423e-001, 4.3032649159e-001, 4.3309381604e-001, 4.3585708737e-001, 4.3861624599e-001, 4.4137126207e-001,
      51             :     4.4412213564e-001, 4.4686883688e-001, 4.4961133599e-001, 4.5234957337e-001, 4.5508357882e-001, 4.5781329274e-001,
      52             :     4.6053871512e-001, 4.6325978637e-001, 4.6597650647e-001, 4.6868881583e-001, 4.7139674425e-001, 4.7410020232e-001,
      53             :     4.7679921985e-001, 4.7949376702e-001, 4.8218378425e-001, 4.8486924171e-001, 4.8755016923e-001, 4.9022647738e-001,
      54             :     4.9289819598e-001, 4.9556526542e-001, 4.9822765589e-001, 5.0088536739e-001, 5.0353837013e-001, 5.0618666410e-001,
      55             :     5.0883013010e-001, 5.1146882772e-001, 5.1410275698e-001, 5.1673179865e-001, 5.1935601234e-001, 5.2197527885e-001,
      56             :     5.2458965778e-001, 5.2719914913e-001, 5.2980363369e-001, 5.3240311146e-001, 5.3499764204e-001, 5.3758704662e-001,
      57             :     5.4017144442e-001, 5.4275077581e-001, 5.4532498121e-001, 5.4789406061e-001, 5.5045795441e-001, 5.5301672220e-001,
      58             :     5.5557024479e-001, 5.5811852217e-001, 5.6066155434e-001, 5.6319934130e-001, 5.6573182344e-001, 5.6825894117e-001,
      59             :     5.7078075409e-001, 5.7329714298e-001, 5.7580816746e-001, 5.7831376791e-001, 5.8081394434e-001, 5.8330863714e-001,
      60             :     5.8579784632e-001, 5.8828157187e-001, 5.9075969458e-001, 5.9323227406e-001, 5.9569931030e-001, 5.9816068411e-001,
      61             :     6.0061645508e-001, 6.0306662321e-001, 6.0551106930e-001, 6.0794979334e-001, 6.1038279533e-001, 6.1281007528e-001,
      62             :     6.1523157358e-001, 6.1764729023e-001, 6.2005722523e-001, 6.2246125937e-001, 6.2485951185e-001, 6.2725180387e-001,
      63             :     6.2963825464e-001, 6.3201874495e-001, 6.3439327478e-001, 6.3676184416e-001, 6.3912445307e-001, 6.4148104191e-001,
      64             :     6.4383155107e-001, 6.4617604017e-001, 6.4851438999e-001, 6.5084666014e-001, 6.5317285061e-001, 6.5549284220e-001,
      65             :     6.5780669451e-001, 6.6011434793e-001, 6.6241580248e-001, 6.6471099854e-001, 6.6699993610e-001, 6.6928261518e-001,
      66             :     6.7155897617e-001, 6.7382901907e-001, 6.7609268427e-001, 6.7835003138e-001, 6.8060100079e-001, 6.8284553289e-001,
      67             :     6.8508368731e-001, 6.8731534481e-001, 6.8954056501e-001, 6.9175922871e-001, 6.9397145510e-001, 6.9617712498e-001,
      68             :     6.9837623835e-001, 7.0056879520e-001, 7.0275473595e-001, 7.0493406057e-001, 7.0710676908e-001, 7.0927280188e-001,
      69             :     7.1143221855e-001, 7.1358484030e-001, 7.1573084593e-001, 7.1787005663e-001, 7.2000253201e-001, 7.2212821245e-001,
      70             :     7.2424709797e-001, 7.2635912895e-001, 7.2846436501e-001, 7.3056274652e-001, 7.3265427351e-001, 7.3473888636e-001,
      71             :     7.3681658506e-001, 7.3888731003e-001, 7.4095112085e-001, 7.4300795794e-001, 7.4505776167e-001, 7.4710059166e-001,
      72             :     7.4913638830e-001, 7.5116515160e-001, 7.5318682194e-001, 7.5520139933e-001, 7.5720882416e-001, 7.5920921564e-001,
      73             :     7.6120239496e-001, 7.6318842173e-001, 7.6516723633e-001, 7.6713889837e-001, 7.6910334826e-001, 7.7106052637e-001,
      74             :     7.7301043272e-001, 7.7495312691e-001, 7.7688848972e-001, 7.7881652117e-001, 7.8073722124e-001, 7.8265058994e-001,
      75             :     7.8455656767e-001, 7.8645521402e-001, 7.8834640980e-001, 7.9023021460e-001, 7.9210656881e-001, 7.9397547245e-001,
      76             :     7.9583692551e-001, 7.9769086838e-001, 7.9953724146e-001, 8.0137616396e-001, 8.0320751667e-001, 8.0503135920e-001,
      77             :     8.0684757233e-001, 8.0865615606e-001, 8.1045717001e-001, 8.1225061417e-001, 8.1403630972e-001, 8.1581443548e-001,
      78             :     8.1758481264e-001, 8.1934750080e-001, 8.2110249996e-001, 8.2284981012e-001, 8.2458931208e-001, 8.2632106543e-001,
      79             :     8.2804507017e-001, 8.2976120710e-001, 8.3146959543e-001, 8.3317017555e-001, 8.3486288786e-001, 8.3654773235e-001,
      80             :     8.3822470903e-001, 8.3989381790e-001, 8.4155499935e-001, 8.4320825338e-001, 8.4485358000e-001, 8.4649091959e-001,
      81             :     8.4812033176e-001, 8.4974175692e-001, 8.5135519505e-001, 8.5296058655e-001, 8.5455799103e-001, 8.5614734888e-001,
      82             :     8.5772860050e-001, 8.5930180550e-001, 8.6086696386e-001, 8.6242395639e-001, 8.6397284269e-001, 8.6551362276e-001,
      83             :     8.6704623699e-001, 8.6857068539e-001, 8.7008696795e-001, 8.7159508467e-001, 8.7309497595e-001, 8.7458664179e-001,
      84             :     8.7607008219e-001, 8.7754529715e-001, 8.7901222706e-001, 8.8047087193e-001, 8.8192129135e-001, 8.8336336613e-001,
      85             :     8.8479709625e-001, 8.8622254133e-001, 8.8763964176e-001, 8.8904833794e-001, 8.9044874907e-001, 8.9184069633e-001,
      86             :     8.9322429895e-001, 8.9459949732e-001, 8.9596623182e-001, 8.9732456207e-001, 8.9867448807e-001, 9.0001589060e-001,
      87             :     9.0134882927e-001, 9.0267330408e-001, 9.0398931503e-001, 9.0529674292e-001, 9.0659570694e-001, 9.0788608789e-001,
      88             :     9.0916800499e-001, 9.1044127941e-001, 9.1170603037e-001, 9.1296219826e-001, 9.1420978308e-001, 9.1544872522e-001,
      89             :     9.1667908430e-001, 9.1790080070e-001, 9.1911387444e-001, 9.2031830549e-001, 9.2151403427e-001, 9.2270112038e-001,
      90             :     9.2387950420e-001, 9.2504924536e-001, 9.2621022463e-001, 9.2736250162e-001, 9.2850607634e-001, 9.2964088917e-001,
      91             :     9.3076694012e-001, 9.3188428879e-001, 9.3299281597e-001, 9.3409252167e-001, 9.3518352509e-001, 9.3626564741e-001,
      92             :     9.3733900785e-001, 9.3840354681e-001, 9.3945920467e-001, 9.4050604105e-001, 9.4154405594e-001, 9.4257318974e-001,
      93             :     9.4359344244e-001, 9.4460481405e-001, 9.4560730457e-001, 9.4660091400e-001, 9.4758558273e-001, 9.4856137037e-001,
      94             :     9.4952815771e-001, 9.5048606396e-001, 9.5143502951e-001, 9.5237499475e-001, 9.5330601931e-001, 9.5422810316e-001,
      95             :     9.5514118671e-001, 9.5604526997e-001, 9.5694035292e-001, 9.5782643557e-001, 9.5870345831e-001, 9.5957154036e-001,
      96             :     9.6043050289e-001, 9.6128046513e-001, 9.6212142706e-001, 9.6295326948e-001, 9.6377605200e-001, 9.6458977461e-001,
      97             :     9.6539443731e-001, 9.6618998051e-001, 9.6697646379e-001, 9.6775382757e-001, 9.6852207184e-001, 9.6928125620e-001,
      98             :     9.7003126144e-001, 9.7077214718e-001, 9.7150391340e-001, 9.7222650051e-001, 9.7293996811e-001, 9.7364425659e-001,
      99             :     9.7433936596e-001, 9.7502535582e-001, 9.7570210695e-001, 9.7636973858e-001, 9.7702813148e-001, 9.7767734528e-001,
     100             :     9.7831737995e-001, 9.7894817591e-001, 9.7956979275e-001, 9.8018211126e-001, 9.8078525066e-001, 9.8137921095e-001,
     101             :     9.8196387291e-001, 9.8253929615e-001, 9.8310548067e-001, 9.8366242647e-001, 9.8421007395e-001, 9.8474848270e-001,
     102             :     9.8527765274e-001, 9.8579752445e-001, 9.8630809784e-001, 9.8680937290e-001, 9.8730140924e-001, 9.8778414726e-001,
     103             :     9.8825758696e-001, 9.8872166872e-001, 9.8917651176e-001, 9.8962199688e-001, 9.9005818367e-001, 9.9048507214e-001,
     104             :     9.9090266228e-001, 9.9131083488e-001, 9.9170976877e-001, 9.9209928513e-001, 9.9247956276e-001, 9.9285042286e-001,
     105             :     9.9321192503e-001, 9.9356412888e-001, 9.9390697479e-001, 9.9424046278e-001, 9.9456459284e-001, 9.9487930536e-001,
     106             :     9.9518471956e-001, 9.9548077583e-001, 9.9576741457e-001, 9.9604469538e-001, 9.9631261826e-001, 9.9657112360e-001,
     107             :     9.9682027102e-001, 9.9706006050e-001, 9.9729043245e-001, 9.9751144648e-001, 9.9772304296e-001, 9.9792528152e-001,
     108             :     9.9811810255e-001, 9.9830156565e-001, 9.9847555161e-001, 9.9864023924e-001, 9.9879544973e-001, 9.9894130230e-001,
     109             :     9.9907773733e-001, 9.9920475483e-001, 9.9932235479e-001, 9.9943059683e-001, 9.9952942133e-001, 9.9961882830e-001,
     110             :     9.9969881773e-001, 9.9976938963e-001, 9.9983060360e-001, 9.9988234043e-001, 9.9992471933e-001, 9.9995762110e-001,
     111             :     9.9998116493e-001, 9.9999529123e-001, 1.0000000000e+000};
     112             : 
     113             : /**
     114             :  * \brief scramble
     115             :           The function sorts the complex vector re/im of length n from 'in-order' to 'bitreversed order'.
     116             : 
     117             :  * \param[i/o] re:   real input
     118             :  * \param[i/o] im:   imag input
     119             :  * \param[i  ] n:    size of fft
     120             :  * \param[i  ] s:    stride of real and imag input
     121             : 
     122             :  * \return none
     123             :  */
     124           0 : static void scramble(LC3_FLOAT* re, LC3_FLOAT* im, LC3_INT n, LC3_INT s)
     125             : {
     126             :     LC3_FLOAT tmp;
     127             :     LC3_INT   m, k, j;
     128             : 
     129           0 :     for (m = 1, j = 0; m < (n - 1); m++) {
     130             :         {
     131           0 :             for (k = n >> 1; (!((j ^= k) & k)); k >>= 1)
     132             :                 ;
     133             :         }
     134             : 
     135           0 :         if (j > m) {
     136           0 :             tmp       = re[s * m];
     137           0 :             re[s * m] = re[s * j];
     138           0 :             re[s * j] = tmp;
     139             : 
     140           0 :             tmp       = im[s * m];
     141           0 :             im[s * m] = im[s * j];
     142           0 :             im[s * j] = tmp;
     143             :         }
     144             :     }
     145           0 : }
     146             : 
     147             : /**
     148             :  * \brief fft
     149             :           The function performs a radix-2, decimation in time complex fft. The calculation takes place inplace.
     150             :           The real and imaginary part can reside in separate buffers as well as interleaved in one buffer. The
     151             :           stride length has to be set accordingly.
     152             : 
     153             :  * \param[i/o] re:          real input / real output
     154             :  * \param[i/o] im:          imag input / imag output
     155             :  * \param[i  ] sizeOfFft:   size of fft
     156             :  * \param[i  ] s:           stride of real and imag input / output
     157             : 
     158             :  * \return none
     159             :  */
     160           0 : static void fft(const LC3_FLOAT* aTrigData, LC3_INT trigdata_size, LC3_FLOAT* re, LC3_FLOAT* im, LC3_INT sizeOfFft,
     161             :                 LC3_INT s)
     162             : {
     163             :     LC3_INT trigstep, i, ldm, n;
     164             :     LC3_INT trigDataSize;
     165           0 :     LC3_INT ldn = 0;
     166             : 
     167           0 :     trigDataSize = sizeOfFft / 2;
     168             : 
     169           0 :     while (sizeOfFft >>= 1) {
     170           0 :         ldn++;
     171             :     }
     172             : 
     173           0 :     n = 1 << ldn;
     174             : 
     175           0 :     scramble(re, im, n, s);
     176             : 
     177             :     /* 1+2 stage implemented as radix 4 */
     178           0 :     for (i = 0; i < n; i += 4) {
     179             :         LC3_FLOAT a00, a01, a10, a11;
     180             :         LC3_FLOAT a20, a21, a30, a31;
     181             : 
     182           0 :         a00 = re[s * (i + 0)] + re[s * (i + 1)];
     183           0 :         a10 = re[s * (i + 2)] + re[s * (i + 3)];
     184           0 :         a20 = im[s * (i + 0)] + im[s * (i + 1)];
     185           0 :         a30 = im[s * (i + 2)] + im[s * (i + 3)];
     186             : 
     187           0 :         a01 = re[s * (i + 0)] - re[s * (i + 1)];
     188           0 :         a21 = re[s * (i + 2)] - re[s * (i + 3)];
     189           0 :         a31 = im[s * (i + 0)] - im[s * (i + 1)];
     190           0 :         a11 = im[s * (i + 2)] - im[s * (i + 3)];
     191             : 
     192           0 :         re[s * (i + 0)] = a00 + a10;
     193           0 :         re[s * (i + 2)] = a00 - a10;
     194           0 :         im[s * (i + 0)] = a20 + a30;
     195           0 :         im[s * (i + 2)] = a20 - a30;
     196           0 :         re[s * (i + 1)] = a11 + a01;
     197           0 :         re[s * (i + 3)] = a01 - a11;
     198           0 :         im[s * (i + 1)] = a31 - a21;
     199           0 :         im[s * (i + 3)] = a21 + a31;
     200             :     }
     201             : 
     202             :     /* next stages implemented as radix 2 */
     203           0 :     for (ldm = 3; ldm <= ldn; ++ldm) {
     204           0 :         const LC3_INT m  = (1 << ldm);
     205           0 :         const LC3_INT mh = (m >> 1);
     206             :         LC3_INT       j, r;
     207             : 
     208           0 :         trigstep = ((trigDataSize * 4) >> ldm) * trigdata_size / trigDataSize;
     209             : 
     210           0 :         for (j = 0; j < mh / 2; ++j) {
     211             :             LC3_FLOAT c1, c2;
     212             : 
     213           0 :             c2 = aTrigData[j * trigstep];
     214           0 :             c1 = aTrigData[trigdata_size - j * trigstep];
     215             : 
     216           0 :             for (r = 0; r < n; r += m) {
     217             :                 LC3_FLOAT vr, vi, ur, ui;
     218             : 
     219           0 :                 LC3_INT t0 = r + j;
     220           0 :                 LC3_INT t1 = s * t0;
     221           0 :                 LC3_INT t2 = s * (t0 + mh);
     222             : 
     223           0 :                 vr = re[t2] * c1 + im[t2] * c2;
     224           0 :                 vi = -re[t2] * c2 + im[t2] * c1;
     225             : 
     226           0 :                 ur = re[t1];
     227           0 :                 ui = im[t1];
     228             : 
     229           0 :                 re[t1] = re[t1] + vr;
     230           0 :                 im[t1] = im[t1] + vi;
     231             : 
     232           0 :                 re[t2] = ur - vr;
     233           0 :                 im[t2] = ui - vi;
     234             : 
     235           0 :                 t0 = r + j + mh / 2;
     236           0 :                 t1 = s * t0;
     237           0 :                 t2 = s * (t0 + mh);
     238             : 
     239           0 :                 vr = -re[t2] * c2 + im[t2] * c1;
     240           0 :                 vi = -re[t2] * c1 - im[t2] * c2;
     241             : 
     242           0 :                 ur     = re[t1];
     243           0 :                 ui     = im[t1];
     244           0 :                 re[t1] = re[t1] + vr;
     245           0 :                 im[t1] = im[t1] + vi;
     246             : 
     247           0 :                 re[t2] = ur - vr;
     248           0 :                 im[t2] = ui - vi;
     249             :             }
     250             :         }
     251             :     }
     252           0 : }
     253             : 
     254             : /**
     255             :  * \brief ifft
     256             :           The function performs a radix-2, decimation in time complex inverse fft. The calculation takes place
     257             :           inplace. The real and imaginary part can reside in separate buffers as well as interleaved in one buffer.
     258             :           The stride length has to be set accordingly.
     259             : 
     260             :  * \param[i/o] re:          real input / real output
     261             :  * \param[i/o] im:          imag input / imag output
     262             :  * \param[i  ] sizeOfFft:   size of fft
     263             :  * \param[i  ] s:           stride of real and imag input / output
     264             : 
     265             :  * \return none
     266             :  */
     267           0 : static void ifft(const LC3_FLOAT* aTrigData, LC3_INT trigdata_size, LC3_FLOAT* re, LC3_FLOAT* im, LC3_INT sizeOfFft,
     268             :                  LC3_INT s)
     269             : {
     270             :     LC3_INT trigstep, i, ldm, n;
     271             :     LC3_INT trigDataSize;
     272           0 :     LC3_INT ldn = 0;
     273             : 
     274           0 :     trigDataSize = sizeOfFft;
     275             : 
     276           0 :     while (sizeOfFft >>= 1) {
     277           0 :         ldn++;
     278             :     }
     279             : 
     280           0 :     n = 1 << ldn;
     281             : 
     282           0 :     scramble(re, im, n, s);
     283             : 
     284             :     /* 1+2 stage radix 4 */
     285           0 :     for (i = 0; i < n; i += 4) {
     286             :         LC3_FLOAT a00, a01, a10, a11;
     287             :         LC3_FLOAT a20, a21, a30, a31;
     288             : 
     289           0 :         a00 = re[s * (i + 0)] + re[s * (i + 1)];
     290           0 :         a10 = re[s * (i + 2)] + re[s * (i + 3)];
     291           0 :         a20 = im[s * (i + 0)] + im[s * (i + 1)];
     292           0 :         a30 = im[s * (i + 2)] + im[s * (i + 3)];
     293             : 
     294           0 :         a01 = re[s * (i + 0)] - re[s * (i + 1)];
     295           0 :         a21 = re[s * (i + 2)] - re[s * (i + 3)];
     296           0 :         a31 = im[s * (i + 0)] - im[s * (i + 1)];
     297           0 :         a11 = im[s * (i + 2)] - im[s * (i + 3)];
     298             : 
     299           0 :         re[s * (i + 0)] = a00 + a10;
     300           0 :         re[s * (i + 2)] = a00 - a10;
     301           0 :         im[s * (i + 0)] = a20 + a30;
     302           0 :         im[s * (i + 2)] = a20 - a30;
     303             : 
     304           0 :         re[s * (i + 1)] = a01 - a11;
     305           0 :         re[s * (i + 3)] = a01 + a11;
     306           0 :         im[s * (i + 1)] = a31 + a21;
     307           0 :         im[s * (i + 3)] = a31 - a21;
     308             :     }
     309             : 
     310           0 :     for (ldm = 3; ldm <= ldn; ++ldm) {
     311           0 :         const LC3_INT m  = (1 << ldm);
     312           0 :         const LC3_INT mh = (m >> 1);
     313             :         LC3_INT       j, r;
     314             : 
     315           0 :         trigstep = ((trigDataSize * 4) >> ldm) * trigdata_size / trigDataSize;
     316             : 
     317           0 :         for (j = 0; j < mh / 2; ++j) {
     318             :             LC3_FLOAT c1, c2;
     319             : 
     320           0 :             c2 = aTrigData[j * trigstep];
     321           0 :             c1 = aTrigData[trigdata_size - j * trigstep];
     322             : 
     323           0 :             for (r = 0; r < n; r += m) {
     324             :                 LC3_FLOAT vr, vi, ur, ui;
     325             : 
     326           0 :                 LC3_INT t0 = r + j;
     327           0 :                 LC3_INT t1 = s * t0;
     328           0 :                 LC3_INT t2 = s * (t0 + mh);
     329             : 
     330           0 :                 vr = re[t2] * c1 - im[t2] * c2;
     331           0 :                 vi = re[t2] * c2 + im[t2] * c1;
     332             : 
     333           0 :                 ur = re[t1];
     334           0 :                 ui = im[t1];
     335             : 
     336           0 :                 re[t1] = ur + vr;
     337           0 :                 im[t1] = ui + vi;
     338             : 
     339           0 :                 re[t2] = ur - vr;
     340           0 :                 im[t2] = ui - vi;
     341             : 
     342           0 :                 t0 = r + j + mh / 2;
     343           0 :                 t1 = s * t0;
     344           0 :                 t2 = s * (t0 + mh);
     345             : 
     346           0 :                 vr = -re[t2] * c2 - im[t2] * c1;
     347           0 :                 vi = re[t2] * c1 - im[t2] * c2;
     348             : 
     349           0 :                 ur = re[t1];
     350           0 :                 ui = im[t1];
     351             : 
     352           0 :                 re[t1] = ur + vr;
     353           0 :                 im[t1] = ui + vi;
     354           0 :                 re[t2] = ur - vr;
     355           0 :                 im[t2] = ui - vi;
     356             :             }
     357             :         }
     358             :     }
     359           0 : }
     360             : 
     361             : /**
     362             :  * \brief cfft
     363             :           The function serves as wrapper for the forward and inverse fft.
     364             : 
     365             :  * \param[i/o] re:          real input / real output
     366             :  * \param[i/o] im:          imag input / imag output
     367             :  * \param[i  ] sizeOfFft:   size of fft
     368             :  * \param[i  ] s:           stride of real and imag input / output
     369             :  * \param[i  ] iSign:       forward fft: -1 / inverse fft: 1
     370             : 
     371             :  * \return none
     372             :  */
     373           0 : void LC3_cfft(LC3_FLOAT* re, LC3_FLOAT* im, LC3_INT length, LC3_INT stride, LC3_INT sign)
     374             : {
     375           0 :     assert(abs(sign) == 1);
     376           0 :     assert(CFFT_SUPPORT(length));
     377             : 
     378           0 :     if (sign == -1) {
     379           0 :         fft(static_table, MAX_TRIGDATA_SIZE, re, im, length, stride);
     380             :     } else {
     381           0 :         ifft(static_table, MAX_TRIGDATA_SIZE, re, im, length, stride);
     382             :     }
     383           0 : }
     384             : 
     385           0 : LC3_INT LC3_cfft_plan(Cfft* handle, LC3_INT length, LC3_INT sign)
     386             : {
     387             :     /* check if length is power of two */
     388           0 :     if (!CFFT_PLAN_SUPPORT(length) || (abs(sign) != 1))
     389             :     {
     390           0 :         return 0;
     391             :     }
     392             : 
     393           0 :     handle->len  = length;
     394           0 :     handle->sign = sign;
     395             : 
     396           0 :     if (length <= MAX_FFT_SIZE) {
     397           0 :         handle->table = NULL;
     398             :     } else {
     399           0 :         LC3_INT i     = 0;
     400           0 :         handle->table = (LC3_FLOAT*)malloc((length / 2 + 1) * sizeof(LC3_FLOAT));
     401           0 :         for (i = 0; i < length / 2 + 1; i++) {
     402           0 :             handle->table[i] = (LC3_FLOAT)LC3_SIN((LC3_FLOAT)M_PIl * i / length);
     403             :         }
     404             :     }
     405           0 :     return 1;
     406             : }
     407             : 
     408           0 : void LC3_cfft_apply(Cfft* handle, LC3_FLOAT* re, LC3_FLOAT* im, LC3_INT stride)
     409             : {
     410           0 :     if (handle->len <= MAX_FFT_SIZE) {
     411           0 :         LC3_cfft(re, im, handle->len, stride, handle->sign);
     412           0 :     } else if (handle->sign == -1) {
     413           0 :         fft(handle->table, handle->len / 2, re, im, handle->len, stride);
     414             :     } else {
     415           0 :         ifft(handle->table, handle->len / 2, re, im, handle->len, stride);
     416             :     }
     417           0 : }
     418             : 
     419           0 : void LC3_cfft_free(Cfft* handle)
     420             : {
     421           0 :     if (handle->table)
     422             :     {
     423           0 :         free(handle->table);
     424             :     }
     425           0 : }

Generated by: LCOV version 1.14