LCOV - code coverage report
Current view: top level - lib_lc3plus - mdct.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 867217ee32c8e8cd2cf5aae69e60c58e00160b49 Lines: 55 125 44.0 %
Date: 2025-12-13 06:47:12 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             : *                        ETSI TS 103 634 V1.6.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 "functions.h"
      13             : 
      14        4398 : static const LC3_FLOAT* mdct_window(LC3_INT length, LC3PLUS_FrameDuration frame_dms, LC3_INT hrmode)
      15             : {
      16        4398 :     if (frame_dms == LC3PLUS_FRAME_DURATION_10MS) {
      17        2380 :         switch (length) {
      18           0 :         case 80:
      19           0 :             return MDCT_WINS_10ms[hrmode][0];
      20           4 :         case 160:
      21           4 :             return MDCT_WINS_10ms[hrmode][1];
      22           0 :         case 240:
      23           0 :             return MDCT_WINS_10ms[hrmode][2];
      24           4 :         case 320:
      25           4 :             return MDCT_WINS_10ms[hrmode][3];
      26        2372 :         case 480:
      27        2372 :             return MDCT_WINS_10ms[hrmode][4];
      28           0 :         case 960:
      29           0 :             return MDCT_WINS_10ms[hrmode][5];
      30           0 :         default:
      31           0 :             return NULL;
      32             :         }
      33             :     }
      34        2018 :     else if (frame_dms == LC3PLUS_FRAME_DURATION_7p5MS) {
      35           0 :         switch (length) {
      36           0 :         case 60:
      37           0 :             return MDCT_WINS_7_5ms[hrmode][0];
      38           0 :         case 120:
      39           0 :             return MDCT_WINS_7_5ms[hrmode][1];
      40           0 :         case 180:
      41           0 :             return MDCT_WINS_7_5ms[hrmode][2];
      42           0 :         case 240:
      43           0 :             return MDCT_WINS_7_5ms[hrmode][3];
      44           0 :         case 360:
      45           0 :             return MDCT_WINS_7_5ms[hrmode][4];
      46           0 :         case 720:
      47           0 :             return MDCT_WINS_7_5ms[hrmode][5];
      48           0 :         default:
      49           0 :             return NULL;
      50             :         }
      51             :     }
      52        2018 :     else if (frame_dms == LC3PLUS_FRAME_DURATION_5MS) {
      53        2016 :         switch (length) {
      54           0 :         case 40:
      55           0 :             return MDCT_WINS_5ms[hrmode][0];
      56           0 :         case 80:
      57           0 :             return MDCT_WINS_5ms[hrmode][1];
      58           0 :         case 120:
      59           0 :             return MDCT_WINS_5ms[hrmode][2];
      60           0 :         case 160:
      61           0 :             return MDCT_WINS_5ms[hrmode][3];
      62        2016 :         case 240:
      63        2016 :             return MDCT_WINS_5ms[hrmode][4];
      64           0 :         case 480:
      65           0 :             return MDCT_WINS_5ms[hrmode][5];
      66           0 :         default:
      67           0 :             return NULL;
      68             :         }
      69             :     }
      70           2 :     else if (frame_dms == LC3PLUS_FRAME_DURATION_2p5MS) {
      71           2 :         switch (length) {
      72           0 :         case 20:
      73           0 :             return MDCT_WINS_2_5ms[hrmode][0];
      74           0 :         case 40:
      75           0 :             return MDCT_WINS_2_5ms[hrmode][1];
      76           0 :         case 60:
      77           0 :             return MDCT_WINS_2_5ms[hrmode][2];
      78           0 :         case 80:
      79           0 :             return MDCT_WINS_2_5ms[hrmode][3];
      80           2 :         case 120:
      81           2 :             return MDCT_WINS_2_5ms[hrmode][4];
      82           0 :         case 240:
      83           0 :             return MDCT_WINS_2_5ms[hrmode][5];
      84           0 :         default:
      85           0 :             return NULL;
      86             :         }
      87             :     }
      88             : #ifdef CR9_C_ADD_1p25MS
      89           0 :     else if (frame_dms == LC3PLUS_FRAME_DURATION_1p25MS) {
      90           0 :         switch (length) {
      91           0 :         case 10:
      92           0 :             return MDCT_WINS_1_25ms[hrmode][0];
      93           0 :         case 20:
      94           0 :             return MDCT_WINS_1_25ms[hrmode][1];
      95           0 :         case 30:
      96           0 :             return MDCT_WINS_1_25ms[hrmode][2];
      97           0 :         case 40:
      98           0 :             return MDCT_WINS_1_25ms[hrmode][3];
      99           0 :         case 60:
     100           0 :             return MDCT_WINS_1_25ms[hrmode][4];
     101           0 :         default:
     102           0 :             return NULL;
     103             :         }
     104             :     }
     105             : #endif
     106           0 :     return NULL;
     107             : }
     108             : 
     109        4398 : void mdct_init(Mdct* mdct, LC3_INT length, LC3PLUS_FrameDuration frame_dms, LC3_INT fs_idx, LC3_INT hrmode)
     110             : {
     111        4398 :     switch (frame_dms)
     112             :     {
     113             : #ifdef CR9_C_ADD_1p25MS
     114           0 :       case LC3PLUS_FRAME_DURATION_1p25MS:
     115           0 :         mdct->leading_zeros = MDCT_la_zeroes_1_25ms[fs_idx];
     116           0 :         break;
     117             : #endif
     118           2 :       case LC3PLUS_FRAME_DURATION_2p5MS:
     119           2 :         mdct->leading_zeros = MDCT_la_zeroes_2_5ms[fs_idx];
     120           2 :         break;
     121        2016 :       case LC3PLUS_FRAME_DURATION_5MS:
     122        2016 :         mdct->leading_zeros = MDCT_la_zeroes_5ms[fs_idx];
     123        2016 :         break;
     124           0 :       case LC3PLUS_FRAME_DURATION_7p5MS:
     125           0 :         mdct->leading_zeros = MDCT_la_zeroes_7_5ms[fs_idx];
     126           0 :         break;
     127        2380 :       case LC3PLUS_FRAME_DURATION_10MS:
     128        2380 :         mdct->leading_zeros = MDCT_la_zeroes[fs_idx];
     129        2380 :         break;
     130           0 :       case LC3PLUS_FRAME_DURATION_UNDEFINED:
     131           0 :         assert(!"invalid frame_ms");
     132             :     }
     133             : 
     134        4398 :     mdct->length     = length;
     135        4398 :     mdct->mem_length = length - mdct->leading_zeros;
     136        4398 :     mdct->window     = mdct_window(length, frame_dms, hrmode);
     137        4398 :     mdct->mem        = calloc(mdct->mem_length, sizeof(*mdct->mem));
     138        4398 :     dct4_init(&mdct->dct, length);
     139        4398 : }
     140             : 
     141        4398 : void mdct_free(Mdct* mdct)
     142             : {
     143        4398 :     if (mdct) {
     144        4398 :         free(mdct->mem);
     145        4398 :         dct4_free(&mdct->dct);
     146        4398 :         memset(mdct, 0, sizeof(*mdct));
     147             :     }
     148        4398 : }
     149             : 
     150     1189311 : void mdct_apply(const LC3_FLOAT* input, LC3_FLOAT* output, Mdct* mdct)
     151             : {
     152             :     LC3_FLOAT tmp[MAX_LEN * 2];
     153             :     LC3_INT   i;
     154             :     LC3_INT hlen;
     155             : 
     156     1189311 :     move_float(tmp, mdct->mem, mdct->mem_length);
     157     1189311 :     move_float(tmp + mdct->mem_length, input, mdct->length);
     158     1189311 :     zero_float(tmp + mdct->length * 2 - mdct->leading_zeros, mdct->leading_zeros);
     159     1189311 :     move_float(mdct->mem, tmp + mdct->length, mdct->mem_length);
     160             : 
     161     1189311 :     mult_vec(tmp, mdct->window, mdct->length * 2);
     162             : 
     163     1189311 :     hlen = mdct->length / 2;
     164   149901351 :     for (i = 0; i < hlen; i++) {
     165   148712040 :         output[i]        = -tmp[hlen * 3 - i - 1] - tmp[hlen * 3 + i];
     166   148712040 :         output[hlen + i] = tmp[i] - tmp[hlen * 2 - i - 1];
     167             :     }
     168             : 
     169     1189311 :     move_float(tmp, output, mdct->length);
     170             : 
     171     1189311 :     dct4_apply(&mdct->dct, tmp, output);
     172     1189311 : }
     173             : 
     174     1189311 : void processMdct_fl(LC3_FLOAT* in, LC3_FLOAT* out, Mdct* mdctStruct) { mdct_apply(in, out, mdctStruct); }

Generated by: LCOV version 1.14