LCOV - code coverage report
Current view: top level - lib_com - basop_tcx_utils.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 207 224 92.4 %
Date: 2025-05-03 01:55:50 Functions: 3 3 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 <assert.h>
      38             : #include <stdint.h>
      39             : #include "options.h"
      40             : #include "cnst.h"
      41             : #include "basop_proto_func.h"
      42             : #include "stl.h"
      43             : #include "prot_fx.h"
      44             : #include "rom_com.h"
      45             : 
      46             : #define WMC_TOOL_SKIP
      47             : 
      48             : /* compare two positive normalized 16 bit mantissa/exponent values */
      49             : /* return value: positive if first value greater, negative if second value greater, zero if equal */
      50             : // static Word16 compMantExp16Unorm( Word16 m1, Word16 e1, Word16 m2, Word16 e2 )
      51             : //{
      52             : //     Word16 tmp;
      53             : //
      54             : //     assert( ( m1 >= 0x4000 ) && ( m2 >= 0x4000 ) ); /* comparisons below work only for normalized mantissas */
      55             : //
      56             : //     tmp = sub( e1, e2 );
      57             : //     if ( tmp == 0 )
      58             : //         tmp = sub( m1, m2 );
      59             : //
      60             : //     return tmp;
      61             : // }
      62             : 
      63      368068 : void basop_lpc2mdct_fx(
      64             :     Word16 *lpcCoeffs,  /* Q12 */
      65             :     Word16 lpcOrder,    /* Q0 */
      66             :     Word16 *mdct_gains, /* Q12 */
      67             :     Word16 *mdct_gains_exp,
      68             :     Word16 *mdct_inv_gains, /* Q12 */
      69             :     Word16 *mdct_inv_gains_exp )
      70             : {
      71             :     Word32 RealData[FDNS_NPTS];
      72             :     Word32 ImagData[FDNS_NPTS];
      73             :     Word16 i, j, k, step, scale, s, tmp16;
      74             :     Word16 g, g_e, ig, ig_e;
      75             :     Word32 tmp32;
      76             :     const PWord16 *ptwiddle;
      77             : 
      78             : 
      79             :     /* short-cut, to avoid calling of BASOP_getTables() */
      80      368068 :     ptwiddle = SineTable512_fx;
      81      368068 :     step = 8;
      82      368068 :     move16();
      83             :     /*ODFT*/
      84      368068 :     assert( lpcOrder < FDNS_NPTS );
      85             : 
      86             :     /* pre-twiddle */
      87     6639213 :     FOR( i = 0; i <= lpcOrder; i++ )
      88             :     {
      89     6271145 :         RealData[i] = L_mult( lpcCoeffs[i], ptwiddle->v.re ); /* Q28 */
      90     6271145 :         move32();
      91     6271145 :         ImagData[i] = L_negate( L_mult( lpcCoeffs[i], ptwiddle->v.im ) ); /* Q28 */
      92     6271145 :         move32();
      93     6271145 :         ptwiddle += step;
      94             :     }
      95             : 
      96             :     /* zero padding */
      97    17653275 :     FOR( ; i < FDNS_NPTS; i++ )
      98             :     {
      99    17285207 :         RealData[i] = 0;
     100    17285207 :         move32();
     101    17285207 :         ImagData[i] = 0;
     102    17285207 :         move32();
     103             :     }
     104             : 
     105             :     /* half length FFT */
     106      368068 :     scale = add( norm_s( lpcCoeffs[0] ), 1 );
     107      368068 :     move16();
     108      368068 :     BASOP_cfft_ivas( RealData, ImagData, 1, &scale ); /* sizeOfFft == FDNS_NPTS == 8 */
     109             : 
     110             : 
     111             :     /*Get amplitude*/
     112      368068 :     j = FDNS_NPTS - 1; /* Q0 */
     113      368068 :     k = 0;
     114      368068 :     move16();
     115      368068 :     move16();
     116             : 
     117    12146244 :     FOR( i = 0; i < FDNS_NPTS / 2; i++ )
     118             :     {
     119    11778176 :         s = sub( norm_l( L_max( L_abs( RealData[i] ), L_abs( ImagData[i] ) ) ), 1 );
     120             : 
     121    11778176 :         tmp16 = extract_h( L_shl( RealData[i], s ) );
     122    11778176 :         tmp32 = L_mult( tmp16, tmp16 );
     123             : 
     124    11778176 :         tmp16 = extract_h( L_shl( ImagData[i], s ) );
     125    11778176 :         tmp16 = mac_r( tmp32, tmp16, tmp16 );
     126             : 
     127    11778176 :         s = shl( sub( scale, s ), 1 );
     128             : 
     129    11778176 :         if ( tmp16 == 0 )
     130             :         {
     131           0 :             s = -16;
     132           0 :             move16();
     133             :         }
     134    11778176 :         if ( tmp16 == 0 )
     135             :         {
     136           0 :             tmp16 = 1;
     137           0 :             move16();
     138             :         }
     139             : 
     140    11778176 :         BASOP_Util_Sqrt_InvSqrt_MantExp( tmp16, s, &g, &g_e, &ig, &ig_e );
     141             : 
     142    11778176 :         if ( mdct_gains != NULL )
     143             :         {
     144    11330528 :             mdct_gains[k] = g; /* exp(g_e) */
     145    11330528 :             move16();
     146             :         }
     147             : 
     148    11778176 :         if ( mdct_gains_exp != NULL )
     149             :         {
     150    11330528 :             mdct_gains_exp[k] = g_e;
     151    11330528 :             move16();
     152             :         }
     153             : 
     154    11778176 :         if ( mdct_inv_gains != NULL )
     155             :         {
     156    11330528 :             mdct_inv_gains[k] = ig; /* exp(ig_e) */
     157    11330528 :             move16();
     158             :         }
     159             : 
     160    11778176 :         if ( mdct_inv_gains_exp != NULL )
     161             :         {
     162    11330528 :             mdct_inv_gains_exp[k] = ig_e;
     163    11330528 :             move16();
     164             :         }
     165             : 
     166    11778176 :         k++;
     167             : 
     168             : 
     169    11778176 :         s = sub( norm_l( L_max( L_abs( RealData[j] ), L_abs( ImagData[j] ) ) ), 1 );
     170             : 
     171    11778176 :         tmp16 = extract_h( L_shl( RealData[j], s ) );
     172    11778176 :         tmp32 = L_mult( tmp16, tmp16 );
     173             : 
     174    11778176 :         tmp16 = extract_h( L_shl( ImagData[j], s ) );
     175    11778176 :         tmp16 = mac_r( tmp32, tmp16, tmp16 );
     176             : 
     177    11778176 :         s = shl( sub( scale, s ), 1 );
     178             : 
     179    11778176 :         if ( tmp16 == 0 )
     180             :         {
     181           0 :             s = -16;
     182           0 :             move16();
     183             :         }
     184    11778176 :         if ( tmp16 == 0 )
     185             :         {
     186           0 :             tmp16 = 1;
     187           0 :             move16();
     188             :         }
     189             : 
     190    11778176 :         BASOP_Util_Sqrt_InvSqrt_MantExp( tmp16, s, &g, &g_e, &ig, &ig_e );
     191             : 
     192    11778176 :         if ( mdct_gains != NULL )
     193             :         {
     194    11330528 :             mdct_gains[k] = g; /* exp(g_e) */
     195    11330528 :             move16();
     196             :         }
     197             : 
     198    11778176 :         if ( mdct_gains_exp != NULL )
     199             :         {
     200    11330528 :             mdct_gains_exp[k] = g_e;
     201    11330528 :             move16();
     202             :         }
     203             : 
     204    11778176 :         if ( mdct_inv_gains != NULL )
     205             :         {
     206    11330528 :             mdct_inv_gains[k] = ig; /* exp(ig_e) */
     207    11330528 :             move16();
     208             :         }
     209             : 
     210    11778176 :         if ( mdct_inv_gains_exp != NULL )
     211             :         {
     212    11330528 :             mdct_inv_gains_exp[k] = ig_e;
     213    11330528 :             move16();
     214             :         }
     215             : 
     216    11778176 :         j--;
     217    11778176 :         k++;
     218             :     }
     219      368068 : }
     220             : 
     221             : 
     222       13989 : void basop_mdct_noiseShaping_interp_fx(
     223             :     Word32 x[],     /* Q16 */
     224             :     Word16 lg,      /* Q0 */
     225             :     Word16 gains[], /* exp(gain_exp) */
     226             :     Word16 gains_exp[] )
     227             : {
     228             :     Word16 i, j, jp, jn, k, l;
     229             :     Word16 g, pg, ng, e, tmp;
     230             : 
     231             : 
     232       13989 :     assert( lg % FDNS_NPTS == 0 );
     233       13989 :     k = shr( lg, 6 ); /* FDNS_NPTS = 64 */
     234             : 
     235       13989 :     IF( gains != NULL )
     236             :     {
     237             :         /* Linear interpolation */
     238       13989 :         IF( sub( k, 4 ) == 0 )
     239             :         {
     240       12695 :             jp = 0;
     241       12695 :             move16();
     242       12695 :             j = 0;
     243       12695 :             move16();
     244       12695 :             jn = 1;
     245       12695 :             move16();
     246             : 
     247      825175 :             FOR( i = 0; i < lg; i += 4 )
     248             :             {
     249      812480 :                 pg = gains[jp];
     250      812480 :                 move16();
     251      812480 :                 g = gains[j];
     252      812480 :                 move16();
     253      812480 :                 ng = gains[jn];
     254      812480 :                 move16();
     255             : 
     256             :                 /* common exponent for pg and g */
     257      812480 :                 tmp = sub( gains_exp[j], gains_exp[jp] );
     258      812480 :                 if ( tmp > 0 )
     259       89229 :                     pg = shr( pg, tmp );
     260      812480 :                 if ( tmp < 0 )
     261       53391 :                     g = shl( g, tmp );
     262      812480 :                 e = s_max( gains_exp[j], gains_exp[jp] );
     263             : 
     264      812480 :                 tmp = mac_r( L_mult( pg, 12288 /* 0.375 in Q15 */ ), g, 20480 /* 0.625 in Q15 */ ); /* exp(gains_exp) */
     265      812480 :                 x[i] = L_shl( Mpy_32_16_1( x[i], tmp ), e );                                        /* Q16 */
     266      812480 :                 move32();
     267             : 
     268      812480 :                 tmp = mac_r( L_mult( pg, 4096 /* 0.125 in Q15*/ ), g, 28672 /* 0.875 in Q15 */ ); /* exp(gains_exp) */
     269      812480 :                 x[i + 1] = L_shl( Mpy_32_16_1( x[i + 1], tmp ), e );                              /* Q16 */
     270      812480 :                 move32();
     271             : 
     272             :                 /* common exponent for g and ng */
     273      812480 :                 g = gains[j]; /* exp(gains_exp) */
     274      812480 :                 move16();
     275      812480 :                 tmp = sub( gains_exp[j], gains_exp[jn] );
     276      812480 :                 if ( tmp > 0 )
     277       53391 :                     ng = shr( ng, tmp );
     278      812480 :                 if ( tmp < 0 )
     279       89229 :                     g = shl( g, tmp );
     280      812480 :                 e = s_max( gains_exp[j], gains_exp[jn] );
     281             : 
     282      812480 :                 tmp = mac_r( L_mult( g, 28672 /* 0.875 in Q15 */ ), ng, 4096 /* 0.125 in Q15*/ ); /* exp(gains_exp) */
     283      812480 :                 x[i + 2] = L_shl( Mpy_32_16_1( x[i + 2], tmp ), e );                              /* Q16 */
     284      812480 :                 move32();
     285             : 
     286      812480 :                 tmp = mac_r( L_mult( g, 20480 /* 0.625 in Q15 */ ), ng, 12288 /* 0.375 in Q15 */ ); /* exp(gains_exp) */
     287      812480 :                 x[i + 3] = L_shl( Mpy_32_16_1( x[i + 3], tmp ), e );                                /* Q16 */
     288      812480 :                 move32();
     289             : 
     290      812480 :                 jp = j;
     291      812480 :                 move16();
     292      812480 :                 j = jn;
     293      812480 :                 move16();
     294      812480 :                 jn = s_min( add( jn, 1 ), FDNS_NPTS - 1 ); /* Q0 */
     295             :             }
     296             :         }
     297        1294 :         ELSE IF( sub( k, 5 ) == 0 )
     298             :         {
     299        1294 :             jp = 0;
     300        1294 :             move16();
     301        1294 :             j = 0;
     302        1294 :             move16();
     303        1294 :             jn = 1;
     304        1294 :             move16();
     305             : 
     306       84110 :             FOR( i = 0; i < lg; i += 5 )
     307             :             {
     308       82816 :                 pg = gains[jp];
     309       82816 :                 move16();
     310       82816 :                 g = gains[j];
     311       82816 :                 move16();
     312       82816 :                 ng = gains[jn];
     313       82816 :                 move16();
     314             : 
     315             :                 /* common exponent for pg and g */
     316       82816 :                 tmp = sub( gains_exp[j], gains_exp[jp] );
     317       82816 :                 if ( tmp > 0 )
     318        8768 :                     pg = shr( pg, tmp );
     319       82816 :                 if ( tmp < 0 )
     320        5135 :                     g = shl( g, tmp );
     321       82816 :                 e = s_max( gains_exp[j], gains_exp[jp] );
     322             : 
     323       82816 :                 tmp = mac_r( L_mult( pg, 13107 /* 0.4 in Q15 */ ), g, 19661 /* 0.6 in Q15 */ ); /* exp(gains_exp) */
     324       82816 :                 x[i] = L_shl( Mpy_32_16_1( x[i], tmp ), e );                                    /* Q16 */
     325       82816 :                 move32();
     326             : 
     327       82816 :                 tmp = mac_r( L_mult( pg, 6554 /* 0.2 in Q15 */ ), g, 26214 /* 0.8 in Q15 */ ); /* exp(gains_exp) */
     328       82816 :                 x[i + 1] = L_shl( Mpy_32_16_1( x[i + 1], tmp ), e );                           /* Q16 */
     329       82816 :                 move32();
     330             : 
     331             : 
     332       82816 :                 x[i + 2] = L_shl( Mpy_32_16_1( x[i + 2], gains[j] ), gains_exp[j] ); /* Q16 */
     333       82816 :                 move32();
     334             : 
     335             :                 /* common exponent for g and ng */
     336       82816 :                 g = gains[j];
     337       82816 :                 move16();
     338       82816 :                 tmp = sub( gains_exp[j], gains_exp[jn] );
     339       82816 :                 if ( tmp > 0 )
     340        5135 :                     ng = shr( ng, tmp );
     341       82816 :                 if ( tmp < 0 )
     342        8768 :                     g = shl( g, tmp );
     343       82816 :                 e = s_max( gains_exp[j], gains_exp[jn] );
     344             : 
     345       82816 :                 tmp = mac_r( L_mult( g, 26214 /* 0.8 in Q15 */ ), ng, 6554 /* 0.2 in Q15 */ ); /* exp(gains_exp) */
     346       82816 :                 x[i + 3] = L_shl( Mpy_32_16_1( x[i + 3], tmp ), e );                           /* Q16 */
     347       82816 :                 move32();
     348             : 
     349       82816 :                 tmp = mac_r( L_mult( g, 19661 /* 0.6 in Q15 */ ), ng, 13107 /* 0.4 in Q15 */ ); /* exp(gains_exp) */
     350       82816 :                 x[i + 4] = L_shl( Mpy_32_16_1( x[i + 4], tmp ), e );                            /* Q16 */
     351       82816 :                 move32();
     352             : 
     353       82816 :                 jp = j;
     354       82816 :                 move16();
     355       82816 :                 j = jn;
     356       82816 :                 move16();
     357       82816 :                 jn = s_min( add( jn, 1 ), FDNS_NPTS - 1 ); /* Q0 */
     358             :             }
     359             :         }
     360             :         ELSE /* no interpolation */
     361             :         {
     362           0 :             FOR( i = 0; i < FDNS_NPTS; i++ )
     363             :             {
     364           0 :                 FOR( l = 0; l < k; l++ )
     365             :                 {
     366           0 :                     *x = L_shl( Mpy_32_16_1( *x, *gains ), *gains_exp ); /* Q16 */
     367           0 :                     move32();
     368           0 :                     x++;
     369             :                 }
     370             : 
     371           0 :                 gains++;
     372           0 :                 gains_exp++;
     373             :             }
     374             :         }
     375             :     }
     376       13989 : }
     377             : 
     378             : 
     379       13989 : void basop_PsychAdaptLowFreqDeemph_fx(
     380             :     Word32 x[],              /* Q16 */
     381             :     const Word16 lpcGains[], /* exp(lpcGains_e) */
     382             :     const Word16 lpcGains_e[],
     383             :     Word16 lf_deemph_factors[] /* Qx */
     384             : )
     385             : {
     386             :     Word16 i;
     387             :     Word16 max_val, max_e, fac, min_val, min_e, tmp, tmp_e;
     388             :     Word32 L_tmp;
     389             : 
     390             : 
     391       13989 :     assert( lpcGains[0] >= 0x4000 );
     392             : 
     393       13989 :     max_val = lpcGains[0];
     394       13989 :     move16();
     395       13989 :     max_e = lpcGains_e[0];
     396       13989 :     move16();
     397       13989 :     min_val = lpcGains[0];
     398       13989 :     move16();
     399       13989 :     min_e = lpcGains_e[0];
     400       13989 :     move16();
     401             : 
     402             :     /* find minimum (min) and maximum (max) of LPC gains in low frequencies */
     403      125901 :     FOR( i = 1; i < 9; i++ )
     404             :     {
     405      111912 :         IF( compMantExp16Unorm( lpcGains[i], lpcGains_e[i], min_val, min_e ) < 0 )
     406             :         {
     407       79733 :             min_val = lpcGains[i];
     408       79733 :             move16();
     409       79733 :             min_e = lpcGains_e[i];
     410       79733 :             move16();
     411             :         }
     412             : 
     413      111912 :         IF( compMantExp16Unorm( lpcGains[i], lpcGains_e[i], max_val, max_e ) > 0 )
     414             :         {
     415       22577 :             max_val = lpcGains[i];
     416       22577 :             move16();
     417       22577 :             max_e = lpcGains_e[i];
     418       22577 :             move16();
     419             :         }
     420             :     }
     421             : 
     422       13989 :     min_e = add( min_e, 5 ); /* min *= 32.0f; */
     423             : 
     424       13989 :     test();
     425       13989 :     IF( ( compMantExp16Unorm( max_val, max_e, min_val, min_e ) < 0 ) && ( min_val > 0 ) )
     426             :     {
     427             :         /* fac = tmp = (float)pow(max / min, 0.0078125f); */
     428       13989 :         tmp_e = min_e;
     429       13989 :         move16();
     430       13989 :         tmp = Inv16( min_val, &tmp_e );
     431       13989 :         L_tmp = L_shl( L_mult( tmp, max_val ), add( tmp_e, max_e ) ); /* Q31 */
     432       13989 :         L_tmp = BASOP_Util_Log2( L_tmp );                             /* Q25 */
     433       13989 :         L_tmp = L_shr( L_tmp, 7 );                                    /* 0.0078125f = 1.f/(1<<7) */
     434       13989 :         L_tmp = BASOP_Util_InvLog2( L_tmp );                          /* Q31 */
     435       13989 :         tmp = round_fx( L_tmp );                                      /* Q15 */
     436       13989 :         fac = tmp;                                                    /* Q15 */
     437       13989 :         move16();
     438             : 
     439             :         /* gradual lowering of lowest 32 bins; DC is lowered by (max/tmp)^1/4 */
     440      461637 :         FOR( i = 31; i >= 0; i-- )
     441             :         {
     442      447648 :             x[i] = Mpy_32_16_1( x[i], fac ); /* Q16 */
     443      447648 :             move32();
     444      447648 :             if ( lf_deemph_factors != NULL )
     445             :             {
     446           0 :                 lf_deemph_factors[i] = mult_r( lf_deemph_factors[i], fac ); /* Qx */
     447           0 :                 move16();
     448             :             }
     449      447648 :             fac = mult_r( fac, tmp ); /* Q15 */
     450             :         }
     451             :     }
     452       13989 : }
     453             : 
     454             : #undef WMC_TOOL_SKIP

Generated by: LCOV version 1.14