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 @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 412 416 99.0 %
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 <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      341101 : 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      341101 :     IF( exp_sns == Q15 )
      63             :     {
      64             :         Word16 index;
      65      157046 :         const Word16 split_len = M / 2;
      66      157046 :         move16();
      67             :         const Word16 *means;
      68      157046 :         const Word16 means_fix = 2; // Q15
      69      157046 :         move16();
      70             :         /* remove means */
      71      157046 :         means = NULL;
      72      157046 :         SWITCH( L_frame )
      73             :         {
      74       11859 :             case L_FRAME16k:
      75       11859 :                 means = &sns_1st_means_16k[core - 1][0]; // Q14
      76       11859 :                 break;
      77       46840 :             case L_FRAME25_6k:
      78       46840 :                 means = &sns_1st_means_25k6[core - 1][0]; // Q14
      79       46840 :                 break;
      80       98347 :             case L_FRAME32k:
      81       98347 :                 means = &sns_1st_means_32k[core - 1][0]; // Q14
      82       98347 :                 break;
      83           0 :             default:
      84           0 :                 assert( !"illegal frame length in sns_1st_cod" );
      85             :         }
      86     2669782 :         FOR( Word16 i = 0; i < M; ++i )
      87             :         {
      88     2512736 :             Word32 tmp = L_mult( means[i], means_fix ); // Q14->Q16
      89     2512736 :             snsq_fx[i] = L_sub( sns_fx[i], tmp );       // Q16
      90     2512736 :             move32();
      91             :         }
      92             : 
      93      157046 :         index = 0;
      94      157046 :         move16();
      95      471138 :         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      314092 :             const Word16 cdbk_fix = 8; // 1.f / powf( 2, SNS_CDBKS_BITS_4_FRAC ) in Q15
     102      314092 :             move16();
     103      314092 :             const Word16 *const cdbk = &sns_1st_cdbk[split][core - 1][0]; // Q12
     104             : 
     105      314092 :             j0 = imult1616( split, split_len );
     106      314092 :             j1 = add( j0, split_len );
     107             : 
     108      314092 :             cdbk_ptr = cdbk;
     109      314092 :             dist_min_fx = MAXVAL_WORD32;
     110      314092 :             index_split = 0;
     111      314092 :             move32();
     112      314092 :             move16();
     113    10365036 :             FOR( Word16 i = 0; i < 32; ++i )
     114             :             {
     115    10050944 :                 Word32 dist_fx = 0;
     116    10050944 :                 move32();
     117    90458496 :                 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    80407552 :                     tmp = L_mult( *cdbk_ptr++, cdbk_fix ); // Q12->Q16
     123    80407552 :                     dist = L_sub( snsq_fx[j], tmp );       // Q16
     124    80407552 :                     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    80407552 :                     dist = Mpy_32_32( dist, dist );
     126    80407552 :                     dist = L_shr( dist, 3 ); // make sure that the sum of 8 values does not overflow
     127    80407552 :                     dist_fx = L_add( dist_fx, dist );
     128             :                 }
     129             : 
     130    10050944 :                 IF( LT_32( dist_fx, dist_min_fx ) )
     131             :                 {
     132     1545363 :                     dist_min_fx = dist_fx;
     133     1545363 :                     move32();
     134     1545363 :                     index_split = i;
     135     1545363 :                     move16();
     136             :                 }
     137             :             }
     138             : 
     139             :             /* set quantized vector */
     140      314092 :             cdbk_ptr = &cdbk[imult1616( index_split, split_len )];
     141     2826828 :             FOR( Word16 j = j0; j < j1; ++j )
     142             :             {
     143     2512736 :                 Word32 tmp_3 = L_mult( means[j], means_fix );   // Q16
     144     2512736 :                 Word32 tmp_4 = L_mult( *cdbk_ptr++, cdbk_fix ); // Q16
     145     2512736 :                 snsq_fx[j] = L_add( tmp_4, tmp_3 );             // Q16
     146     2512736 :                 move32();
     147             :             }
     148             : 
     149             :             /* for second split shift by five bits to store both indices as one 10 bit value */
     150      314092 :             if ( EQ_16( split, 1 ) )
     151             :             {
     152      157046 :                 index_split = shl( index_split, 5 );
     153             :             }
     154             : 
     155      314092 :             index = add( index, index_split );
     156             :         }
     157      157046 :         return index;
     158             :     }
     159             :     ELSE
     160             :     {
     161             :         Word16 index, i;
     162      184055 :         const Word16 split_len = M / 2;
     163      184055 :         move16();
     164             :         const Word16 *means;
     165      184055 :         const Word16 means_fix = 2; // Q15
     166      184055 :         move16();
     167             :         /* remove means */
     168      184055 :         means = NULL;
     169      184055 :         SWITCH( L_frame )
     170             :         {
     171       22016 :             case L_FRAME16k:
     172       22016 :                 means = &sns_1st_means_16k[core - 1][0];
     173       22016 :                 break;
     174       50869 :             case L_FRAME25_6k:
     175       50869 :                 means = &sns_1st_means_25k6[core - 1][0];
     176       50869 :                 break;
     177      111170 :             case L_FRAME32k:
     178      111170 :                 means = &sns_1st_means_32k[core - 1][0];
     179      111170 :                 break;
     180           0 :             default:
     181           0 :                 assert( !"illegal frame length in sns_1st_cod" );
     182             :         }
     183      184055 :         Word16 exp_snsq_buffer[M] = { 0 }, exp_snsq = 0;
     184      184055 :         move16();
     185      184055 :         move16();
     186     3128935 :         FOR( i = 0; i < M; ++i )
     187             :         {
     188     2944880 :             Word32 tmp = L_mult( means[i], means_fix ); // Q16
     189     2944880 :             exp_snsq_buffer[i] = 0;
     190     2944880 :             move16();
     191     2944880 :             snsq_fx[i] = BASOP_Util_Add_Mant32Exp( sns_fx[i], exp_sns, L_negate( tmp ), 15, &exp_snsq_buffer[i] );
     192     2944880 :             move32();
     193             :         }
     194     3128935 :         FOR( i = 0; i < M; i++ )
     195             :         {
     196     2944880 :             exp_snsq = s_max( exp_snsq_buffer[i], exp_snsq );
     197             :         }
     198     3128935 :         FOR( i = 0; i < M; i++ )
     199             :         {
     200     2944880 :             snsq_fx[i] = L_shr( snsq_fx[i], exp_snsq - exp_snsq_buffer[i] );
     201     2944880 :             move32();
     202             :         }
     203             : 
     204      184055 :         index = 0;
     205      184055 :         move16();
     206      552165 :         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      368110 :             const Word16 cdbk_fix = 8; // 1.f / powf( 2, SNS_CDBKS_BITS_4_FRAC ) in Q15
     212      368110 :             move16();
     213      368110 :             const Word16 *const cdbk = &sns_1st_cdbk[split][core - 1][0];
     214             : 
     215      368110 :             j0 = imult1616( split, split_len );
     216      368110 :             j1 = add( j0, split_len );
     217             : 
     218      368110 :             cdbk_ptr = cdbk;
     219      368110 :             dist_min_fx = MAXVAL_WORD32;
     220      368110 :             Word16 exp_dist_min = 31;
     221      368110 :             index_split = 0;
     222    12147630 :             FOR( i = 0; i < 32; ++i )
     223             :             {
     224    11779520 :                 Word32 dist_fx = 0;
     225    11779520 :                 move32();
     226    11779520 :                 Word16 exp_dist = 0;
     227    11779520 :                 move16();
     228   106015680 :                 FOR( Word16 j = j0; j < j1; ++j )
     229             :                 {
     230             :                     Word32 tmp_fx;
     231    94236160 :                     Word16 exp_tmp = 0;
     232    94236160 :                     move16();
     233    94236160 :                     Word32 tmp_1 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16
     234    94236160 :                     tmp_fx = BASOP_Util_Add_Mant32Exp( snsq_fx[j], exp_snsq, L_negate( tmp_1 ), 15, &exp_tmp );
     235    94236160 :                     Word32 tmp_2 = Mpy_32_32( tmp_fx, tmp_fx );                                             // exp_tmp*2
     236    94236160 :                     dist_fx = BASOP_Util_Add_Mant32Exp( dist_fx, exp_dist, tmp_2, exp_tmp * 2, &exp_dist ); // exp_tmp*2
     237             :                 }
     238             : 
     239    11779520 :                 IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( dist_fx, exp_dist, dist_min_fx, exp_dist_min ), -1 ) )
     240             :                 {
     241     1826673 :                     dist_min_fx = dist_fx;
     242     1826673 :                     move32();
     243     1826673 :                     exp_dist_min = exp_dist;
     244     1826673 :                     move16();
     245     1826673 :                     index_split = i;
     246     1826673 :                     move16();
     247             :                 }
     248             :             }
     249             : 
     250             :             /* set quantized vector */
     251      368110 :             cdbk_ptr = &cdbk[imult1616( index_split, split_len )];
     252     3312990 :             FOR( Word16 j = j0; j < j1; ++j )
     253             :             {
     254     2944880 :                 Word32 tmp_3 = L_mult( means[j], means_fix );       // Q16
     255     2944880 :                 Word32 tmp_4 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16
     256     2944880 :                 snsq_fx[j] = L_add( tmp_4, tmp_3 );                 // Q16
     257     2944880 :                 move32();
     258             :             }
     259             : 
     260             :             /* for second split shift by five bits to store both indices as one 10 bit value */
     261      368110 :             IF( EQ_16( split, 1 ) )
     262             :             {
     263      184055 :                 index_split = shl( index_split, 5 );
     264             :             }
     265             : 
     266      368110 :             index = add( index, index_split );
     267             :         }
     268             : 
     269      184055 :         return index;
     270             :     }
     271             : }
     272             : 
     273             : /*-------------------------------------------------------------------
     274             :  * sns_2st_cod()
     275             :  *
     276             :  *
     277             :  *-------------------------------------------------------------------*/
     278             : 
     279             : /* r  : number of allocated bits        */
     280      536122 : 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      536122 :     Word16 x_fx[M] = { 0 };
     291      536122 :     move16();
     292             :     Word16 xq_fx[M];
     293      536122 :     Word16 exp_x_buff[M] = { 0 }, exp_x = 0;
     294      536122 :     move16();
     295      536122 :     move16();
     296      536122 :     Word32 scale_fx = 858993472; // Q31
     297      536122 :     move32();
     298             :     Word16 nq;
     299             : 
     300     9114074 :     FOR( i = 0; i < M; i++ )
     301             :     {
     302     8577952 :         Word16 exp_tmp = 0;
     303     8577952 :         move16();
     304     8577952 :         Word32 tmp = BASOP_Util_Add_Mant32Exp( sns_fx[i], exp_sns, L_negate( snsq_fx[i] ), exp_snsq, &exp_tmp );
     305     8577952 :         x_fx[i] = BASOP_Util_Divide3232_Scale( tmp, scale_fx, &exp_x_buff[i] );
     306     8577952 :         move16();
     307     8577952 :         exp_x_buff[i] = add( exp_x_buff[i], exp_tmp );
     308     8577952 :         move16();
     309             :     }
     310     9114074 :     FOR( i = 0; i < M; i++ )
     311             :     {
     312     8577952 :         exp_x = s_max( exp_x, exp_x_buff[i] );
     313             :     }
     314     9114074 :     FOR( i = 0; i < M; i++ )
     315             :     {
     316     8577952 :         x_fx[i] = shr( x_fx[i], sub( ( 15 - Q10 ), exp_x_buff[i] ) );
     317     8577952 :         move16();
     318             :     }
     319             : 
     320             :     /* quantize */
     321      536122 :     AVQ_cod_lpc_fx( x_fx, xq_fx, indx, 2 );
     322     9114074 :     FOR( i = 0; i < M; i++ )
     323             :     {
     324     8577952 :         Word32 tmp_1 = Mpy_32_16_1( scale_fx, xq_fx[i] ); // Q31 + Q10 - 15
     325     8577952 :         tmp_1 = L_shr( tmp_1, 10 );                       // Q16
     326     8577952 :         snsq_fx[i] = L_add( snsq_fx[i], tmp_1 );          // Q16
     327     8577952 :         move32();
     328             :     }
     329             : 
     330             :     /* total number of bits using entropic code to index the quantizer number */
     331      536122 :     nbits = 0;
     332      536122 :     move16();
     333     1608366 :     FOR( i = 0; i < 2; i++ )
     334             :     {
     335     1072244 :         nq = indx[i];
     336     1072244 :         move16();
     337     1072244 :         nbits = add( nbits, ( add( 2, ( shl( nq, 2 ) ) ) ) ); /* 2 bits to specify Q2,Q3,Q4,ext */
     338             : 
     339     1072244 :         IF( GT_16( nq, 6 ) )
     340             :         {
     341         327 :             nbits = add( nbits, sub( nq, 3 ) ); /* unary code (Q7=1110, ...) */
     342             :         }
     343     1071917 :         ELSE IF( GT_16( nq, 4 ) )
     344             :         {
     345       36277 :             nbits = add( nbits, sub( nq, 4 ) ); /* Q5=0, Q6=10 */
     346             :         }
     347     1035640 :         ELSE IF( nq == 0 )
     348             :         {
     349      111292 :             nbits = add( nbits, 3 ); /* Q0=110 */
     350             :         }
     351             :     }
     352             : 
     353      536122 :     return ( nbits );
     354             : }
     355             : 
     356             : /*-------------------------------------------------------------------
     357             :  * sns_avq_cod()
     358             :  *
     359             :  * Stereo noise-shaping AVQ encoder for 1 channel
     360             :  *-------------------------------------------------------------------*/
     361       72776 : 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       72776 :     index[0] = sns_1st_cod_fx( sns_fx, exp_sns, L_frame, core, sns_q_fx );
     379       72776 :     move16();
     380       72776 :     nit = 1 + 2;
     381       72776 :     move16();
     382       72776 :     IF( !low_brate_mode )
     383             :     {
     384       72614 :         nbt = sns_2st_cod_fx( sns_fx, exp_sns, sns_q_fx, 31 - Q16, &index[1] );
     385       72614 :         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       72776 :     index += nit;
     396       72776 :     nit = 0;
     397       72776 :     move16();
     398       72776 :     *index = 0;
     399       72776 :     move16();
     400             : 
     401       72776 :     IF( EQ_16( core, TCX_10_CORE ) )
     402             :     {
     403       11394 :         index++;
     404             : 
     405       11394 :         index[0] = sns_1st_cod_fx( snsmid_fx, exp_snsmid, L_frame, core, snsmid_q_fx );
     406       11394 :         move16();
     407       11394 :         nit = 1 + 2;
     408       11394 :         move16();
     409       11394 :         IF( !low_brate_mode )
     410             :         {
     411       11261 :             nbits = sns_2st_cod_fx( snsmid_fx, exp_snsmid, snsmid_q_fx, 31 - Q16, &index[1] );
     412       11261 :             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       11394 :         nbt = add( 10, nbits );
     426             : 
     427       11394 :         IF( !low_brate_mode )
     428             :         {
     429      191437 :             FOR( i = 0; i < M; i++ )
     430             :             {
     431      180176 :                 snsmid_q0_fx[i] = sns_q_fx[i];
     432      180176 :                 move32();
     433             :             }
     434       11261 :             nbits = sns_2st_cod_fx( snsmid_fx, exp_snsmid, snsmid_q0_fx, 31 - Q16, indxt );
     435             : 
     436       11261 :             IF( LT_16( nbits, nbt ) )
     437             :             {
     438        7178 :                 nbt = nbits;
     439        7178 :                 move16();
     440        7178 :                 nit = add( 2, add( indxt[0], indxt[1] ) );
     441        7178 :                 index[-1] = 1;
     442        7178 :                 move16();
     443             : 
     444      122026 :                 FOR( i = 0; i < M; i++ )
     445             :                 {
     446      114848 :                     snsmid_q_fx[i] = snsmid_q0_fx[i];
     447      114848 :                     move32();
     448             :                 }
     449             : 
     450       61797 :                 FOR( i = 0; i < nit; i++ )
     451             :                 {
     452       54619 :                     index[i] = indxt[i];
     453       54619 :                     move16();
     454             :                 }
     455             :             }
     456             :         }
     457       11394 :         index += nit;
     458             :     }
     459       72776 :     return;
     460             : }
     461             : 
     462             : /*-------------------------------------------------------------------
     463             :  * sns_avq_cod_stereo()
     464             :  *
     465             :  * Stereo noise-shaping AVQ encoder for 2 channels
     466             :  *-------------------------------------------------------------------*/
     467             : 
     468      220493 : 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      220493 :     Word16 exp_ener_side = 0, exp_side_buffer[M] = { 0 }, exp_side = MIN16B;
     483      220493 :     move16();
     484      220493 :     move16();
     485      220493 :     move16();
     486             : 
     487             :     /* Compute side */
     488      220493 :     ener_side_fx = 0;
     489      220493 :     move16();
     490     3748381 :     FOR( i = 0; i < M; i++ )
     491             :     {
     492     3527888 :         side_fx[i] = BASOP_Util_Add_Mant32Exp( snsl_fx[i], exp_snl, L_negate( snsr_fx[i] ), exp_snr, &exp_side_buffer[i] );
     493     3527888 :         move32();
     494     3527888 :         Word32 tmp = Mpy_32_32( side_fx[i], side_fx[i] ); // exp_side[i] * 2
     495     3527888 :         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     3748381 :     FOR( i = 0; i < M; i++ )
     498             :     {
     499     3527888 :         exp_side = s_max( exp_side, exp_side_buffer[i] );
     500             :     }
     501     3748381 :     FOR( i = 0; i < M; i++ )
     502             :     {
     503     3527888 :         side_fx[i] = L_shr( side_fx[i], exp_side - exp_side_buffer[i] );
     504     3527888 :         move32();
     505             :     }
     506             : 
     507      220493 :     Word16 flag = BASOP_Util_Cmp_Mant32Exp( ener_side_fx, exp_ener_side, 24576, 31 - Q11 );
     508      220493 :     IF( EQ_16( flag, -1 ) )
     509             :     {
     510             :         /* MS coding */
     511      184055 :         *indexl++ = 2;
     512      184055 :         move16();
     513      184055 :         *indexr++ = 3;
     514      184055 :         move16();
     515             : 
     516             :         /* Compute mid */
     517      184055 :         Word16 exp_mid_buffer[M] = { 0 };
     518      184055 :         move16();
     519     3128935 :         FOR( i = 0; i < M; i++ )
     520             :         {
     521     2944880 :             mid_fx[i] = BASOP_Util_Add_Mant32Exp( snsl_fx[i], exp_snl, snsr_fx[i], exp_snr, &exp_mid_buffer[i] );
     522     2944880 :             move32();
     523     2944880 :             mid_fx[i] = L_shr( mid_fx[i], 1 );
     524     2944880 :             move32();
     525             :         }
     526             : 
     527             :         /* Quantize mid */
     528      184055 :         Word16 exp_mid = 0;
     529      184055 :         move16();
     530     3128935 :         FOR( i = 0; i < M; i++ )
     531             :         {
     532     2944880 :             exp_mid = s_max( exp_mid, exp_mid_buffer[i] );
     533             :         }
     534     3128935 :         FOR( i = 0; i < M; i++ )
     535             :         {
     536     2944880 :             mid_fx[i] = L_shr( mid_fx[i], exp_mid - exp_mid_buffer[i] );
     537     2944880 :             move32();
     538             :         }
     539      184055 :         indexl[0] = sns_1st_cod_fx( mid_fx, exp_mid, L_frame, TCX_20_CORE, mid_q_fx );
     540      184055 :         move16();
     541      184055 :         sns_2st_cod_fx( mid_fx, exp_mid, mid_q_fx, ( 31 - Q16 ), &indexl[1] );
     542             : 
     543             :         /* Quantize side */
     544      184055 :         indexr[0] = -1;
     545      184055 :         move16();
     546     3128935 :         FOR( i = 0; i < M; i++ )
     547             :         {
     548     2944880 :             side_q_fx[i] = 0;
     549     2944880 :             move32();
     550             :         }
     551      184055 :         sns_2st_cod_fx( side_fx, exp_side, side_q_fx, 31 - Q16, &indexr[1] );
     552             : 
     553             :         /* Detect zero side */
     554      184055 :         flag_zero = 1;
     555      184055 :         move16();
     556      616048 :         FOR( i = 0; i < M; i++ )
     557             :         {
     558      596239 :             if ( side_q_fx[i] != 0 )
     559             :             {
     560      164246 :                 flag_zero = 0;
     561      164246 :                 move16();
     562      164246 :                 break;
     563             :             }
     564             :         }
     565      184055 :         if ( flag_zero )
     566             :         {
     567       19809 :             indexr[0] = -2;
     568       19809 :             move16();
     569             :         }
     570             : 
     571             :         /* Go back to LR */
     572     3128935 :         FOR( i = 0; i < M; i++ )
     573             :         {
     574     2944880 :             Word32 a = L_shr( side_q_fx[i], 1 );
     575     2944880 :             snsl_q_fx[i] = L_add( mid_q_fx[i], a );
     576     2944880 :             move32();
     577     2944880 :             snsr_q_fx[i] = L_sub( mid_q_fx[i], a );
     578     2944880 :             move32();
     579             :         }
     580             :     }
     581             :     ELSE
     582             :     {
     583             :         /* LR coding */
     584       36438 :         *indexl++ = 0;
     585       36438 :         move16();
     586       36438 :         *indexr++ = 1;
     587       36438 :         move16();
     588             : 
     589             :         /* Quantize left */
     590       36438 :         indexl[0] = sns_1st_cod_fx( snsl_fx, exp_snl, L_frame, TCX_20_CORE, snsl_q_fx );
     591       36438 :         move16();
     592       36438 :         sns_2st_cod_fx( snsl_fx, exp_snl, snsl_q_fx, ( 31 - Q16 ), &indexl[1] );
     593             : 
     594             :         /* Quantize right */
     595       36438 :         indexr[0] = sns_1st_cod_fx( snsr_fx, exp_snr, L_frame, TCX_20_CORE, snsr_q_fx );
     596       36438 :         move16();
     597       36438 :         sns_2st_cod_fx( snsr_fx, exp_snr, snsr_q_fx, ( 31 - Q16 ), &indexr[1] );
     598             :     }
     599      220493 :     return;
     600             : }
     601       47977 : 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       47977 :     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       47977 :     nbits = 0;
     618       47977 :     move16();
     619       47977 :     idxIndices = 0;
     620       47977 :     move16();
     621       47977 :     set16_fx( weights_fx, ONE_IN_Q8, M );
     622             : 
     623       47977 :     sns_stereo_mode[0] = SNS_STEREO_MODE_LR;
     624       47977 :     move16();
     625       47977 :     sns_stereo_mode[1] = SNS_STEREO_MODE_LR;
     626       47977 :     move16();
     627       47977 :     zero_side_flag[0] = 0;
     628       47977 :     move16();
     629       47977 :     zero_side_flag[1] = 0;
     630       47977 :     move16();
     631             : 
     632             :     /* use snsQ_out as buffer, move input vectors */
     633      143931 :     FOR( ch = 0; ch < CPE_CHANNELS; ++ch )
     634             :     {
     635       95954 :         IF( EQ_16( sts[ch]->core, TCX_20_CORE ) )
     636             :         {
     637       93608 :             nSubframes = 1;
     638             :         }
     639             :         ELSE
     640             :         {
     641        2346 :             nSubframes = NB_DIV;
     642             :         }
     643       95954 :         move16();
     644             : 
     645      194254 :         FOR( k = 0; k < nSubframes; ++k )
     646             :         {
     647       98300 :             Copy32( sns_in_fx[ch][k], snsQ_out_fx[ch][k], M ); // sns_e
     648             :         }
     649             : 
     650       95954 :         sns_e_tmp[ch][0] = sns_e;
     651       95954 :         move16();
     652       95954 :         sns_e_tmp[ch][1] = sns_e;
     653       95954 :         move16();
     654             :     }
     655             : 
     656             :     /* stereo mode decision */
     657       47977 :     IF( EQ_16( sts[0]->core, sts[1]->core ) )
     658             :     {
     659       47653 :         IF( EQ_16( sts[0]->core, TCX_20_CORE ) )
     660             :         {
     661       46642 :             nSubframes = 1;
     662             :         }
     663             :         ELSE
     664             :         {
     665        1011 :             nSubframes = NB_DIV;
     666             :         }
     667       47653 :         move16();
     668             : 
     669       96317 :         FOR( k = 0; k < nSubframes; ++k )
     670             :         {
     671             :             Word32 side_fx[M];
     672             :             Word32 ener_side_fx;
     673             :             Word16 ener_side_q;
     674             : 
     675             : #ifdef VEC_ARITH_OPT_v1
     676       48664 :             v_sub_fixed_no_hdrm( snsQ_out_fx[0][k], snsQ_out_fx[1][k], side_fx, M );
     677             : #else  /* VEC_ARITH_OPT_v1 */
     678             :             v_sub_fixed( snsQ_out_fx[0][k], snsQ_out_fx[1][k], side_fx, M, 0 );
     679             : #endif /* VEC_ARITH_OPT_v1 */
     680             : 
     681             :             Word64 L64_sum;
     682       48664 :             L64_sum = 1;
     683       48664 :             move64();
     684      827288 :             FOR( i = 0; i < M; i++ )
     685             :             {
     686      778624 :                 L64_sum = W_mac_32_32( L64_sum, side_fx[i], side_fx[i] );
     687             :             }
     688       48664 :             i = W_norm( L64_sum );
     689       48664 :             L64_sum = W_shl( L64_sum, i );
     690       48664 :             ener_side_fx = W_extract_h( L64_sum ); // ener_side_q
     691       48664 :             ener_side_q = sub( add( shl( sub( 31, sns_e ), 1 ), add( 1, i ) ), 32 );
     692             : 
     693       48664 :             sns_stereo_mode[k] = 0;
     694       48664 :             move16();
     695       48664 :             zero_side_flag[k] = 0;
     696       48664 :             move16();
     697             : 
     698       48664 :             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 ) ) ) )
     699             :             {
     700       45454 :                 sns_stereo_mode[k] = 1;
     701       45454 :                 move16();
     702             :             }
     703             : 
     704       48664 :             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 ) ) ) )
     705             :             {
     706        9478 :                 zero_side_flag[k] = 1;
     707        9478 :                 move16();
     708             :             }
     709             : 
     710             : 
     711       48664 :             IF( EQ_16( sns_stereo_mode[k], SNS_STEREO_MODE_MS ) )
     712             :             {
     713       45454 :                 convertToMS_fx( M, snsQ_out_fx[0][k], snsQ_out_fx[1][k], ONE_IN_Q30 );
     714             :             }
     715             :         }
     716             :     }
     717             : 
     718             :     /* run MSVQ */
     719      143931 :     FOR( ch = 0; ch < CPE_CHANNELS; ++ch )
     720             :     {
     721       95954 :         st = sts[ch];
     722       95954 :         IF( EQ_16( st->core, TCX_20_CORE ) )
     723             :         {
     724       93608 :             nSubframes = 1;
     725             :         }
     726             :         ELSE
     727             :         {
     728        2346 :             nSubframes = NB_DIV;
     729             :         }
     730       95954 :         move16();
     731             : 
     732      194254 :         FOR( k = 0; k < nSubframes; ++k )
     733             :         {
     734       98300 :             Word16 is_side = 0;
     735       98300 :             move16();
     736       98300 :             IF( EQ_16( ch, 1 ) && EQ_16( sns_stereo_mode[k], SNS_STEREO_MODE_MS ) )
     737             :             {
     738       45454 :                 is_side = 1;
     739       45454 :                 move16();
     740             :             }
     741             : 
     742             :             const Word16 *const *cdbks_fx;
     743             :             const Word16 *levels;
     744             :             const Word16 *bits;
     745             :             Word16 nStages;
     746       98300 :             IF( EQ_16( nSubframes, 1 ) )
     747             :             {
     748       93608 :                 cdbks_fx = ivas_sns_cdbks_tcx20_fx;
     749       93608 :                 levels = ivas_sns_cdbks_tcx20_levels;
     750       93608 :                 bits = ivas_sns_cdbks_tcx20_bits;
     751       93608 :                 nStages = SNS_MSVQ_NSTAGES_TCX20;
     752             :             }
     753             :             ELSE
     754             :             {
     755        4692 :                 cdbks_fx = ivas_sns_cdbks_tcx10_fx;
     756        4692 :                 levels = ivas_sns_cdbks_tcx10_levels;
     757        4692 :                 bits = ivas_sns_cdbks_tcx10_bits;
     758        4692 :                 nStages = SNS_MSVQ_NSTAGES_TCX10;
     759             :             }
     760       98300 :             move16();
     761             : 
     762       98300 :             Word32 *snsQ_fx = snsQ_out_fx[ch][k];
     763       98300 :             const Word32 *sns_ptr_fx = snsQ_out_fx[ch][k];
     764             : 
     765       98300 :             IF( is_side )
     766             :             {
     767             :                 const Word16 *const *side_cdbks_fx;
     768             :                 const Word16 *side_levels;
     769             : 
     770       45454 :                 IF( EQ_16( st->core, TCX_20_CORE ) )
     771             :                 {
     772       43625 :                     side_cdbks_fx = ivas_sns_cdbks_side_tcx20_fx;
     773       43625 :                     side_levels = ivas_sns_cdbks_side_tcx20_levels;
     774       43625 :                     bits = ivas_sns_cdbks_side_tcx20_bits;
     775             :                 }
     776             :                 ELSE
     777             :                 {
     778        1829 :                     side_cdbks_fx = ivas_sns_cdbks_side_tcx10_fx;
     779        1829 :                     side_levels = ivas_sns_cdbks_side_tcx10_levels;
     780        1829 :                     bits = ivas_sns_cdbks_side_tcx10_bits;
     781             :                 }
     782             : 
     783             : 
     784       45454 :                 IF( zero_side_flag[k] )
     785             :                 {
     786        9478 :                     set32_fx( snsQ_fx, 0, M );
     787        9478 :                     CONTINUE;
     788             :                 }
     789             : 
     790       35976 :                 nStages = SNS_MSVQ_NSTAGES_SIDE;
     791       35976 :                 move16();
     792             : 
     793       35976 :                 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] );
     794       35976 :                 msvq_dec_fx( side_cdbks_fx, NULL, NULL, nStages, M, M, &indices[idxIndices], 0, NULL, snsQ_fx, NULL, Q15 );
     795             :             }
     796             :             ELSE
     797             :             {
     798       52846 :                 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] );
     799       52846 :                 msvq_dec_fx( cdbks_fx, NULL, NULL, nStages, M, M, &indices[idxIndices], 0, NULL, snsQ_fx, NULL, Q12 );
     800             :             }
     801       88822 :             Word16 shift = find_guarded_bits_fx( M );
     802       88822 :             sns_e_tmp[ch][k] = sub( 31, sub( 20, shift ) );
     803       88822 :             move16();
     804       88822 :             idxIndices = add( idxIndices, nStages );
     805             : 
     806      369295 :             FOR( i = 0; i < nStages; ++i )
     807             :             {
     808      280473 :                 nbits = add( nbits, bits[i] );
     809             :             }
     810             :         }
     811             :     }
     812             :     /* Re-Scaling Buffers*/
     813       47977 :     sns_e = sns_e_tmp[0][0];
     814       47977 :     move16();
     815             : 
     816      143931 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
     817             :     {
     818       95954 :         sns_e = s_max( sns_e, sns_e_tmp[ch][0] );
     819       95954 :         sns_e = s_max( sns_e, sns_e_tmp[ch][1] );
     820             :     }
     821             : 
     822      143931 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
     823             :     {
     824      194254 :         FOR( k = 0; k < nSubframes; k++ )
     825             :         {
     826       98300 :             scale_sig32( snsQ_out_fx[ch][k], M, sub( sns_e_tmp[ch][k], sns_e ) ); // Q(31-sns_e_tmp[ch][k])
     827             :         }
     828             :     }
     829             :     /* get back to L/F representation */
     830       47977 :     test();
     831       47977 :     IF( EQ_16( sns_stereo_mode[0], SNS_STEREO_MODE_MS ) || EQ_16( sns_stereo_mode[1], SNS_STEREO_MODE_MS ) )
     832             :     {
     833       44580 :         IF( EQ_16( sts[0]->core, TCX_20_CORE ) )
     834             :         {
     835       43625 :             nSubframes = 1;
     836             :         }
     837             :         ELSE
     838             :         {
     839         955 :             nSubframes = NB_DIV;
     840             :         }
     841       44580 :         move16();
     842             : 
     843       90115 :         FOR( k = 0; k < nSubframes; ++k )
     844             :         {
     845       45535 :             IF( EQ_16( sns_stereo_mode[k], SNS_STEREO_MODE_MS ) )
     846             :             {
     847       45454 :                 convertToMS_fx( M, snsQ_out_fx[0][k], snsQ_out_fx[1][k], ONE_IN_Q31 );
     848             :             }
     849             :         }
     850             :     }
     851             : 
     852       47977 :     return nbits;
     853             : }

Generated by: LCOV version 1.14