LCOV - code coverage report
Current view: top level - lib_com - logqnorm_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 131 141 92.9 %
Date: 2025-05-03 01:55:50 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             : #include <stdint.h>
      34             : #include "options.h" /* Compilation switches                   */
      35             : #include "prot_fx.h" /* Function prototypes                    */
      36             : #include "rom_com.h" /* Static table prototypes                */
      37             : #include "cnst.h"    /* Common constants                       */
      38             : #include <math.h>
      39             : /*--------------------------------------------------------------------------*
      40             :  * Local constants
      41             :  *--------------------------------------------------------------------------*/
      42             : 
      43             : #define THREN2POW 1518500250L
      44             : 
      45             : /*--------------------------------------------------------------------------*
      46             :  * logqnorm_fx
      47             :  *
      48             :  * Log quantization for norms of sub-vectors
      49             :  *--------------------------------------------------------------------------*/
      50      257249 : void logqnorm_ivas_fx(
      51             :     const Word32 *x_fx,    /* i  : coefficient vector Qq*/
      52             :     const Word16 q,        /* i  : q of coefficient vector */
      53             :     Word16 *k_fx,          /* o  : index (Q0)*/
      54             :     const Word16 L,        /* i  : codebook length */
      55             :     const Word16 N,        /* i  : sub-vector size */
      56             :     const Word32 *thre_fxn /* i  : quantization thresholds Q14*/
      57             : )
      58             : {
      59             :     Word16 i, j, j1, j2;
      60             :     Word64 temp_fx;
      61             :     Word32 temp32_fx;
      62             :     Word32 power_fx;
      63             :     Word64 thren0_sqr, threnL2_sqr;
      64             :     Word32 thren0_sqr32, threnL2_sqr32;
      65             :     Word16 thren0_sqr32_e, threnL2_sqr32_e;
      66      257249 :     temp_fx = 0;
      67      257249 :     move64();
      68             :     Word32 result1, result2;
      69             :     Word16 result1_e, result2_e;
      70      257249 :     Word16 gd_bits = find_guarded_bits_fx( N );
      71     4599815 :     FOR( i = 0; i < N; i++ )
      72             :     {
      73     4342566 :         temp_fx = W_add( W_shr( W_mult0_32_32( x_fx[i], x_fx[i] ), gd_bits ), temp_fx ); // 2*qin-gd_bits
      74             :     }
      75      257249 :     Word16 l_shift = W_norm( temp_fx );
      76      257249 :     temp32_fx = W_extract_h( W_shl( temp_fx, l_shift ) ); // 2*qin-gd_bits + l_shift -32
      77      257249 :     Word16 temp_e = sub( 31, ( sub( add( sub( shl( q, 1 ), gd_bits ), l_shift ), 32 ) ) );
      78             :     /* sqrt will be done later */
      79             :     // temp *= inv_tbl[N];
      80      257249 :     temp32_fx = Mpy_32_16_1( temp32_fx, inv_tbl_fx[N] );             // temp_e
      81      257249 :     thren0_sqr = W_mult0_32_32( thre_fxn[0], thre_fxn[0] );          // Q28
      82      257249 :     threnL2_sqr = W_mult0_32_32( thre_fxn[L - 2], thre_fxn[L - 2] ); // Q28
      83      257249 :     l_shift = W_norm( thren0_sqr );
      84      257249 :     thren0_sqr32 = W_extract_h( W_shl( thren0_sqr, l_shift ) ); // Q28 + l_shift - 32
      85      257249 :     thren0_sqr32_e = sub( 31, sub( add( Q28, l_shift ), 32 ) );
      86      257249 :     l_shift = W_norm( threnL2_sqr );
      87      257249 :     threnL2_sqr32 = W_extract_h( W_shl( threnL2_sqr, l_shift ) ); // Q28 + l_shift - 32
      88      257249 :     threnL2_sqr32_e = sub( 31, sub( add( Q28, l_shift ), 32 ) );
      89      257249 :     result1 = BASOP_Util_Add_Mant32Exp( thren0_sqr32, thren0_sqr32_e, L_negate( temp32_fx ), temp_e, &result1_e );
      90      257249 :     result2 = BASOP_Util_Add_Mant32Exp( threnL2_sqr32, threnL2_sqr32_e, L_negate( temp32_fx ), temp_e, &result2_e );
      91             : 
      92      257249 :     IF( result1 <= 0 )
      93             :     {
      94           0 :         *k_fx = 0;
      95           0 :         move16();
      96             :     }
      97      257249 :     ELSE IF( result2 > 0 )
      98             :     {
      99        1164 :         *k_fx = sub( L, 1 );
     100        1164 :         move16();
     101             :     }
     102             :     ELSE
     103             :     {
     104      256085 :         Word16 e = 0;
     105      256085 :         move16();
     106      256085 :         power_fx = Sqrt32( ONE_IN_Q31, &e );
     107      256085 :         power_fx = Sqrt32( temp32_fx, &temp_e ); // Q31-temp_e
     108             :         // power_fx = L_shr( power_fx , Q14-(31-temp_e));
     109      256085 :         j1 = 0;
     110      256085 :         move16();
     111      256085 :         j2 = sub( L, 1 );
     112      256085 :         move16();
     113     1635941 :         WHILE( GT_16( sub( j2, j1 ), 1 ) )
     114             :         {
     115     1379856 :             j = shr( add( j1, j2 ), 1 );
     116     1379856 :             Word16 flag = BASOP_Util_Cmp_Mant32Exp( power_fx, temp_e, thre_fxn[j], Q31 - Q14 );
     117     1379856 :             IF( flag >= 0 )
     118             :             {
     119      602935 :                 j2 = j;
     120      602935 :                 move16();
     121             :             }
     122             :             ELSE
     123             :             {
     124      776921 :                 j1 = j;
     125      776921 :                 move16();
     126             :             }
     127             :         }
     128             : 
     129      256085 :         *k_fx = j2;
     130      256085 :         move16();
     131             :     }
     132      257249 :     return;
     133             : }
     134      139692 : void logqnorm_fx(
     135             :     const Word32 *L_x,    /* i : coefficient vector                         Qx  */
     136             :     const Word16 qx,      /* i : Q value of input                               */
     137             :     Word16 *k,            /* o : index                                      Q0  */
     138             :     const Word16 L,       /* i : codebook length                            Q0  */
     139             :     const Word16 N,       /* i : sub-vector size                            Q0  */
     140             :     const Word16 hvq_flag /* i : HVQ flag                                   Q0  */
     141             : )
     142             : {
     143             :     Word16 i, m;
     144             :     Word16 coefs_shift, power_shift, temp_shift;
     145             :     Word32 L_temp, L_temp1, L_temp2;
     146             :     Word16 coefs16[MAX_SFM_LEN_FX];
     147             :     UWord16 lsb;
     148             : 
     149      139692 :     Word16 offset = add( 3, shl( qx, 1 ) ); /* 3 + 2*qx */
     150             : 
     151      139692 :     lsb = 0U; /* to avoid compilation warnings */
     152      139692 :     move16();
     153             : 
     154      139692 :     L_temp1 = L_deposit_l( 1 );
     155     2565833 :     FOR( i = 0; i < N; i++ )
     156             :     {
     157     2426141 :         L_temp2 = L_abs( L_x[i] );
     158     2426141 :         L_temp1 = L_max( L_temp1, L_temp2 );
     159             :     }
     160      139692 :     coefs_shift = sub( norm_l( L_temp1 ), sqac_headroom_fx[N] );
     161      139692 :     L_temp = L_deposit_l( 0 );
     162             : 
     163     2565833 :     FOR( i = 0; i < N; i++ )
     164             :     {
     165     2426141 :         coefs16[i] = extract_h( L_shl( L_x[i], coefs_shift ) ); // Qx + coefs_shift - 16
     166     2426141 :         move16();
     167     2426141 :         L_temp = L_mac0( L_temp, coefs16[i], coefs16[i] ); // 2*(Qx + coefs_shift - 16)
     168             :     }
     169             : 
     170      139692 :     IF( GT_16( N, 1 ) )
     171             :     {
     172      136847 :         Mpy_32_16_ss( L_temp, inv_tbl_fx[N], &L_temp, &lsb ); // 2*(Qx + coefs_shift - 16)
     173             :     }
     174      139692 :     power_shift = shl( sub( coefs_shift, 16 ), 1 );
     175             : 
     176      139692 :     temp_shift = norm_l( L_temp );
     177      139692 :     m = add( temp_shift, power_shift );
     178             : 
     179      139692 :     L_temp1 = L_add( L_shl( L_temp, temp_shift ), L_shr( lsb, sub( 16, temp_shift ) ) ); // 2*(Qx + coefs_shift - 16)+ temp_shift
     180             : 
     181      139692 :     m = add( offset, m );
     182      139692 :     test();
     183      139692 :     IF( LT_16( m, 5 ) && hvq_flag )
     184             :     {
     185           0 :         m = shl( m, 1 );
     186           0 :         IF( LT_32( L_temp1, 1276901417L /* 2^0.25 Q30 */ ) )
     187             :         {
     188           0 :             m = add( m, 2 );
     189             :         }
     190           0 :         ELSE IF( LT_32( L_temp1, 1805811301L /* 2^0.75 Q30 */ ) )
     191             :         {
     192           0 :             m = add( m, 1 );
     193             :         }
     194             :     }
     195             :     ELSE
     196             :     {
     197      139692 :         if ( LT_32( L_temp1, THREN2POW /* 2^0.5 Q30 */ ) )
     198             :         {
     199       69564 :             m = add( m, 1 );
     200             :         }
     201      139692 :         if ( hvq_flag )
     202             :         {
     203           0 :             m = add( m, 5 ); /* offset, 5 extra levels in HVQ codebook */
     204             :         }
     205             :     }
     206      139692 :     *k = s_max( m, 0 );
     207      139692 :     move16();
     208      139692 :     i = sub( L, 1 );
     209      139692 :     *k = s_min( *k, i );
     210      139692 :     move16();
     211             : 
     212      139692 :     return;
     213             : }
     214             : 
     215        5626 : void logqnorm_2_fx(
     216             :     const Word32 *env_fl,    /* o, Q10  : index */
     217             :     const Word16 L,          /* i  : codebook length */
     218             :     const Word16 n_env_band, /* i  : sub-vector size */
     219             :     const Word16 nb_sfm,     /* i  : sub-vector size */
     220             :     Word16 *ynrm,            /* o  : norm indices            Q0*/
     221             :     Word16 *normqlg2,        /* o  : quantized norm values   Q0*/
     222             :     const Word32 *thren      /* i, Q10 : quantization thresholds */
     223             : )
     224             : {
     225             :     Word16 i, j, j1, j2;
     226             :     Word32 temp, power;
     227             : 
     228       94513 :     FOR( i = n_env_band; i < nb_sfm; i++ )
     229             :     {
     230       88887 :         temp = env_fl[sub( i, n_env_band )];
     231       88887 :         IF( LE_32( thren[0], temp ) )
     232             :         {
     233           0 :             *ynrm = 0;
     234           0 :             move16();
     235             :         }
     236       88887 :         ELSE IF( GT_32( thren[sub( L, 2 )], temp ) )
     237             :         {
     238        8833 :             *ynrm = sub( L, 1 );
     239        8833 :             move16();
     240             :         }
     241             :         ELSE
     242             :         {
     243       80054 :             power = temp;
     244       80054 :             move16();
     245       80054 :             j1 = 0;
     246       80054 :             move16();
     247       80054 :             j2 = sub( L, 1 );
     248      511060 :             WHILE( GT_16( sub( j2, j1 ), 1 ) )
     249             :             {
     250      431006 :                 j = shr( add( j1, j2 ), 1 );
     251      431006 :                 IF( GE_32( power, thren[j] ) )
     252             :                 {
     253      166551 :                     j2 = j;
     254      166551 :                     move16();
     255             :                 }
     256             :                 ELSE
     257             :                 {
     258      264455 :                     j1 = j;
     259      264455 :                     move16();
     260             :                 }
     261             :             }
     262       80054 :             *ynrm = j2;
     263       80054 :             move16();
     264             :         }
     265       88887 :         *normqlg2 = dicnlg2[*ynrm];
     266       88887 :         move16();
     267       88887 :         normqlg2++;
     268       88887 :         ynrm++;
     269             :     }
     270             : 
     271        5626 :     return;
     272             : }
     273             : 
     274             : /*--------------------------------------------------------------------------
     275             :  *  calc_norm_fx()
     276             :  *
     277             :  *  Calculate the norms for the spectral envelope
     278             :  *--------------------------------------------------------------------------*/
     279        7815 : void calc_norm_ivas_fx(
     280             :     const Word32 *x_fx,      /* i  : Input vector.(Qin)                       */
     281             :     Word16 *norm,            /* o  : Quantization indices for norms   Q0   */
     282             :     Word16 *normlg,          /* o  : Quantized norms in log2         Q0   */
     283             :     const Word16 start_band, /* i  : Indice of band to start coding      */
     284             :     const Word16 num_bands,  /* i  : Number of bands                     */
     285             :     const Word16 *band_len,  /* i  : Length of bands                     */
     286             :     const Word16 *band_start /* i  : Start of bands                      */
     287             : )
     288             : {
     289             :     Word16 nrm;
     290             :     Word16 band;
     291             :     Word16 tmp;
     292             : 
     293        7815 :     set16_fx( norm, 0, start_band );
     294        7815 :     logqnorm_ivas_fx( &x_fx[band_start[start_band]], 12, &nrm, 32, band_len[start_band], thren_HQ_fx );
     295        7815 :     norm[start_band] = nrm;
     296        7815 :     move16();
     297        7815 :     normlg[start_band] = dicnlg2[nrm];
     298        7815 :     move16();
     299             : 
     300        7815 :     tmp = add( start_band, num_bands );
     301      226494 :     FOR( band = add( start_band, 1 ); band < tmp; band++ )
     302             :     {
     303      218679 :         logqnorm_ivas_fx( &x_fx[band_start[band]], 12, &nrm, 40, band_len[band], thren_HQ_fx );
     304      218679 :         norm[band] = nrm;
     305      218679 :         move16();
     306      218679 :         normlg[band] = dicnlg2[nrm]; // Q0
     307      218679 :         move16();
     308             :     }
     309             : 
     310        7815 :     return;
     311             : }
     312             : 
     313        3207 : void calc_norm_fx(
     314             :     const Word32 *L_x,       /* i  : Input vector.                   Qx  */
     315             :     const Word16 qx,         /* i  : Q value of input                    */
     316             :     Word16 *norm,            /* o  : Quantization indices for norms  Q0  */
     317             :     Word16 *normlg,          /* o  : Quantized norms in log2         Q0  */
     318             :     const Word16 start_band, /* i  : Indice of band to start coding  Q0  */
     319             :     const Word16 num_bands,  /* i  : Number of bands                 Q0  */
     320             :     const Word16 *band_len,  /* i  : Length of bands                 Q0  */
     321             :     const Word16 *band_start /* i  : Start of bands                  Q0  */
     322             : )
     323             : {
     324             :     Word16 nrm;
     325             :     Word16 band;
     326             :     Word16 tmp;
     327             : 
     328        3207 :     set16_fx( norm, 0, start_band );
     329        3207 :     logqnorm_fx( &L_x[band_start[start_band]], qx, &nrm, 32, band_len[start_band], 0 );
     330        3207 :     norm[start_band] = nrm;
     331        3207 :     move16();
     332        3207 :     normlg[start_band] = dicnlg2[nrm];
     333        3207 :     move16();
     334             : 
     335        3207 :     tmp = add( start_band, num_bands );
     336      135618 :     FOR( band = add( start_band, 1 ); band < tmp; band++ )
     337             :     {
     338      132411 :         logqnorm_fx( &L_x[band_start[band]], qx, &nrm, 40, band_len[band], 0 );
     339             : 
     340      132411 :         norm[band] = nrm;
     341      132411 :         move16();
     342      132411 :         normlg[band] = dicnlg2[nrm];
     343      132411 :         move16();
     344             :     }
     345             : 
     346        3207 :     return;
     347             : }

Generated by: LCOV version 1.14