LCOV - code coverage report
Current view: top level - lib_com - edct.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 142 166 85.5 %
Date: 2025-05-23 08:37:30 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : /*====================================================================================
      34             :     EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
      35             :   ====================================================================================*/
      36             : 
      37             : #include <stdint.h>
      38             : #include "options.h"
      39             : #ifdef DEBUGGING
      40             : #include "debug.h"
      41             : #endif
      42             : #include "cnst.h"
      43             : #include "rom_com.h"
      44             : #include "prot.h"
      45             : #include "wmc_auto.h"
      46             : #include <math.h> /* for cosf, sinf */
      47             : 
      48     8908545 : static ivas_error get_edct_table(
      49             :     const float **edct_table,
      50             :     const int16_t length )
      51             : {
      52             :     ivas_error error;
      53             : 
      54     8908545 :     error = IVAS_ERR_OK;
      55     8908545 :     *edct_table = NULL;
      56             : 
      57     8908545 :     switch ( length )
      58             :     {
      59       36266 :         case 1200:
      60       36266 :             *edct_table = edct_table_600;
      61       36266 :             break;
      62     3220224 :         case 960:
      63     3220224 :             *edct_table = edct_table_480;
      64     3220224 :             break;
      65     2295580 :         case 640:
      66     2295580 :             *edct_table = edct_table_320;
      67     2295580 :             break;
      68     1209618 :         case 320:
      69     1209618 :             *edct_table = edct_table_160;
      70     1209618 :             break;
      71      913574 :         case 256:
      72      913574 :             *edct_table = edct_table_128;
      73      913574 :             break;
      74      123380 :         case 240:
      75      123380 :             *edct_table = edct_table_120;
      76      123380 :             break;
      77           0 :         case 200:
      78           0 :             *edct_table = edct_table_100;
      79           0 :             break;
      80      174639 :         case 160:
      81      174639 :             *edct_table = edct_table_80;
      82      174639 :             break;
      83           0 :         case 40:
      84           0 :             *edct_table = edct_table_20;
      85           0 :             break;
      86       10862 :         case 800:
      87       10862 :             *edct_table = edct_table_400;
      88       10862 :             break;
      89      761088 :         case 512:
      90      761088 :             *edct_table = edct_table_256;
      91      761088 :             break;
      92       53362 :         case 480:
      93       53362 :             *edct_table = edct_table_240;
      94       53362 :             break;
      95       35591 :         case 400:
      96       35591 :             *edct_table = edct_table_200;
      97       35591 :             break;
      98       44391 :         case 128:
      99       44391 :             *edct_table = edct_table_64;
     100       44391 :             break;
     101       29970 :         case 80:
     102       29970 :             *edct_table = edct_table_40;
     103       29970 :             break;
     104             : #ifdef DEBUGGING
     105             :         default:
     106             :             return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "edct/edst(): length is not in table!" );
     107             : #endif
     108             :     }
     109             : 
     110     8908545 :     return error;
     111             : }
     112             : 
     113             : 
     114             : /*-----------------------------------------------------------------*
     115             :  * edct()
     116             :  *
     117             :  * DCT-IV transform
     118             :  *-----------------------------------------------------------------*/
     119             : 
     120     7990964 : void edct(
     121             :     const float *x,            /* i  : input signal        */
     122             :     float *y,                  /* o  : output transform    */
     123             :     const int16_t length,      /* i  : length              */
     124             :     const int16_t element_mode /* i  : IVAS element mode   */
     125             : )
     126             : {
     127             :     int16_t i;
     128             :     float re[L_FRAME_PLUS / 2];
     129             :     float im[L_FRAME_PLUS / 2];
     130     7990964 :     const float *edct_table = 0;
     131             :     float local;
     132             : 
     133     7990964 :     get_edct_table( &edct_table, length );
     134             : 
     135             :     /* Twiddling and Pre-rotate */
     136  2489915508 :     for ( i = 0; i < length / 2; i++ )
     137             :     {
     138  2481924544 :         re[i] = x[2 * i] * edct_table[i] + x[length - 1 - 2 * i] * edct_table[length / 2 - 1 - i];
     139  2481924544 :         im[i] = x[length - 1 - 2 * i] * edct_table[i] - x[2 * i] * edct_table[length / 2 - 1 - i];
     140             :     }
     141             : 
     142     7990964 :     if ( element_mode == EVS_MONO )
     143             :     {
     144       89349 :         DoFFT( re, im, length / 2 );
     145             :     }
     146             :     else
     147             :     {
     148     7901615 :         fft( re, im, length / 2, 1 );
     149             :     }
     150             : 
     151     7990964 :     local = ( 0.75f * EVS_PI ) / length;
     152             : 
     153  2489915508 :     for ( i = 0; i < length / 2; i++ )
     154             :     {
     155             :         float tmp;
     156  2481924544 :         tmp = re[i] - im[i] * local; /* 3*pi/(4*length) is a constant */
     157  2481924544 :         im[i] = im[i] + re[i] * local;
     158  2481924544 :         re[i] = tmp;
     159             :     }
     160             : 
     161             :     /* Post-rotate and obtain the output data */
     162  2489915508 :     for ( i = 0; i < length / 2; i++ )
     163             :     {
     164  2481924544 :         y[2 * i] = re[i] * edct_table[i] + im[i] * edct_table[length / 2 - 1 - i];
     165  2481924544 :         y[length - 1 - 2 * i] = re[i] * edct_table[length / 2 - 1 - i] - im[i] * edct_table[i];
     166             :     }
     167             : 
     168     7990964 :     return;
     169             : }
     170             : 
     171             : 
     172             : /*-------------------------------------------------------------------------*
     173             :  * edst()
     174             :  *
     175             :  * DST-IV transform
     176             :  *-------------------------------------------------------------------------*/
     177             : 
     178      917581 : void edst(
     179             :     const float *x,            /* i  : input signal        */
     180             :     float *y,                  /* o  : output transform    */
     181             :     const int16_t length,      /* i  : length              */
     182             :     const int16_t element_mode /* i  : IVAS element mode   */
     183             : )
     184             : {
     185             :     int16_t i;
     186             :     float re[L_FRAME_PLUS / 2];
     187             :     float im[L_FRAME_PLUS / 2];
     188      917581 :     const float *edct_table = 0;
     189             :     float local;
     190             : 
     191      917581 :     get_edct_table( &edct_table, length );
     192             : 
     193             :     /* Twiddling and Pre-rotate */
     194   383447061 :     for ( i = 0; i < length / 2; i++ )
     195             :     {
     196   382529480 :         re[i] = x[length - 1 - 2 * i] * edct_table[i] + x[2 * i] * edct_table[length / 2 - 1 - i];
     197   382529480 :         im[i] = x[2 * i] * edct_table[i] - x[length - 1 - 2 * i] * edct_table[length / 2 - 1 - i];
     198             :     }
     199             : 
     200      917581 :     if ( element_mode == EVS_MONO )
     201             :     {
     202        6577 :         DoFFT( re, im, length / 2 );
     203             :     }
     204             :     else
     205             :     {
     206      911004 :         fft( re, im, length / 2, 1 );
     207             :     }
     208             : 
     209      917581 :     local = ( 0.75f * EVS_PI ) / length;
     210             : 
     211   383447061 :     for ( i = 0; i < length / 2; i++ )
     212             :     {
     213             :         float tmp;
     214   382529480 :         tmp = re[i] - im[i] * local; /* 3*pi/(4*length) is a constant */
     215   382529480 :         im[i] = im[i] + re[i] * local;
     216   382529480 :         re[i] = tmp;
     217             :     }
     218             : 
     219             :     /* Post-rotate and obtain the output data */
     220   383447061 :     for ( i = 0; i < length / 2; i++ )
     221             :     {
     222   382529480 :         y[2 * i] = re[i] * edct_table[i] + im[i] * edct_table[length / 2 - 1 - i];
     223   382529480 :         y[length - 1 - 2 * i] = im[i] * edct_table[i] - re[i] * edct_table[length / 2 - 1 - i];
     224             :     }
     225             : 
     226      917581 :     return;
     227             : }
     228             : 
     229             : #define FAST_EDXT /* optimized FFT-based DCT/DST algorithm */
     230             : 
     231             : /*-------------------------------------------------------------------------*
     232             :  * edxt()
     233             :  *
     234             :  * DCT/DST-II or III transform (currently also calculates DCT-IV and DST-IV)
     235             :  *-------------------------------------------------------------------------*/
     236             : 
     237        3670 : void edxt(
     238             :     const float *x,            /* i  : input signal        */
     239             :     float *y,                  /* o  : output transform    */
     240             :     const int16_t length,      /* i  : length              */
     241             :     const uint16_t kernelType, /* i  : kernel type (0 - 3) */
     242             :     const uint16_t synthesis   /* i  : nonzero for inverse */
     243             : )
     244             : {
     245        3670 :     const float pi_len = EVS_PI / length;
     246             :     int16_t k, m;
     247             : 
     248             : #ifdef FAST_EDXT
     249        3670 :     if ( kernelType == MDST_II || kernelType == MDCT_II )
     250        3670 :     {
     251        3670 :         const int16_t Nm1 = length - 1;
     252        3670 :         const float xSign = 2.f * ( kernelType >> 1 ) - 1.f;
     253        3670 :         const float scale = 0.5f * pi_len;
     254             :         float re[L_FRAME_PLUS];
     255             :         float im[L_FRAME_PLUS];
     256             : 
     257        3670 :         if ( !synthesis )
     258             :         {
     259      148366 :             for ( k = Nm1 >> 1; k >= 0; k-- ) /* pre-modulation of audio input */
     260             :             {
     261      147840 :                 re[k] = x[2 * k];
     262      147840 :                 re[Nm1 - k] = x[2 * k + 1] * xSign;
     263      147840 :                 im[k] = im[Nm1 - k] = 0.f;
     264             :             }
     265             : 
     266         526 :             if ( length == 512 )
     267             :             {
     268           0 :                 DoRTFTn( re, im, 512 );
     269             :             }
     270             :             else /* fft() doesn't support 512 */
     271             :             {
     272         526 :                 fft( re, im, length, 1 );
     273             :             }
     274             : 
     275         526 :             if ( kernelType >> 1 )
     276             :             {
     277       72400 :                 for ( k = Nm1 >> 1; k > 0; k-- )
     278             :                 {
     279       72138 :                     const float wRe = cosf( scale * k );
     280       72138 :                     const float wIm = sinf( scale * k );
     281             : 
     282       72138 :                     y[k] /*pt 1*/ = wRe * re[k] + wIm * im[k];
     283       72138 :                     y[length - k] = wIm * re[k] - wRe * im[k];
     284             :                 }
     285         262 :                 y[length >> 1] = re[length >> 1] * sqrtf( 0.5f );
     286             :             }
     287             :             else /* forw. DST-II */
     288             :             {
     289       75440 :                 for ( k = Nm1 >> 1; k > 0; k-- )
     290             :                 {
     291       75176 :                     const float wRe = cosf( scale * k );
     292       75176 :                     const float wIm = sinf( scale * k );
     293             : 
     294       75176 :                     y[Nm1 - k] = wRe * re[k] + wIm * im[k];
     295       75176 :                     y[k - 1] = wIm * re[k] - wRe * im[k];
     296             :                 }
     297         264 :                 y[Nm1 >> 1] = re[length >> 1] * sqrtf( 0.5f );
     298             :             }
     299             : 
     300         526 :             y[Nm1 - Nm1 * ( kernelType >> 1 )] = re[0] * 0.5f;
     301             :         }
     302             :         else /* inverse II = III */
     303             :         {
     304        3144 :             if ( kernelType >> 1 )
     305             :             {
     306      365664 :                 for ( k = Nm1 >> 1; k > 0; k-- )
     307             :                 {
     308      364110 :                     const float wRe = cosf( scale * k ) * 0.5f;
     309      364110 :                     const float wIm = sinf( scale * k ) * 0.5f;
     310             : 
     311      364110 :                     re[k] = wRe * x[k] + wIm * x[length - k];
     312      364110 :                     im[k] = wRe * x[length - k] - wIm * x[k];
     313             :                 }
     314        1554 :                 re[length >> 1] = x[length >> 1] * sqrtf( 0.5f );
     315             :             }
     316             :             else /* DST type III */
     317             :             {
     318      390768 :                 for ( k = Nm1 >> 1; k > 0; k-- )
     319             :                 {
     320      389178 :                     const float wRe = cosf( scale * k ) * 0.5f;
     321      389178 :                     const float wIm = sinf( scale * k ) * 0.5f;
     322             : 
     323      389178 :                     re[k] = wRe * x[Nm1 - k] + wIm * x[k - 1];
     324      389178 :                     im[k] = wRe * x[k - 1] - wIm * x[Nm1 - k];
     325             :                 }
     326        1590 :                 re[length >> 1] = x[Nm1 >> 1] * sqrtf( 0.5f );
     327             :             }
     328             : 
     329        3144 :             re[0] = x[Nm1 - Nm1 * ( kernelType >> 1 )];
     330        3144 :             im[0] = im[length >> 1] = 0.f;
     331      756432 :             for ( k = Nm1 >> 1; k > 0; k-- )
     332             :             {
     333      753288 :                 re[length - k] = re[k];
     334      753288 :                 im[length - k] = -im[k];
     335             :             }
     336             : 
     337        3144 :             if ( length == 512 )
     338             :             {
     339         798 :                 DoRTFTn( re, im, 512 );
     340             :             }
     341             :             else /* fft() doesn't support 512 */
     342             :             {
     343        2346 :                 fft( re, im, length, 1 );
     344             :             }
     345             : 
     346      759576 :             for ( k = Nm1 >> 1; k >= 0; k-- ) /* post-modulation of FFT output */
     347             :             {
     348      756432 :                 y[2 * k] = re[k];
     349      756432 :                 y[2 * k + 1] = re[Nm1 - k] * xSign;
     350             :             }
     351             :         }
     352             :     }
     353             :     else
     354             : #endif
     355           0 :         if ( kernelType & 1 ) /* DST */
     356             :     {
     357           0 :         const float offK = ( kernelType == MDST_II && synthesis ? 0.5f : 1.0f - 0.5f * ( kernelType >> 1 ) );
     358           0 :         const float offM = ( kernelType == MDST_II && synthesis ? 1.0f : 0.5f );
     359             : 
     360           0 :         for ( k = 0; k < length; k++ )
     361             :         {
     362           0 :             y[k] = 0.f;
     363           0 :             for ( m = 0; m < length; m++ )
     364             :             {
     365           0 :                 y[k] += x[m] * sinf( pi_len * ( m + offM ) * ( k + offK ) );
     366             :             }
     367             :         }
     368           0 :         if ( offK == 1.f )
     369             :         {
     370           0 :             y[length - 1] *= 0.5f; /* scale Nyquist sample */
     371             :         }
     372             :     }
     373             :     else /* kernelType 0, 2: DCT */
     374             :     {
     375           0 :         const float offK = ( kernelType == MDCT_II && synthesis ? 0.5f : 0.5f - 0.5f * ( kernelType >> 1 ) );
     376           0 :         const float offM = ( kernelType == MDCT_II && synthesis ? 0.0f : 0.5f );
     377             : 
     378           0 :         for ( k = 0; k < length; k++ )
     379             :         {
     380           0 :             y[k] = 0.f;
     381           0 :             for ( m = 0; m < length; m++ )
     382             :             {
     383           0 :                 y[k] += x[m] * cosf( pi_len * ( m + offM ) * ( k + offK ) );
     384             :             }
     385             :         }
     386           0 :         if ( offK == 0.f )
     387             :         {
     388           0 :             y[0] *= 0.5f; /* scale lowest (i.e. DC) sample */
     389             :         }
     390             :     }
     391             : 
     392        3670 :     v_multc( y, ( kernelType == MDCT_II ? -1.f : 1.f ) * sqrtf( 2.f / length ), y, length );
     393             : 
     394        3670 :     return;
     395             : }
     396             : 
     397             : /*-----------------------------------------------------------------*
     398             :  * iedct_short()
     399             :  *
     400             :  * Inverse EDCT for short frames
     401             :  *-----------------------------------------------------------------*/
     402             : 
     403       15580 : void iedct_short(
     404             :     const float *in,              /* i  : input vector          */
     405             :     float *out,                   /* o  : output vector         */
     406             :     const int16_t segment_length, /* i  : length                */
     407             :     const int16_t element_mode    /* i  : IVAS element mode     */
     408             : )
     409             : {
     410             :     float alias[MAX_SEGMENT_LENGTH];
     411             :     int16_t i;
     412             : 
     413       15580 :     edct( in, alias, segment_length / 2, element_mode );
     414             : 
     415     1158620 :     for ( i = 0; i < segment_length / 4; i++ )
     416             :     {
     417     1143040 :         out[i] = alias[segment_length / 4 + i];
     418     1143040 :         out[segment_length / 4 + i] = -alias[segment_length / 2 - 1 - i];
     419     1143040 :         out[segment_length / 2 + i] = -alias[segment_length / 4 - 1 - i];
     420     1143040 :         out[3 * segment_length / 4 + i] = -alias[i];
     421             :     }
     422             : 
     423       15580 :     return;
     424             : }

Generated by: LCOV version 1.14