LCOV - code coverage report
Current view: top level - lib_enc - ivas_sns_enc_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 574a190e3c6896c6c4ed10d7f23649709a0c4347 Lines: 412 416 99.0 %
Date: 2025-06-27 02:59:36 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 <assert.h>
      34             : #include <stdint.h>
      35             : #include "options.h"
      36             : #include <math.h>
      37             : #include "cnst.h"
      38             : #include "prot_fx.h"
      39             : #include "ivas_prot_fx.h"
      40             : #include "rom_com.h"
      41             : #include "ivas_rom_com.h"
      42             : #include "ivas_rom_com_fx.h"
      43             : #include "ivas_cnst.h"
      44             : #include "wmc_auto.h"
      45             : #include "prot_fx_enc.h"
      46             : 
      47             : /*-------------------------------------------------------------------
      48             :  * sns_1st_cod()
      49             :  *
      50             :  *
      51             :  *-------------------------------------------------------------------*/
      52             : 
      53             : /* r  : codebook index */
      54      341159 : static Word16 sns_1st_cod_fx(
      55             :     const Word32 *sns_fx, /* i  : vector to quantize                */
      56             :     Word16 exp_sns,
      57             :     const Word16 L_frame,
      58             :     const Word16 core,
      59             :     Word32 *snsq_fx /* o  : quantized sns    Q16 */
      60             : )
      61             : {
      62      341159 :     IF( exp_sns == Q15 )
      63             :     {
      64             :         Word16 index;
      65      157080 :         const Word16 split_len = M / 2;
      66      157080 :         move16();
      67             :         const Word16 *means;
      68      157080 :         const Word16 means_fix = 2; // Q15
      69      157080 :         move16();
      70             :         /* remove means */
      71      157080 :         means = NULL;
      72      157080 :         SWITCH( L_frame )
      73             :         {
      74       11865 :             case L_FRAME16k:
      75       11865 :                 means = &sns_1st_means_16k[core - 1][0]; // Q14
      76       11865 :                 break;
      77       46872 :             case L_FRAME25_6k:
      78       46872 :                 means = &sns_1st_means_25k6[core - 1][0]; // Q14
      79       46872 :                 break;
      80       98343 :             case L_FRAME32k:
      81       98343 :                 means = &sns_1st_means_32k[core - 1][0]; // Q14
      82       98343 :                 break;
      83           0 :             default:
      84           0 :                 assert( !"illegal frame length in sns_1st_cod" );
      85             :         }
      86     2670360 :         FOR( Word16 i = 0; i < M; ++i )
      87             :         {
      88     2513280 :             Word32 tmp = L_mult( means[i], means_fix ); // Q14->Q16
      89     2513280 :             snsq_fx[i] = L_sub( sns_fx[i], tmp );       // Q16
      90     2513280 :             move32();
      91             :         }
      92             : 
      93      157080 :         index = 0;
      94      157080 :         move16();
      95      471240 :         FOR( Word16 split = 0; split < 2; ++split )
      96             :         {
      97             :             const Word16 *cdbk_ptr;
      98             :             Word16 j0, j1;
      99             :             Word16 index_split;
     100             :             Word32 dist_min_fx;
     101      314160 :             const Word16 cdbk_fix = 8; // 1.f / powf( 2, SNS_CDBKS_BITS_4_FRAC ) in Q15
     102      314160 :             move16();
     103      314160 :             const Word16 *const cdbk = &sns_1st_cdbk[split][core - 1][0]; // Q12
     104             : 
     105      314160 :             j0 = imult1616( split, split_len );
     106      314160 :             j1 = add( j0, split_len );
     107             : 
     108      314160 :             cdbk_ptr = cdbk;
     109      314160 :             dist_min_fx = MAXVAL_WORD32;
     110      314160 :             index_split = 0;
     111      314160 :             move32();
     112      314160 :             move16();
     113    10367280 :             FOR( Word16 i = 0; i < 32; ++i )
     114             :             {
     115    10053120 :                 Word32 dist_fx = 0;
     116    10053120 :                 move32();
     117    90478080 :                 FOR( Word16 j = j0; j < j1; ++j ) // j1-j0=split_len. split_len=M/2. M=16
     118             :                 {
     119             :                     Word32 tmp;
     120             :                     Word32 dist;
     121             : 
     122    80424960 :                     tmp = L_mult( *cdbk_ptr++, cdbk_fix ); // Q12->Q16
     123    80424960 :                     dist = L_sub( snsq_fx[j], tmp );       // Q16
     124    80424960 :                     dist = L_shl( dist, 11 );              // cdbk_ptr is a 16 bit LUT with 3.12 values, used as 3.16. assumption: snsq_fx has the same representation. thus, the subtraction results are in 4.16, which leaves 11 bit headroom.
     125    80424960 :                     dist = Mpy_32_32( dist, dist );
     126    80424960 :                     dist = L_shr( dist, 3 ); // make sure that the sum of 8 values does not overflow
     127    80424960 :                     dist_fx = L_add( dist_fx, dist );
     128             :                 }
     129             : 
     130    10053120 :                 IF( LT_32( dist_fx, dist_min_fx ) )
     131             :                 {
     132     1545905 :                     dist_min_fx = dist_fx;
     133     1545905 :                     move32();
     134     1545905 :                     index_split = i;
     135     1545905 :                     move16();
     136             :                 }
     137             :             }
     138             : 
     139             :             /* set quantized vector */
     140      314160 :             cdbk_ptr = &cdbk[imult1616( index_split, split_len )];
     141     2827440 :             FOR( Word16 j = j0; j < j1; ++j )
     142             :             {
     143     2513280 :                 Word32 tmp_3 = L_mult( means[j], means_fix );   // Q16
     144     2513280 :                 Word32 tmp_4 = L_mult( *cdbk_ptr++, cdbk_fix ); // Q16
     145     2513280 :                 snsq_fx[j] = L_add( tmp_4, tmp_3 );             // Q16
     146     2513280 :                 move32();
     147             :             }
     148             : 
     149             :             /* for second split shift by five bits to store both indices as one 10 bit value */
     150      314160 :             if ( EQ_16( split, 1 ) )
     151             :             {
     152      157080 :                 index_split = shl( index_split, 5 );
     153             :             }
     154             : 
     155      314160 :             index = add( index, index_split );
     156             :         }
     157      157080 :         return index;
     158             :     }
     159             :     ELSE
     160             :     {
     161             :         Word16 index, i;
     162      184079 :         const Word16 split_len = M / 2;
     163      184079 :         move16();
     164             :         const Word16 *means;
     165      184079 :         const Word16 means_fix = 2; // Q15
     166      184079 :         move16();
     167             :         /* remove means */
     168      184079 :         means = NULL;
     169      184079 :         SWITCH( L_frame )
     170             :         {
     171       22038 :             case L_FRAME16k:
     172       22038 :                 means = &sns_1st_means_16k[core - 1][0];
     173       22038 :                 break;
     174       50865 :             case L_FRAME25_6k:
     175       50865 :                 means = &sns_1st_means_25k6[core - 1][0];
     176       50865 :                 break;
     177      111176 :             case L_FRAME32k:
     178      111176 :                 means = &sns_1st_means_32k[core - 1][0];
     179      111176 :                 break;
     180           0 :             default:
     181           0 :                 assert( !"illegal frame length in sns_1st_cod" );
     182             :         }
     183      184079 :         Word16 exp_snsq_buffer[M] = { 0 }, exp_snsq = 0;
     184      184079 :         move16();
     185      184079 :         move16();
     186     3129343 :         FOR( i = 0; i < M; ++i )
     187             :         {
     188     2945264 :             Word32 tmp = L_mult( means[i], means_fix ); // Q16
     189     2945264 :             exp_snsq_buffer[i] = 0;
     190     2945264 :             move16();
     191     2945264 :             snsq_fx[i] = BASOP_Util_Add_Mant32Exp( sns_fx[i], exp_sns, L_negate( tmp ), 15, &exp_snsq_buffer[i] );
     192     2945264 :             move32();
     193             :         }
     194     3129343 :         FOR( i = 0; i < M; i++ )
     195             :         {
     196     2945264 :             exp_snsq = s_max( exp_snsq_buffer[i], exp_snsq );
     197             :         }
     198     3129343 :         FOR( i = 0; i < M; i++ )
     199             :         {
     200     2945264 :             snsq_fx[i] = L_shr( snsq_fx[i], exp_snsq - exp_snsq_buffer[i] );
     201     2945264 :             move32();
     202             :         }
     203             : 
     204      184079 :         index = 0;
     205      184079 :         move16();
     206      552237 :         FOR( Word16 split = 0; split < 2; ++split )
     207             :         {
     208             :             const Word16 *cdbk_ptr;
     209             :             Word16 j0, j1, index_split;
     210             :             Word32 dist_min_fx;
     211      368158 :             const Word16 cdbk_fix = 8; // 1.f / powf( 2, SNS_CDBKS_BITS_4_FRAC ) in Q15
     212      368158 :             move16();
     213      368158 :             const Word16 *const cdbk = &sns_1st_cdbk[split][core - 1][0];
     214             : 
     215      368158 :             j0 = imult1616( split, split_len );
     216      368158 :             j1 = add( j0, split_len );
     217             : 
     218      368158 :             cdbk_ptr = cdbk;
     219      368158 :             dist_min_fx = MAXVAL_WORD32;
     220      368158 :             Word16 exp_dist_min = 31;
     221      368158 :             index_split = 0;
     222    12149214 :             FOR( i = 0; i < 32; ++i )
     223             :             {
     224    11781056 :                 Word32 dist_fx = 0;
     225    11781056 :                 move32();
     226    11781056 :                 Word16 exp_dist = 0;
     227    11781056 :                 move16();
     228   106029504 :                 FOR( Word16 j = j0; j < j1; ++j )
     229             :                 {
     230             :                     Word32 tmp_fx;
     231    94248448 :                     Word16 exp_tmp = 0;
     232    94248448 :                     move16();
     233    94248448 :                     Word32 tmp_1 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16
     234    94248448 :                     tmp_fx = BASOP_Util_Add_Mant32Exp( snsq_fx[j], exp_snsq, L_negate( tmp_1 ), 15, &exp_tmp );
     235    94248448 :                     Word32 tmp_2 = Mpy_32_32( tmp_fx, tmp_fx );                                             // exp_tmp*2
     236    94248448 :                     dist_fx = BASOP_Util_Add_Mant32Exp( dist_fx, exp_dist, tmp_2, exp_tmp * 2, &exp_dist ); // exp_tmp*2
     237             :                 }
     238             : 
     239    11781056 :                 IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( dist_fx, exp_dist, dist_min_fx, exp_dist_min ), -1 ) )
     240             :                 {
     241     1827307 :                     dist_min_fx = dist_fx;
     242     1827307 :                     move32();
     243     1827307 :                     exp_dist_min = exp_dist;
     244     1827307 :                     move16();
     245     1827307 :                     index_split = i;
     246     1827307 :                     move16();
     247             :                 }
     248             :             }
     249             : 
     250             :             /* set quantized vector */
     251      368158 :             cdbk_ptr = &cdbk[imult1616( index_split, split_len )];
     252     3313422 :             FOR( Word16 j = j0; j < j1; ++j )
     253             :             {
     254     2945264 :                 Word32 tmp_3 = L_mult( means[j], means_fix );       // Q16
     255     2945264 :                 Word32 tmp_4 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16
     256     2945264 :                 snsq_fx[j] = L_add( tmp_4, tmp_3 );                 // Q16
     257     2945264 :                 move32();
     258             :             }
     259             : 
     260             :             /* for second split shift by five bits to store both indices as one 10 bit value */
     261      368158 :             IF( EQ_16( split, 1 ) )
     262             :             {
     263      184079 :                 index_split = shl( index_split, 5 );
     264             :             }
     265             : 
     266      368158 :             index = add( index, index_split );
     267             :         }
     268             : 
     269      184079 :         return index;
     270             :     }
     271             : }
     272             : 
     273             : /*-------------------------------------------------------------------
     274             :  * sns_2st_cod()
     275             :  *
     276             :  *
     277             :  *-------------------------------------------------------------------*/
     278             : 
     279             : /* r  : number of allocated bits        */
     280      536209 : static Word16 sns_2st_cod_fx(
     281             :     const Word32 *sns_fx, /* i  : normalized vector to quantize   */
     282             :     Word16 exp_sns,
     283             :     Word32 *snsq_fx, /* i/o: i:1st stage   o:1st+2nd stage   Q16 */
     284             :     Word16 exp_snsq,
     285             :     Word16 *indx /* o  : index[] (4 bits per words)      */
     286             : )
     287             : {
     288             :     Word16 i, nbits;
     289             : 
     290      536209 :     Word16 x_fx[M] = { 0 };
     291      536209 :     move16();
     292             :     Word16 xq_fx[M];
     293      536209 :     Word16 exp_x_buff[M] = { 0 }, exp_x = 0;
     294      536209 :     move16();
     295      536209 :     move16();
     296      536209 :     Word32 scale_fx = 858993472; // Q31
     297      536209 :     move32();
     298             :     Word16 nq;
     299             : 
     300     9115553 :     FOR( i = 0; i < M; i++ )
     301             :     {
     302     8579344 :         Word16 exp_tmp = 0;
     303     8579344 :         move16();
     304     8579344 :         Word32 tmp = BASOP_Util_Add_Mant32Exp( sns_fx[i], exp_sns, L_negate( snsq_fx[i] ), exp_snsq, &exp_tmp );
     305     8579344 :         x_fx[i] = BASOP_Util_Divide3232_Scale( tmp, scale_fx, &exp_x_buff[i] );
     306     8579344 :         move16();
     307     8579344 :         exp_x_buff[i] = add( exp_x_buff[i], exp_tmp );
     308     8579344 :         move16();
     309             :     }
     310     9115553 :     FOR( i = 0; i < M; i++ )
     311             :     {
     312     8579344 :         exp_x = s_max( exp_x, exp_x_buff[i] );
     313             :     }
     314     9115553 :     FOR( i = 0; i < M; i++ )
     315             :     {
     316     8579344 :         x_fx[i] = shr( x_fx[i], sub( ( 15 - Q10 ), exp_x_buff[i] ) );
     317     8579344 :         move16();
     318             :     }
     319             : 
     320             :     /* quantize */
     321      536209 :     AVQ_cod_lpc_fx( x_fx, xq_fx, indx, 2 );
     322     9115553 :     FOR( i = 0; i < M; i++ )
     323             :     {
     324     8579344 :         Word32 tmp_1 = Mpy_32_16_1( scale_fx, xq_fx[i] ); // Q31 + Q10 - 15
     325     8579344 :         tmp_1 = L_shr( tmp_1, 10 );                       // Q16
     326     8579344 :         snsq_fx[i] = L_add( snsq_fx[i], tmp_1 );          // Q16
     327     8579344 :         move32();
     328             :     }
     329             : 
     330             :     /* total number of bits using entropic code to index the quantizer number */
     331      536209 :     nbits = 0;
     332      536209 :     move16();
     333     1608627 :     FOR( i = 0; i < 2; i++ )
     334             :     {
     335     1072418 :         nq = indx[i];
     336     1072418 :         move16();
     337     1072418 :         nbits = add( nbits, ( add( 2, ( shl( nq, 2 ) ) ) ) ); /* 2 bits to specify Q2,Q3,Q4,ext */
     338             : 
     339     1072418 :         IF( GT_16( nq, 6 ) )
     340             :         {
     341         338 :             nbits = add( nbits, sub( nq, 3 ) ); /* unary code (Q7=1110, ...) */
     342             :         }
     343     1072080 :         ELSE IF( GT_16( nq, 4 ) )
     344             :         {
     345       36308 :             nbits = add( nbits, sub( nq, 4 ) ); /* Q5=0, Q6=10 */
     346             :         }
     347     1035772 :         ELSE IF( nq == 0 )
     348             :         {
     349      111060 :             nbits = add( nbits, 3 ); /* Q0=110 */
     350             :         }
     351             :     }
     352             : 
     353      536209 :     return ( nbits );
     354             : }
     355             : 
     356             : /*-------------------------------------------------------------------
     357             :  * sns_avq_cod()
     358             :  *
     359             :  * Stereo noise-shaping AVQ encoder for 1 channel
     360             :  *-------------------------------------------------------------------*/
     361       72781 : void sns_avq_cod_fx(
     362             :     const Word32 *sns_fx, /* i  : Input sns vectors               */
     363             :     Word16 exp_sns,
     364             :     const Word32 *snsmid_fx, /* i  : Input mid-sns vectors           */
     365             :     Word16 exp_snsmid,
     366             :     Word32 *sns_q_fx,    /* o  : Quantized LFS vectors           Q16 */
     367             :     Word32 *snsmid_q_fx, /* o  : Quantized mid-LFS vectors       Q16 */
     368             :     Word16 *index,       /* o  : Quantization indices            */
     369             :     const Word16 core,   /* i  : core                            */
     370             :     const Word16 L_frame,
     371             :     const Word16 low_brate_mode /* i  : flag low bit operating mode     */
     372             : )
     373             : {
     374             :     Word16 i;
     375             :     Word16 indxt[256], nbits, nbt, nit;
     376             :     Word32 snsmid_q0_fx[M];
     377             : 
     378       72781 :     index[0] = sns_1st_cod_fx( sns_fx, exp_sns, L_frame, core, sns_q_fx );
     379       72781 :     move16();
     380       72781 :     nit = 1 + 2;
     381       72781 :     move16();
     382       72781 :     IF( !low_brate_mode )
     383             :     {
     384       72619 :         nbt = sns_2st_cod_fx( sns_fx, exp_sns, sns_q_fx, 31 - Q16, &index[1] );
     385       72619 :         nit = add( nit, add( index[1], index[2] ) );
     386             :     }
     387             :     ELSE
     388             :     {
     389         162 :         index[1] = SNS_LOW_BR_MODE;
     390         162 :         move16();
     391         162 :         index[2] = 0;
     392         162 :         move16();
     393             :     }
     394             : 
     395       72781 :     index += nit;
     396       72781 :     nit = 0;
     397       72781 :     move16();
     398       72781 :     *index = 0;
     399       72781 :     move16();
     400             : 
     401       72781 :     IF( EQ_16( core, TCX_10_CORE ) )
     402             :     {
     403       11399 :         index++;
     404             : 
     405       11399 :         index[0] = sns_1st_cod_fx( snsmid_fx, exp_snsmid, L_frame, core, snsmid_q_fx );
     406       11399 :         move16();
     407       11399 :         nit = 1 + 2;
     408       11399 :         move16();
     409       11399 :         IF( !low_brate_mode )
     410             :         {
     411       11266 :             nbits = sns_2st_cod_fx( snsmid_fx, exp_snsmid, snsmid_q_fx, 31 - Q16, &index[1] );
     412       11266 :             nit = add( nit, add( index[1], index[2] ) );
     413             :         }
     414             :         ELSE
     415             :         {
     416         133 :             index[1] = SNS_LOW_BR_MODE;
     417         133 :             move16();
     418         133 :             index[2] = 0;
     419         133 :             move16();
     420         133 :             nbits = 0;
     421         133 :             move16();
     422             :         }
     423             : 
     424             : 
     425       11399 :         nbt = add( 10, nbits );
     426             : 
     427       11399 :         IF( !low_brate_mode )
     428             :         {
     429      191522 :             FOR( i = 0; i < M; i++ )
     430             :             {
     431      180256 :                 snsmid_q0_fx[i] = sns_q_fx[i];
     432      180256 :                 move32();
     433             :             }
     434       11266 :             nbits = sns_2st_cod_fx( snsmid_fx, exp_snsmid, snsmid_q0_fx, 31 - Q16, indxt );
     435             : 
     436       11266 :             IF( LT_16( nbits, nbt ) )
     437             :             {
     438        7179 :                 nbt = nbits;
     439        7179 :                 move16();
     440        7179 :                 nit = add( 2, add( indxt[0], indxt[1] ) );
     441        7179 :                 index[-1] = 1;
     442        7179 :                 move16();
     443             : 
     444      122043 :                 FOR( i = 0; i < M; i++ )
     445             :                 {
     446      114864 :                     snsmid_q_fx[i] = snsmid_q0_fx[i];
     447      114864 :                     move32();
     448             :                 }
     449             : 
     450       61796 :                 FOR( i = 0; i < nit; i++ )
     451             :                 {
     452       54617 :                     index[i] = indxt[i];
     453       54617 :                     move16();
     454             :                 }
     455             :             }
     456             :         }
     457       11399 :         index += nit;
     458             :     }
     459       72781 :     return;
     460             : }
     461             : 
     462             : /*-------------------------------------------------------------------
     463             :  * sns_avq_cod_stereo()
     464             :  *
     465             :  * Stereo noise-shaping AVQ encoder for 2 channels
     466             :  *-------------------------------------------------------------------*/
     467             : 
     468      220529 : void sns_avq_cod_stereo_fx(
     469             :     const Word32 *snsl_fx, /* i  : Input sns vector (left channel)         */
     470             :     Word16 exp_snl,
     471             :     const Word32 *snsr_fx, /* i  : Input sns vector (right channel)        */
     472             :     Word16 exp_snr,
     473             :     const Word16 L_frame,
     474             :     Word32 *snsl_q_fx, /* o  : Quantized sns vector (left channel)     Q16 */
     475             :     Word32 *snsr_q_fx, /* o  : Quantized sns vector (right channel)    Q16 */
     476             :     Word16 *indexl,    /* o  : Quantization indices (left channel)     */
     477             :     Word16 *indexr     /* o  : Quantization indices (right channel)    */
     478             : )
     479             : {
     480             :     Word16 i, flag_zero;
     481             :     Word32 mid_fx[M], side_fx[M], mid_q_fx[M], side_q_fx[M], ener_side_fx;
     482      220529 :     Word16 exp_ener_side = 0, exp_side_buffer[M] = { 0 }, exp_side = MIN16B;
     483      220529 :     move16();
     484      220529 :     move16();
     485      220529 :     move16();
     486             : 
     487             :     /* Compute side */
     488      220529 :     ener_side_fx = 0;
     489      220529 :     move16();
     490     3748993 :     FOR( i = 0; i < M; i++ )
     491             :     {
     492     3528464 :         side_fx[i] = BASOP_Util_Add_Mant32Exp( snsl_fx[i], exp_snl, L_negate( snsr_fx[i] ), exp_snr, &exp_side_buffer[i] );
     493     3528464 :         move32();
     494     3528464 :         Word32 tmp = Mpy_32_32( side_fx[i], side_fx[i] ); // exp_side[i] * 2
     495     3528464 :         ener_side_fx = BASOP_Util_Add_Mant32Exp( ener_side_fx, exp_ener_side, tmp, shl( exp_side_buffer[i], 1 ), &exp_ener_side );
     496             :     }
     497     3748993 :     FOR( i = 0; i < M; i++ )
     498             :     {
     499     3528464 :         exp_side = s_max( exp_side, exp_side_buffer[i] );
     500             :     }
     501     3748993 :     FOR( i = 0; i < M; i++ )
     502             :     {
     503     3528464 :         side_fx[i] = L_shr( side_fx[i], exp_side - exp_side_buffer[i] );
     504     3528464 :         move32();
     505             :     }
     506             : 
     507      220529 :     Word16 flag = BASOP_Util_Cmp_Mant32Exp( ener_side_fx, exp_ener_side, 24576, 31 - Q11 );
     508      220529 :     IF( EQ_16( flag, -1 ) )
     509             :     {
     510             :         /* MS coding */
     511      184079 :         *indexl++ = 2;
     512      184079 :         move16();
     513      184079 :         *indexr++ = 3;
     514      184079 :         move16();
     515             : 
     516             :         /* Compute mid */
     517      184079 :         Word16 exp_mid_buffer[M] = { 0 };
     518      184079 :         move16();
     519     3129343 :         FOR( i = 0; i < M; i++ )
     520             :         {
     521     2945264 :             mid_fx[i] = BASOP_Util_Add_Mant32Exp( snsl_fx[i], exp_snl, snsr_fx[i], exp_snr, &exp_mid_buffer[i] );
     522     2945264 :             move32();
     523     2945264 :             mid_fx[i] = L_shr( mid_fx[i], 1 );
     524     2945264 :             move32();
     525             :         }
     526             : 
     527             :         /* Quantize mid */
     528      184079 :         Word16 exp_mid = 0;
     529      184079 :         move16();
     530     3129343 :         FOR( i = 0; i < M; i++ )
     531             :         {
     532     2945264 :             exp_mid = s_max( exp_mid, exp_mid_buffer[i] );
     533             :         }
     534     3129343 :         FOR( i = 0; i < M; i++ )
     535             :         {
     536     2945264 :             mid_fx[i] = L_shr( mid_fx[i], exp_mid - exp_mid_buffer[i] );
     537     2945264 :             move32();
     538             :         }
     539      184079 :         indexl[0] = sns_1st_cod_fx( mid_fx, exp_mid, L_frame, TCX_20_CORE, mid_q_fx );
     540      184079 :         move16();
     541      184079 :         sns_2st_cod_fx( mid_fx, exp_mid, mid_q_fx, ( 31 - Q16 ), &indexl[1] );
     542             : 
     543             :         /* Quantize side */
     544      184079 :         indexr[0] = -1;
     545      184079 :         move16();
     546     3129343 :         FOR( i = 0; i < M; i++ )
     547             :         {
     548     2945264 :             side_q_fx[i] = 0;
     549     2945264 :             move32();
     550             :         }
     551      184079 :         sns_2st_cod_fx( side_fx, exp_side, side_q_fx, 31 - Q16, &indexr[1] );
     552             : 
     553             :         /* Detect zero side */
     554      184079 :         flag_zero = 1;
     555      184079 :         move16();
     556      615598 :         FOR( i = 0; i < M; i++ )
     557             :         {
     558      595805 :             if ( side_q_fx[i] != 0 )
     559             :             {
     560      164286 :                 flag_zero = 0;
     561      164286 :                 move16();
     562      164286 :                 break;
     563             :             }
     564             :         }
     565      184079 :         if ( flag_zero )
     566             :         {
     567       19793 :             indexr[0] = -2;
     568       19793 :             move16();
     569             :         }
     570             : 
     571             :         /* Go back to LR */
     572     3129343 :         FOR( i = 0; i < M; i++ )
     573             :         {
     574     2945264 :             Word32 a = L_shr( side_q_fx[i], 1 );
     575     2945264 :             snsl_q_fx[i] = L_add( mid_q_fx[i], a );
     576     2945264 :             move32();
     577     2945264 :             snsr_q_fx[i] = L_sub( mid_q_fx[i], a );
     578     2945264 :             move32();
     579             :         }
     580             :     }
     581             :     ELSE
     582             :     {
     583             :         /* LR coding */
     584       36450 :         *indexl++ = 0;
     585       36450 :         move16();
     586       36450 :         *indexr++ = 1;
     587       36450 :         move16();
     588             : 
     589             :         /* Quantize left */
     590       36450 :         indexl[0] = sns_1st_cod_fx( snsl_fx, exp_snl, L_frame, TCX_20_CORE, snsl_q_fx );
     591       36450 :         move16();
     592       36450 :         sns_2st_cod_fx( snsl_fx, exp_snl, snsl_q_fx, ( 31 - Q16 ), &indexl[1] );
     593             : 
     594             :         /* Quantize right */
     595       36450 :         indexr[0] = sns_1st_cod_fx( snsr_fx, exp_snr, L_frame, TCX_20_CORE, snsr_q_fx );
     596       36450 :         move16();
     597       36450 :         sns_2st_cod_fx( snsr_fx, exp_snr, snsr_q_fx, ( 31 - Q16 ), &indexr[1] );
     598             :     }
     599      220529 :     return;
     600             : }
     601       48382 : Word16 quantize_sns_fx(
     602             :     Word32 sns_in_fx[CPE_CHANNELS][NB_DIV][M],   /* sns_e */
     603             :     Word32 snsQ_out_fx[CPE_CHANNELS][NB_DIV][M], /* sns_e */
     604             :     Word16 sns_e,
     605             :     Encoder_State **sts,
     606             :     Word16 *indices,          /* Q0 */
     607             :     Word16 *zero_side_flag,   /* Q0 */
     608             :     Word16 *sns_stereo_mode ) /* Q0 */
     609             : {
     610       48382 :     Word16 nSubframes = 0, k, ch, i;
     611             :     Word16 nbits, idxIndices;
     612             :     Encoder_State *st;
     613             : 
     614             :     Word16 weights_fx[M];
     615             :     Word16 sns_e_tmp[CPE_CHANNELS][NB_DIV];
     616             : 
     617       48382 :     nbits = 0;
     618       48382 :     move16();
     619       48382 :     idxIndices = 0;
     620       48382 :     move16();
     621       48382 :     set16_fx( weights_fx, ONE_IN_Q8, M );
     622             : 
     623       48382 :     sns_stereo_mode[0] = SNS_STEREO_MODE_LR;
     624       48382 :     move16();
     625       48382 :     sns_stereo_mode[1] = SNS_STEREO_MODE_LR;
     626       48382 :     move16();
     627       48382 :     zero_side_flag[0] = 0;
     628       48382 :     move16();
     629       48382 :     zero_side_flag[1] = 0;
     630       48382 :     move16();
     631             : 
     632             :     /* use snsQ_out as buffer, move input vectors */
     633      145146 :     FOR( ch = 0; ch < CPE_CHANNELS; ++ch )
     634             :     {
     635       96764 :         IF( EQ_16( sts[ch]->core, TCX_20_CORE ) )
     636             :         {
     637       94418 :             nSubframes = 1;
     638             :         }
     639             :         ELSE
     640             :         {
     641        2346 :             nSubframes = NB_DIV;
     642             :         }
     643       96764 :         move16();
     644             : 
     645      195874 :         FOR( k = 0; k < nSubframes; ++k )
     646             :         {
     647       99110 :             Copy32( sns_in_fx[ch][k], snsQ_out_fx[ch][k], M ); // sns_e
     648             :         }
     649             : 
     650       96764 :         sns_e_tmp[ch][0] = sns_e;
     651       96764 :         move16();
     652       96764 :         sns_e_tmp[ch][1] = sns_e;
     653       96764 :         move16();
     654             :     }
     655             : 
     656             :     /* stereo mode decision */
     657       48382 :     IF( EQ_16( sts[0]->core, sts[1]->core ) )
     658             :     {
     659       48058 :         IF( EQ_16( sts[0]->core, TCX_20_CORE ) )
     660             :         {
     661       47047 :             nSubframes = 1;
     662             :         }
     663             :         ELSE
     664             :         {
     665        1011 :             nSubframes = NB_DIV;
     666             :         }
     667       48058 :         move16();
     668             : 
     669       97127 :         FOR( k = 0; k < nSubframes; ++k )
     670             :         {
     671             :             Word32 side_fx[M];
     672             :             Word32 ener_side_fx;
     673             :             Word16 ener_side_q;
     674             : 
     675       49069 :             v_sub_fixed_no_hdrm( snsQ_out_fx[0][k], snsQ_out_fx[1][k], side_fx, M );
     676             : 
     677             :             Word64 L64_sum;
     678       49069 :             L64_sum = 1;
     679       49069 :             move64();
     680      834173 :             FOR( i = 0; i < M; i++ )
     681             :             {
     682      785104 :                 L64_sum = W_mac_32_32( L64_sum, side_fx[i], side_fx[i] );
     683             :             }
     684       49069 :             i = W_norm( L64_sum );
     685       49069 :             L64_sum = W_shl( L64_sum, i );
     686       49069 :             ener_side_fx = W_extract_h( L64_sum ); // ener_side_q
     687       49069 :             ener_side_q = sub( add( shl( sub( 31, sns_e ), 1 ), add( 1, i ) ), 32 );
     688             : 
     689       49069 :             sns_stereo_mode[k] = 0;
     690       49069 :             move16();
     691       49069 :             zero_side_flag[k] = 0;
     692       49069 :             move16();
     693             : 
     694       49069 :             IF( LT_32( L_shl( ener_side_fx, sub( s_min( Q27, ener_side_q ), ener_side_q ) ), L_shl( 1610612736 /* 12.0 if Q27*/, sub( s_min( Q27, ener_side_q ), Q27 ) ) ) )
     695             :             {
     696       45900 :                 sns_stereo_mode[k] = 1;
     697       45900 :                 move16();
     698             :             }
     699             : 
     700       49069 :             IF( LT_32( L_shl( ener_side_fx, sub( s_min( Q30, ener_side_q ), ener_side_q ) ), L_shl( 1, s_min( Q30, ener_side_q ) ) ) )
     701             :             {
     702        9499 :                 zero_side_flag[k] = 1;
     703        9499 :                 move16();
     704             :             }
     705             : 
     706             : 
     707       49069 :             IF( EQ_16( sns_stereo_mode[k], SNS_STEREO_MODE_MS ) )
     708             :             {
     709       45900 :                 convertToMS_fx( M, snsQ_out_fx[0][k], snsQ_out_fx[1][k], ONE_IN_Q30 );
     710             :             }
     711             :         }
     712             :     }
     713             : 
     714             :     /* run MSVQ */
     715      145146 :     FOR( ch = 0; ch < CPE_CHANNELS; ++ch )
     716             :     {
     717       96764 :         st = sts[ch];
     718       96764 :         IF( EQ_16( st->core, TCX_20_CORE ) )
     719             :         {
     720       94418 :             nSubframes = 1;
     721             :         }
     722             :         ELSE
     723             :         {
     724        2346 :             nSubframes = NB_DIV;
     725             :         }
     726       96764 :         move16();
     727             : 
     728      195874 :         FOR( k = 0; k < nSubframes; ++k )
     729             :         {
     730       99110 :             Word16 is_side = 0;
     731       99110 :             move16();
     732       99110 :             IF( EQ_16( ch, 1 ) && EQ_16( sns_stereo_mode[k], SNS_STEREO_MODE_MS ) )
     733             :             {
     734       45900 :                 is_side = 1;
     735       45900 :                 move16();
     736             :             }
     737             : 
     738             :             const Word16 *const *cdbks_fx;
     739             :             const Word16 *levels;
     740             :             const Word16 *bits;
     741             :             Word16 nStages;
     742       99110 :             IF( EQ_16( nSubframes, 1 ) )
     743             :             {
     744       94418 :                 cdbks_fx = ivas_sns_cdbks_tcx20_fx;
     745       94418 :                 levels = ivas_sns_cdbks_tcx20_levels;
     746       94418 :                 bits = ivas_sns_cdbks_tcx20_bits;
     747       94418 :                 nStages = SNS_MSVQ_NSTAGES_TCX20;
     748             :             }
     749             :             ELSE
     750             :             {
     751        4692 :                 cdbks_fx = ivas_sns_cdbks_tcx10_fx;
     752        4692 :                 levels = ivas_sns_cdbks_tcx10_levels;
     753        4692 :                 bits = ivas_sns_cdbks_tcx10_bits;
     754        4692 :                 nStages = SNS_MSVQ_NSTAGES_TCX10;
     755             :             }
     756       99110 :             move16();
     757             : 
     758       99110 :             Word32 *snsQ_fx = snsQ_out_fx[ch][k];
     759       99110 :             const Word32 *sns_ptr_fx = snsQ_out_fx[ch][k];
     760             : 
     761       99110 :             IF( is_side )
     762             :             {
     763             :                 const Word16 *const *side_cdbks_fx;
     764             :                 const Word16 *side_levels;
     765             : 
     766       45900 :                 IF( EQ_16( st->core, TCX_20_CORE ) )
     767             :                 {
     768       44060 :                     side_cdbks_fx = ivas_sns_cdbks_side_tcx20_fx;
     769       44060 :                     side_levels = ivas_sns_cdbks_side_tcx20_levels;
     770       44060 :                     bits = ivas_sns_cdbks_side_tcx20_bits;
     771             :                 }
     772             :                 ELSE
     773             :                 {
     774        1840 :                     side_cdbks_fx = ivas_sns_cdbks_side_tcx10_fx;
     775        1840 :                     side_levels = ivas_sns_cdbks_side_tcx10_levels;
     776        1840 :                     bits = ivas_sns_cdbks_side_tcx10_bits;
     777             :                 }
     778             : 
     779             : 
     780       45900 :                 IF( zero_side_flag[k] )
     781             :                 {
     782        9499 :                     set32_fx( snsQ_fx, 0, M );
     783        9499 :                     CONTINUE;
     784             :                 }
     785             : 
     786       36401 :                 nStages = SNS_MSVQ_NSTAGES_SIDE;
     787       36401 :                 move16();
     788             : 
     789       36401 :                 msvq_enc_ivas_fx( side_cdbks_fx, Q15, NULL, NULL, snsQ_fx, sns_e, side_levels, 3, nStages, weights_fx, M, M, 0, NULL, &indices[idxIndices] );
     790       36401 :                 msvq_dec_fx( side_cdbks_fx, NULL, NULL, nStages, M, M, &indices[idxIndices], 0, NULL, snsQ_fx, NULL, Q15 );
     791             :             }
     792             :             ELSE
     793             :             {
     794       53210 :                 msvq_enc_ivas_fx( cdbks_fx, Q12, NULL, NULL, sns_ptr_fx, sns_e, levels, 3, nStages, weights_fx, M, M, 0, NULL, &indices[idxIndices] );
     795       53210 :                 msvq_dec_fx( cdbks_fx, NULL, NULL, nStages, M, M, &indices[idxIndices], 0, NULL, snsQ_fx, NULL, Q12 );
     796             :             }
     797       89611 :             Word16 shift = find_guarded_bits_fx( M );
     798       89611 :             sns_e_tmp[ch][k] = sub( 31, sub( 20, shift ) );
     799       89611 :             move16();
     800       89611 :             idxIndices = add( idxIndices, nStages );
     801             : 
     802      372401 :             FOR( i = 0; i < nStages; ++i )
     803             :             {
     804      282790 :                 nbits = add( nbits, bits[i] );
     805             :             }
     806             :         }
     807             :     }
     808             :     /* Re-Scaling Buffers*/
     809       48382 :     sns_e = sns_e_tmp[0][0];
     810       48382 :     move16();
     811             : 
     812      145146 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
     813             :     {
     814       96764 :         sns_e = s_max( sns_e, sns_e_tmp[ch][0] );
     815       96764 :         sns_e = s_max( sns_e, sns_e_tmp[ch][1] );
     816             :     }
     817             : 
     818      145146 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
     819             :     {
     820      195874 :         FOR( k = 0; k < nSubframes; k++ )
     821             :         {
     822       99110 :             scale_sig32( snsQ_out_fx[ch][k], M, sub( sns_e_tmp[ch][k], sns_e ) ); // Q(31-sns_e_tmp[ch][k])
     823             :         }
     824             :     }
     825             :     /* get back to L/F representation */
     826       48382 :     test();
     827       48382 :     IF( EQ_16( sns_stereo_mode[0], SNS_STEREO_MODE_MS ) || EQ_16( sns_stereo_mode[1], SNS_STEREO_MODE_MS ) )
     828             :     {
     829       45028 :         IF( EQ_16( sts[0]->core, TCX_20_CORE ) )
     830             :         {
     831       44060 :             nSubframes = 1;
     832             :         }
     833             :         ELSE
     834             :         {
     835         968 :             nSubframes = NB_DIV;
     836             :         }
     837       45028 :         move16();
     838             : 
     839       91024 :         FOR( k = 0; k < nSubframes; ++k )
     840             :         {
     841       45996 :             IF( EQ_16( sns_stereo_mode[k], SNS_STEREO_MODE_MS ) )
     842             :             {
     843       45900 :                 convertToMS_fx( M, snsQ_out_fx[0][k], snsQ_out_fx[1][k], ONE_IN_Q31 );
     844             :             }
     845             :         }
     846             :     }
     847             : 
     848       48382 :     return nbits;
     849             : }

Generated by: LCOV version 1.14