LCOV - code coverage report
Current view: top level - lib_lc3plus/fft - iis_fft.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 0 66 0.0 %
Date: 2025-05-23 08:37:30 Functions: 0 10 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 <assert.h>
      13             : #include <stddef.h>
      14             : #include <stdio.h>
      15             : #include <stdlib.h>
      16             : #include <string.h>
      17             : #include <math.h>
      18             : #include "iis_fft.h"
      19             : 
      20             : /**************************************************************************************************/
      21             : 
      22             : /* AFFT uses two fft implementations
      23             :  * cfft is used for lengths of power of two, >= 256.
      24             :  * iisfft is used for everything else. it is optimized for certain lengths. for a list of
      25             :    fast lengths, check the fft_n function.
      26             : */
      27             : 
      28             : #define FFT_COMPLEX 1
      29             : #define FFT_REAL 2
      30             : 
      31             : 
      32           0 : static IIS_FFT_ERROR create(HANDLE_IIS_FFT* handle, LC3_INT type, LC3_INT len, IIS_FFT_DIR sign)
      33             : {
      34           0 :     IIS_FFT_ERROR  err = IIS_FFT_MEMORY_ERROR;
      35             : 
      36             :     /* for real transforms the actual performed fft is half length */
      37           0 :     LC3_INT trlen = (type == FFT_COMPLEX) ? len : len / 2;
      38             : 
      39             :     /* check argument sanity */
      40           0 :     if ((sign != IIS_FFT_FWD) && (sign != IIS_FFT_BWD))
      41             :     {
      42           0 :         return IIS_FFT_INTERNAL_ERROR;
      43             :     }
      44             : 
      45             : 
      46           0 :     if (!(*handle))
      47             :     {
      48           0 :       (*handle) = (HANDLE_IIS_FFT)calloc(1, sizeof(IIS_FFT));
      49             :     }
      50           0 :     if (!(*handle))
      51             :     {
      52           0 :         return IIS_FFT_MEMORY_ERROR;
      53             :     }
      54             : 
      55           0 :     (*handle)->len  = len;
      56           0 :     (*handle)->sign = sign;
      57             : 
      58             :     /* create sine lookup table for real ffts */
      59           0 :     if (type == FFT_REAL)
      60             :     {
      61           0 :         LC3_create_sine_table(len, (*handle)->sine_table);
      62           0 :         if (!(*handle)->sine_table)
      63             :         {
      64           0 :            goto handle_error1;
      65             :         }
      66             :     }
      67             : 
      68             :     /*  set default cfft_plan to 0(length). (and default iisfft_plan to zero length)  */
      69           0 :     (*handle)->cfft.len = 0;  /* 0 length means that cfft should not be  called */
      70           0 :     (*handle)->iisfft.length = 0; /*saftey setting for  iisfft length struct */
      71             : 
      72             :     /* use cfft for legth of power two larger than 256. for length below iisfft is faster */
      73           0 :     if (trlen >= 256 && CFFT_PLAN_SUPPORT(trlen)) {
      74           0 :         LC3_INT s = (type == FFT_REAL) ? IIS_FFT_FWD : sign;
      75           0 :         err       = LC3_cfft_plan(&(*handle)->cfft, trlen, s) ? IIS_FFT_NO_ERROR : IIS_FFT_INTERNAL_ERROR;
      76             :     } else {
      77           0 :         LC3_INT s = (type == FFT_REAL) ? IIS_FFT_FWD : sign;
      78           0 :         err       = LC3_iisfft_plan(&(*handle)->iisfft, trlen, s);
      79             :     }
      80             : 
      81           0 :     return IIS_FFT_NO_ERROR;
      82             : 
      83           0 : handle_error1:
      84           0 :     free((*handle));
      85             : 
      86           0 :     return err;
      87             : }
      88             : 
      89           0 : IIS_FFT_ERROR LC3_IIS_RFFT_Create(HANDLE_IIS_FFT* handle, LC3_INT32 len, IIS_FFT_DIR sign)
      90             : {
      91           0 :     return create(handle, FFT_REAL, len, sign);
      92             : }
      93             : 
      94           0 : static IIS_FFT_ERROR destroy(HANDLE_IIS_FFT* handle)
      95             : {
      96           0 :     if (handle && *handle) {
      97           0 :         LC3_iisfft_free(&(*handle)->iisfft);
      98           0 :         LC3_cfft_free(&(*handle)->cfft);
      99           0 :         free(*handle);
     100           0 :         *handle = NULL;
     101             :     }
     102           0 :     return IIS_FFT_NO_ERROR;
     103             : }
     104             : 
     105           0 : IIS_FFT_ERROR LC3_IIS_CFFT_Create(HANDLE_IIS_FFT* handle, LC3_INT len, IIS_FFT_DIR sign)
     106             : {
     107           0 :     return create(handle, FFT_COMPLEX, len, sign);
     108             : }
     109             : 
     110             : 
     111           0 : IIS_FFT_ERROR LC3_IIS_xFFT_Destroy(HANDLE_IIS_FFT* handle) { return destroy(handle); }
     112             : 
     113           0 : IIS_FFT_ERROR LC3_IIS_CFFT_Destroy(HANDLE_IIS_FFT* handle) { return destroy(handle); }
     114             : 
     115           0 : static IIS_FFT_ERROR real_destroy(HANDLE_IIS_FFT* handle)
     116             : {
     117           0 :     if (handle && *handle) {
     118           0 :         LC3_iisfft_free(&(*handle)->iisfft);
     119           0 :         *handle = NULL;
     120             :     }
     121           0 :     return IIS_FFT_NO_ERROR;
     122             : }
     123             : 
     124           0 : IIS_FFT_ERROR LC3_IIS_RFFT_Destroy(HANDLE_IIS_FFT* handle) { return real_destroy(handle); }
     125             : 
     126           0 : IIS_FFT_ERROR LC3_IIS_FFT_Apply_CFFT(HANDLE_IIS_FFT handle, const Complex* input, Complex* output)
     127             : {
     128             :     LC3_FLOAT* dummy;
     129           0 :     if (!handle)
     130             :     {
     131           0 :         return IIS_FFT_INTERNAL_ERROR;
     132             :     }
     133             : 
     134             :     /* check for inplace operation */
     135           0 :     memmove(output, input, sizeof(*input) * handle->len);
     136           0 :     dummy = (LC3_FLOAT*)output;
     137           0 :     if (handle->cfft.len > 0) {
     138           0 :         LC3_cfft_apply(&handle->cfft, dummy, dummy + 1, 2);
     139             :     } else {
     140           0 :         LC3_iisfft_apply(&handle->iisfft, dummy);
     141             :     }
     142             : 
     143           0 :     return IIS_FFT_NO_ERROR;
     144             : }
     145             : 
     146             : 
     147           0 : IIS_FFT_ERROR LC3_IIS_FFT_Apply_RFFT(HANDLE_IIS_FFT handle, const LC3_FLOAT* in, LC3_FLOAT* out)
     148             : {
     149           0 :    if (!handle) {
     150           0 :       return IIS_FFT_INTERNAL_ERROR;
     151             :    }
     152             : 
     153           0 :    memmove(out, in, sizeof(LC3_FLOAT) * handle->len);
     154             : 
     155           0 :    if (handle->sign == IIS_FFT_BWD) {
     156           0 :       LC3_rfft_pre(handle->sine_table, out, handle->len);
     157             :    }
     158             : 
     159           0 :    if (handle->cfft.len > 0) {
     160           0 :       LC3_cfft_apply(&handle->cfft, out, out + 1, 2);
     161             :    }
     162             :    else {
     163           0 :       LC3_iisfft_apply(&handle->iisfft, out);
     164             :    }
     165             : 
     166           0 :    if (handle->sign == IIS_FFT_FWD) {
     167           0 :       LC3_rfft_post(handle->sine_table, out, handle->len);
     168             :    }
     169             : 
     170           0 :    return IIS_FFT_NO_ERROR;
     171             : }

Generated by: LCOV version 1.14