LCOV - code coverage report
Current view: top level - lib_com - ivas_omasa_com_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 301 331 90.9 %
Date: 2025-05-03 01:55:50 Functions: 10 10 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 "options.h"
      34             : #include <stdlib.h>
      35             : #include "ivas_cnst.h"
      36             : #include "ivas_prot_fx.h"
      37             : #include "prot_fx.h"
      38             : #include "ivas_rom_com.h"
      39             : #include "rom_com.h"
      40             : #include <math.h>
      41             : 
      42             : /*---------------------------------------------------------------
      43             :  * Local constants
      44             :  *---------------------------------------------------------------*/
      45             : 
      46             : #define GAMMA_ISM_LOW_IMP_FX    26215 /*0.8f in Q15*/
      47             : #define GAMMA_ISM_MEDIUM_IMP_FX 39322 /*1.2f in Q15*/
      48             : #define GAMMA_ISM_HIGH_IMP_FX   45876 /*1.4f in Q15*/
      49             : 
      50             : #define GAMMA_ISM_LOW_IMP2_FX    29492 /*0.9f in Q15*/
      51             : #define GAMMA_ISM_MEDIUM_IMP2_FX 39322 /*1.2f in Q15*/
      52             : #define GAMMA_ISM_HIGH_IMP2_FX   44237 /*1.35f in Q15*/
      53             : 
      54             : #define GAMMA_ISM_LOW_IMP3_FX    27853 /*0.85f in Q15*/
      55             : #define GAMMA_ISM_MEDIUM_IMP3_FX 37684 /*1.15f in Q15*/
      56             : #define GAMMA_ISM_HIGH_IMP3_FX   42599 /*1.3f in Q15*/
      57             : 
      58             : #define GAMMA_ISM_LOW_IMP4_FX    26215 /*0.8f in Q15*/
      59             : #define GAMMA_ISM_MEDIUM_IMP4_FX 32768 /*1.0f in Q15*/
      60             : #define GAMMA_ISM_HIGH_IMP4_FX   39322 /*1.2f in Q15*/
      61             : 
      62             : /*---------------------------------------------------------------
      63             :  * ivas_omasa_ism_mode_select()
      64             :  *
      65             :  * selects the ISM mode base on IVAS total bit-rate and
      66             :  * the number of objects in the combined ISM MASA format mode
      67             :  * ---------------------------------------------------------------*/
      68             : 
      69             : /*! r : ISM format mode */
      70       18320 : ISM_MODE ivas_omasa_ism_mode_select_fx(
      71             :     const Word32 ivas_total_brate, /* i  : IVAS total bitrate      */
      72             :     const Word16 nchan_ism         /* i  : number of input ISM's   */
      73             : )
      74             : {
      75       18320 :     ISM_MODE ism_mode = ISM_MODE_NONE;
      76       18320 :     move32();
      77             : 
      78       18320 :     SWITCH( nchan_ism )
      79             :     {
      80        1720 :         case 1:
      81        1720 :             IF( GE_32( ivas_total_brate, IVAS_24k4 ) )
      82             :             {
      83        1422 :                 ism_mode = ISM_MASA_MODE_DISC;
      84        1422 :                 move32();
      85             :             }
      86             :             ELSE
      87             :             {
      88         298 :                 ism_mode = ISM_MODE_NONE;
      89         298 :                 move32();
      90             :             }
      91        1720 :             BREAK;
      92        1752 :         case 2:
      93        1752 :             IF( GE_32( ivas_total_brate, IVAS_48k ) )
      94             :             {
      95         957 :                 ism_mode = ISM_MASA_MODE_DISC;
      96         957 :                 move32();
      97             :             }
      98         795 :             ELSE IF( GE_32( ivas_total_brate, IVAS_32k ) )
      99             :             {
     100         495 :                 ism_mode = ISM_MASA_MODE_PARAM_ONE_OBJ;
     101         495 :                 move32();
     102             :             }
     103             :             ELSE
     104             :             {
     105         300 :                 ism_mode = ISM_MODE_NONE;
     106         300 :                 move32();
     107             :             }
     108        1752 :             BREAK;
     109        7369 :         case 3:
     110        7369 :             IF( GE_32( ivas_total_brate, IVAS_96k ) )
     111             :             {
     112        2326 :                 ism_mode = ISM_MASA_MODE_DISC;
     113        2326 :                 move32();
     114             :             }
     115        5043 :             ELSE IF( GE_32( ivas_total_brate, IVAS_64k ) )
     116             :             {
     117        1684 :                 ism_mode = ISM_MASA_MODE_PARAM_ONE_OBJ;
     118        1684 :                 move32();
     119             :             }
     120        3359 :             ELSE IF( GE_32( ivas_total_brate, IVAS_32k ) )
     121             :             {
     122        2303 :                 ism_mode = ISM_MASA_MODE_MASA_ONE_OBJ;
     123        2303 :                 move32();
     124             :             }
     125             :             ELSE
     126             :             {
     127        1056 :                 ism_mode = ISM_MODE_NONE;
     128        1056 :                 move32();
     129             :             }
     130        7369 :             BREAK;
     131        7479 :         case 4:
     132        7479 :             IF( GE_32( ivas_total_brate, IVAS_128k ) )
     133             :             {
     134        1975 :                 ism_mode = ISM_MASA_MODE_DISC;
     135        1975 :                 move32();
     136             :             }
     137        5504 :             ELSE IF( GE_32( ivas_total_brate, IVAS_64k ) )
     138             :             {
     139        2002 :                 ism_mode = ISM_MASA_MODE_PARAM_ONE_OBJ;
     140        2002 :                 move32();
     141             :             }
     142        3502 :             ELSE IF( GE_32( ivas_total_brate, IVAS_32k ) )
     143             :             {
     144        2410 :                 ism_mode = ISM_MASA_MODE_MASA_ONE_OBJ;
     145        2410 :                 move32();
     146             :             }
     147             :             ELSE
     148             :             {
     149        1092 :                 ism_mode = ISM_MODE_NONE;
     150        1092 :                 move32();
     151             :             }
     152        7479 :             BREAK;
     153             :     }
     154             : 
     155       18320 :     return ism_mode;
     156             : }
     157             : 
     158             : /*---------------------------------------------------------------
     159             :  * ivas_set_omasa_TC()
     160             :  *
     161             :  * set number of transport channels in OMASA format
     162             :  * ---------------------------------------------------------------*/
     163             : 
     164        3138 : void ivas_set_omasa_TC_fx(
     165             :     const ISM_MODE ism_mode, /* i  : ISM mode                   */
     166             :     const Word16 nchan_ism,  /* i  : number of input ISMs       */
     167             :     Word16 *nSCE,            /* o  : number of SCEs             */
     168             :     Word16 *nCPE             /* o  : number of CPEs             */
     169             : )
     170             : {
     171        3138 :     SWITCH( ism_mode )
     172             :     {
     173        1446 :         case ISM_MASA_MODE_MASA_ONE_OBJ:
     174             :         case ISM_MASA_MODE_PARAM_ONE_OBJ:
     175        1446 :             *nCPE = 1;
     176        1446 :             move16();
     177        1446 :             *nSCE = 1;
     178        1446 :             move16();
     179        1446 :             BREAK;
     180         847 :         case ISM_MASA_MODE_DISC:
     181         847 :             *nCPE = 1;
     182         847 :             move16();
     183         847 :             *nSCE = nchan_ism;
     184         847 :             move16();
     185         847 :             BREAK;
     186         845 :         case ISM_MODE_NONE:
     187         845 :             *nCPE = 1;
     188         845 :             move16();
     189         845 :             *nSCE = 0;
     190         845 :             move16();
     191         845 :             BREAK;
     192           0 :         default:
     193           0 :             BREAK;
     194             :     }
     195             : 
     196        3138 :     return;
     197             : }
     198             : 
     199             : /*---------------------------------------------------------------
     200             :  * ivas_interformat_brate()
     201             :  *
     202             :  * Bit-budget distribution in case of combined-format coding
     203             :  * ---------------------------------------------------------------*/
     204             : 
     205             : /*! r: adjusted bitrate */
     206       25221 : Word32 ivas_interformat_brate_fx(
     207             :     const ISM_MODE ism_mode,    /* i  : ISM mode                           */
     208             :     const Word16 nchan_ism,     /* i  : number of ISM channels             */
     209             :     const Word32 element_brate, /* i  : element bitrate                    */
     210             :     const Word16 ism_imp,       /* i  : ISM importance flag                */
     211             :     const Word16 limit_flag     /* i  : flag to limit the bitrate increase */
     212             : )
     213             : {
     214             :     Word32 element_brate_out;
     215             :     Word16 nBits, limit_low, limit_high;
     216             : 
     217       25221 :     nBits = extract_l( Mpy_32_32( element_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) ); /* Q0 */
     218             : 
     219       25221 :     IF( ism_imp == ISM_INACTIVE_IMP )
     220             :     {
     221           0 :         nBits = BITS_ISM_INACTIVE;
     222           0 :         move16();
     223             :     }
     224             :     ELSE
     225             :     {
     226       25221 :         test();
     227       25221 :         test();
     228       25221 :         test();
     229       25221 :         test();
     230       25221 :         test();
     231       25221 :         test();
     232       25221 :         test();
     233       25221 :         test();
     234       25221 :         test();
     235       25221 :         IF( EQ_16( ism_mode, ISM_MASA_MODE_DISC ) && ( ( EQ_16( nchan_ism, 4 ) && EQ_32( element_brate, 24000 ) ) || ( EQ_16( nchan_ism, 3 ) && LE_32( element_brate, 24000 ) ) || ( EQ_16( nchan_ism, 2 ) && LE_32( element_brate, 11000 ) ) ) ) /* for border case in DISC mode */
     236             :         {
     237        3491 :             test();
     238        3491 :             test();
     239        3491 :             test();
     240        3491 :             test();
     241        3491 :             test();
     242        3491 :             test();
     243        3491 :             IF( EQ_16( limit_flag, 1 ) && ( ( EQ_16( nchan_ism, 4 ) && EQ_32( element_brate, 24000 ) ) || ( EQ_16( nchan_ism, 3 ) && EQ_32( element_brate, 20000 ) ) || ( EQ_16( nchan_ism, 2 ) && LE_32( element_brate, 11000 ) ) ) )
     244             :             {
     245        3006 :                 return element_brate;
     246             :             }
     247             : 
     248         485 :             IF( EQ_16( ism_imp, ISM_LOW_IMP ) )
     249             :             {
     250          36 :                 nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_LOW_IMP4_FX, nBits ) );
     251             :             }
     252         449 :             ELSE IF( EQ_16( ism_imp, ISM_MEDIUM_IMP ) )
     253             :             {
     254         152 :                 nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_MEDIUM_IMP4_FX, nBits ) );
     255         152 :                 IF( EQ_16( limit_flag, -1 ) )
     256             :                 {
     257           0 :                     nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_HIGH_IMP4_FX, nBits ) );
     258             :                 }
     259             :             }
     260             :             ELSE /* ISM_HIGH_IMP */
     261             :             {
     262         297 :                 nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_HIGH_IMP4_FX, nBits ) );
     263         297 :                 IF( EQ_16( limit_flag, -1 ) )
     264             :                 {
     265           0 :                     nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_HIGH_IMP4_FX, nBits ) );
     266             :                 }
     267             :             }
     268             :         }
     269       21730 :         ELSE IF( EQ_16( ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) ||
     270             :                  ( EQ_16( ism_mode, ISM_MASA_MODE_DISC ) && EQ_32( element_brate, 9600 ) ) /* this condition corresponds to the ivas_total_brate = 24400 and 1 object */
     271             :         )
     272             :         {
     273        5363 :             test();
     274        5363 :             IF( EQ_16( ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) && EQ_32( element_brate, IVAS_13k2 ) )
     275             :             {
     276         702 :                 IF( EQ_16( ism_imp, ISM_LOW_IMP ) )
     277             :                 {
     278          20 :                     nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_LOW_IMP3_FX, nBits ) );
     279             :                 }
     280         682 :                 ELSE IF( EQ_16( ism_imp, ISM_MEDIUM_IMP ) )
     281             :                 {
     282         172 :                     nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_MEDIUM_IMP3_FX, nBits ) );
     283             :                 }
     284             :                 ELSE /* ISM_HIGH_IMP */
     285             :                 {
     286         510 :                     nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_HIGH_IMP4_FX, nBits ) );
     287             :                 }
     288             :             }
     289             :             ELSE
     290             :             {
     291        4661 :                 IF( EQ_16( ism_imp, ISM_LOW_IMP ) )
     292             :                 {
     293         116 :                     nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_LOW_IMP3_FX, nBits ) );
     294             :                 }
     295        4545 :                 ELSE IF( EQ_16( ism_imp, ISM_MEDIUM_IMP ) )
     296             :                 {
     297        1282 :                     nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_MEDIUM_IMP3_FX, nBits ) );
     298             :                 }
     299             :                 ELSE /* ISM_HIGH_IMP */
     300             :                 {
     301        3263 :                     nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_HIGH_IMP3_FX, nBits ) );
     302             :                 }
     303             :             }
     304             :         }
     305       16367 :         ELSE IF( EQ_16( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) && EQ_32( element_brate, 16000 ) )
     306             :         {
     307        1875 :             IF( EQ_16( ism_imp, ISM_LOW_IMP ) )
     308             :             {
     309          56 :                 nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_LOW_IMP_FX, nBits ) );
     310             :             }
     311        1819 :             ELSE IF( EQ_16( ism_imp, ISM_MEDIUM_IMP ) )
     312             :             {
     313         545 :                 nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_MEDIUM_IMP_FX, nBits ) );
     314             :             }
     315             :             ELSE /* ISM_HIGH_IMP */
     316             :             {
     317        1274 :                 nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_HIGH_IMP3_FX, nBits ) );
     318             :             }
     319             :         }
     320             :         ELSE
     321             :         {
     322       14492 :             IF( EQ_16( ism_imp, ISM_LOW_IMP ) )
     323             :             {
     324         626 :                 nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_LOW_IMP_FX, nBits ) );
     325             :             }
     326       13866 :             ELSE IF( EQ_16( ism_imp, ISM_MEDIUM_IMP ) )
     327             :             {
     328        3740 :                 nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_MEDIUM_IMP_FX, nBits ) );
     329             :             }
     330             :             ELSE /* ISM_HIGH_IMP */
     331             :             {
     332       10126 :                 nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_HIGH_IMP_FX, nBits ) );
     333             :             }
     334             :         }
     335             :     }
     336             : 
     337       22215 :     limit_low = MIN_BRATE_SWB_BWE / FRAMES_PER_SEC;
     338       22215 :     move16();
     339       22215 :     IF( ism_imp == ISM_INACTIVE_IMP )
     340             :     {
     341           0 :         limit_low = BITS_ISM_INACTIVE;
     342           0 :         move16();
     343             :     }
     344       22215 :     ELSE IF( GE_32( element_brate, SCE_CORE_16k_LOW_LIMIT ) )
     345             :     {
     346       15441 :         limit_low = SCE_CORE_16k_LOW_LIMIT / FRAMES_PER_SEC;
     347       15441 :         move16();
     348             :     }
     349             : 
     350       22215 :     limit_high = IVAS_512k / FRAMES_PER_SEC;
     351       22215 :     move16();
     352       22215 :     IF( LE_32( element_brate, SCE_CORE_16k_LOW_LIMIT ) )
     353             :     {
     354        6774 :         limit_high = ACELP_12k8_HIGH_LIMIT / FRAMES_PER_SEC;
     355        6774 :         move16();
     356             :     }
     357             : 
     358       22215 :     nBits = check_bounds_s_fx( nBits, limit_low, limit_high );
     359             : 
     360       22215 :     element_brate_out = L_mult0( nBits, FRAMES_PER_SEC );
     361             : 
     362       22215 :     return element_brate_out;
     363             : }
     364             : 
     365             : /*---------------------------------------------------------------
     366             :  * ivas_combined_format_brate_sanity()
     367             :  *
     368             :  * Sanity check in combined format coding
     369             :  * ---------------------------------------------------------------*/
     370             : 
     371         228 : void ivas_combined_format_brate_sanity_fx(
     372             :     const Word32 element_brate,       /* i  : element bitrate                */
     373             :     const Word16 core,                /* i  : core                           */
     374             :     const Word32 total_brate,         /* i  : total bitrate                  */
     375             :     Word32 *core_brate,               /* i/o: core bitrate                   */
     376             :     Word16 *inactive_coder_type_flag, /* o  : inactive coder_type flag       */
     377             :     Word16 *diff_nBits                /* o  : number of differential bits    */
     378             : )
     379             : {
     380             :     Word16 limit_high, nBits;
     381             :     Word32 brate_diff;
     382             : 
     383         228 :     brate_diff = L_sub( total_brate, *core_brate );
     384             : 
     385             :     /* sanity check: at lowest IVAS bit-rates and one ISM channel coded by
     386             :     low-rate core-coder mode, it can happen that the CPE (MASA) bit-budget
     387             :     for ACELP core-coding @12.8 kHz is too high */
     388             : 
     389         228 :     IF( LT_32( element_brate, ACELP_12k8_HIGH_LIMIT ) )
     390             :     {
     391          70 :         limit_high = ACELP_12k8_HIGH_LIMIT / FRAMES_PER_SEC;
     392          70 :         move16();
     393          70 :         nBits = extract_l( Mpy_32_32( *core_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) );
     394             : 
     395          70 :         *diff_nBits = sub( nBits, limit_high );
     396          70 :         move16();
     397          70 :         IF( *diff_nBits > 0 )
     398             :         {
     399           0 :             test();
     400           0 :             IF( EQ_16( core, TCX_20_CORE ) || EQ_16( core, TCX_10_CORE ) )
     401             :             {
     402           0 :                 *diff_nBits = 0;
     403           0 :                 move16();
     404             :             }
     405             :             ELSE /* ACELP core */
     406             :             {
     407           0 :                 *core_brate = L_sub( *core_brate, L_mult0( *diff_nBits, FRAMES_PER_SEC ) );
     408           0 :                 move32();
     409             :             }
     410             :         }
     411             :     }
     412             : 
     413             :     /*-----------------------------------------------------------------*
     414             :      * set inactive coder_type flag in ACELP core
     415             :      *-----------------------------------------------------------------*/
     416             : 
     417         228 :     IF( core == ACELP_CORE )
     418             :     {
     419          96 :         *inactive_coder_type_flag = 0; /* AVQ by default */
     420          96 :         move16();
     421          96 :         if ( LE_32( L_add( *core_brate, brate_diff ), MAX_GSC_INACTIVE_BRATE ) )
     422             :         {
     423          74 :             *inactive_coder_type_flag = 1; /* GSC */
     424          74 :             move16();
     425             :         }
     426             :     }
     427             : 
     428         228 :     return;
     429             : }
     430             : 
     431             : 
     432             : /*---------------------------------------------------------------
     433             :  * bits_index_ism_ratio()
     434             :  *
     435             :  *
     436             :  * ---------------------------------------------------------------*/
     437             : 
     438             : /*!r : number of bits for ISM ratio index */
     439        3415 : Word16 bits_index_ism_ratio_fx(
     440             :     const Word16 nchan_ism /* i  : number of objects    */
     441             : )
     442             : {
     443             :     Word16 bits_index;
     444             : 
     445        3415 :     bits_index = 0;
     446        3415 :     move16();
     447        3415 :     IF( EQ_16( nchan_ism, 2 ) )
     448             :     {
     449         404 :         bits_index = 3;
     450         404 :         move16();
     451             :     }
     452        3011 :     ELSE IF( EQ_16( nchan_ism, 3 ) )
     453             :     {
     454        1318 :         bits_index = 6;
     455        1318 :         move16();
     456             :     }
     457        1693 :     ELSE IF( EQ_16( nchan_ism, 4 ) )
     458             :     {
     459        1693 :         bits_index = 7;
     460        1693 :         move16();
     461             :     }
     462             :     ELSE
     463             :     {
     464           0 :         assert( ( nchan_ism >= 2 && nchan_ism <= 4 ) && "Wrong number of objects for MASA_ISM." );
     465             :     }
     466             : 
     467        3415 :     return bits_index;
     468             : }
     469             : 
     470             : /*---------------------------------------------------------------
     471             :  * calculate_nbits_meta()
     472             :  *
     473             :  *
     474             :  * ---------------------------------------------------------------*/
     475             : 
     476       11626 : static Word16 get_bits_ism_fx(
     477             :     Word32 val // Q29
     478             : )
     479             : {
     480             :     Word16 res;
     481       11626 :     test();
     482       11626 :     test();
     483       11626 :     test();
     484       11626 :     test();
     485       11626 :     test();
     486       11626 :     test();
     487             :     /* Considering only 3 points after decimal point, and replacing the other digits with 9 after that*/
     488       11626 :     IF( LE_32( val, 536870912 /*1 (in Q29)*/ ) && GT_32( val, 447750340 /*5/6 (in Q29)*/ ) )
     489             :     {
     490             :         //  1 (in Q29) <= val <= 5/6 (in Q29) => res = 0
     491        3977 :         res = 0;
     492        3977 :         move16();
     493             :     }
     494        7649 :     ELSE IF( LE_32( val, 447750340 /* 5/6 (in Q29)*/ ) && GT_32( val, 358092870 /*4/6 (in Q29)*/ ) )
     495             :     {
     496             :         //  5/6 (in Q29) <= val <= 4/6 (in Q29) => res = 1
     497        1337 :         res = 1;
     498        1337 :         move16();
     499             :     }
     500        6312 :     ELSE IF( LE_32( val, 358092870 /*4/6 (in Q29)*/ ) && GT_32( val, 268972326 /*3/6 (in Q29)*/ ) )
     501             :     {
     502             :         //  4/6 (in Q29) <= val <= 3/6 (in Q29) => res = 2
     503        1333 :         res = 2;
     504        1333 :         move16();
     505             :     }
     506        4979 :     ELSE IF( LE_32( val, 268972326 /*3/6 (in Q29)*/ ) && GT_32( val, 179314884 /* 2/6 (in Q29) */ ) )
     507             :     {
     508             :         //  3/6 (in Q29) <= val <= 2/6 (in Q29) => res = 3
     509        1364 :         res = 3;
     510        1364 :         move16();
     511             :     }
     512        3615 :     ELSE IF( LE_32( val, 179314884 /* 2/6 (in Q29) */ ) && GT_32( val, 89657442 /* 1/6 => res (in Q29) */ ) )
     513             :     {
     514             :         //  2/6 (in Q29) <= val <= 1/6 => res (in Q29) = 4
     515        1387 :         res = 4;
     516        1387 :         move16();
     517             :     }
     518        2228 :     ELSE IF( LE_32( val, 89657442 /* 1/6 => res (in Q29) */ ) && GT_32( val, 536870 /* 0.0009999999 ( in Q29 )*/ ) )
     519             :     {
     520             :         //  1/6 (in Q29) <= val <= 0 (in Q29) => res = 5
     521             :         // 0.0009999999 in Q29-> 536870
     522        2153 :         res = 5;
     523        2153 :         move16();
     524             :     }
     525             :     ELSE
     526             :     {
     527          75 :         res = 6;
     528          75 :         move16();
     529             :     }
     530       11626 :     return res;
     531             : }
     532             : 
     533             : 
     534        3459 : void calculate_nbits_meta_fx(
     535             :     const Word16 nchan_ism,
     536             :     Word32 q_energy_ratio_ism[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS], // Q30
     537             :     Word32 masa_to_total_energy_ratio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],          // Q30
     538             :     const Word16 numSf,
     539             :     const Word16 numCodingBands,
     540             :     Word16 *bits_ism,
     541             :     const Word16 idx_sep_obj,
     542             :     const Word16 ism_imp )
     543             : {
     544             :     Word16 sf, band, obj;
     545             :     Word32 priority[MAX_NUM_OBJECTS], max_p; /* Q29 */
     546             : 
     547        3459 :     IF( GT_16( nchan_ism, 1 ) )
     548             :     {
     549        3459 :         set32_fx( priority, 0, nchan_ism );
     550       13872 :         FOR( sf = 0; sf < numSf; sf++ )
     551             :         {
     552       66961 :             FOR( band = 0; band < numCodingBands; band++ )
     553             :             {
     554      254292 :                 FOR( obj = 0; obj < nchan_ism; obj++ )
     555             :                 {
     556      197744 :                     priority[obj] = L_max( priority[obj], ( Mpy_32_32( q_energy_ratio_ism[sf][band][obj], L_sub( ONE_IN_Q30 /* 1.0f in Q30 */, masa_to_total_energy_ratio[sf][band] ) ) ) ); // Qx - 1
     557      197744 :                     move32();
     558             :                 }
     559             :             }
     560             :         }
     561             :     }
     562             :     ELSE
     563             :     {
     564           0 :         priority[0] = ONE_IN_Q29; /* 1.0f in Q29 */
     565           0 :         move32();
     566             :     }
     567             : 
     568             :     /* decide parameters for ISM metadata quantization */
     569        3459 :     maximum_32_fx( priority, nchan_ism, &max_p );
     570       15085 :     FOR( obj = 0; obj < nchan_ism; obj++ )
     571             :     {
     572       11626 :         IF( EQ_16( obj, idx_sep_obj ) )
     573             :         {
     574        3459 :             IF( EQ_16( ism_imp, 3 ) )
     575             :             {
     576        2428 :                 priority[obj] = ONE_IN_Q29; /* 1.0f in Q29 */
     577        2428 :                 move32();
     578             :             }
     579        1031 :             ELSE IF( EQ_16( ism_imp, 2 ) )
     580             :             {
     581         943 :                 priority[obj] = L_shr( L_add( ONE_IN_Q29, max_p ), 1 ); // Q29
     582         943 :                 move32();
     583             :             }
     584             :             ELSE
     585             :             {
     586          88 :                 priority[obj] = max_p; /* Q29 */
     587          88 :                 move32();
     588             :             }
     589             :         }
     590       11626 :         bits_ism[obj] = sub( bits_direction_masa[0], get_bits_ism_fx( priority[obj] ) );
     591       11626 :         move16();
     592             :     }
     593        3459 :     return;
     594             : }
     595             : 
     596             : 
     597             : /*---------------------------------------------------------------
     598             :  * ivas_get_stereo_panning_gains()
     599             :  *
     600             :  *
     601             :  *---------------------------------------------------------------*/
     602             : 
     603             : #define SIN_NEG_30_DEGREES_Q15 ( (Word16) 0xC000 )
     604             : #define SIN_30_DEGREES_Q15     ( (Word16) 0x4000 )
     605             : 
     606      113723 : void get_panning_gain_fx(
     607             :     const Word16 sinAngleMapped, // Q15
     608             :     Word16 *panningGains         // Q15
     609             : )
     610             : {
     611             :     Word16 tbl_len, idx, lim_l, lim_r;
     612      113723 :     const Word16 *ptr_sin = &ivas_sine_panning_tbl_fx[0];   // Q15
     613      113723 :     const Word16 *ptr_tan_0 = ivas_tan_panning_gain_tbl_fx; // Q15
     614             : 
     615      113723 :     tbl_len = 601;
     616      113723 :     move16();
     617      113723 :     idx = shr( tbl_len, 1 );
     618      113723 :     lim_l = 0;
     619      113723 :     move16();
     620      113723 :     lim_r = tbl_len;
     621      113723 :     move16();
     622             : 
     623             :     WHILE( 1 )
     624             :     {
     625      845572 :         idx = shr( add( lim_l, lim_r ), 1 );
     626      845572 :         test();
     627      845572 :         IF( GE_16( idx, tbl_len ) )
     628             :         {
     629           0 :             panningGains[0] = ptr_tan_0[tbl_len - 1]; // Q15
     630           0 :             move16();
     631           0 :             panningGains[1] = ptr_tan_0[0]; // Q15
     632           0 :             move16();
     633           0 :             BREAK;
     634             :         }
     635      845572 :         ELSE IF( idx < 0 )
     636             :         {
     637           0 :             panningGains[0] = ptr_tan_0[0]; // Q15
     638           0 :             move16();
     639           0 :             panningGains[1] = ptr_tan_0[tbl_len - 1]; // Q15
     640           0 :             move16();
     641           0 :             BREAK;
     642             :         }
     643      845572 :         ELSE IF( LE_16( sinAngleMapped, ptr_sin[idx + 1] ) && GE_16( sinAngleMapped, ptr_sin[idx] ) )
     644             :         {
     645      113723 :             IF( EQ_16( sinAngleMapped, ptr_sin[idx + 1] ) )
     646             :             {
     647        8682 :                 panningGains[0] = ptr_tan_0[idx + 1]; // Q15
     648        8682 :                 move16();
     649        8682 :                 panningGains[1] = ptr_tan_0[tbl_len - idx - 2]; // Q15
     650        8682 :                 move16();
     651        8682 :                 BREAK;
     652             :             }
     653      105041 :             ELSE IF( EQ_16( sinAngleMapped, ptr_sin[idx] ) )
     654             :             {
     655       20720 :                 panningGains[0] = ptr_tan_0[idx]; // Q15
     656       20720 :                 move16();
     657       20720 :                 panningGains[1] = ptr_tan_0[tbl_len - idx - 1]; // Q15
     658       20720 :                 move16();
     659       20720 :                 BREAK;
     660             :             }
     661             :             ELSE
     662             :             {
     663             :                 Word16 mid;
     664       84321 :                 mid = extract_l( L_shr( L_add( L_deposit_l( ptr_sin[idx] ), L_deposit_l( ptr_sin[idx + 1] ) ), 1 ) );
     665       84321 :                 IF( LE_16( sinAngleMapped, mid ) )
     666             :                 {
     667       41798 :                     panningGains[0] = ptr_tan_0[idx]; // Q15
     668       41798 :                     move16();
     669       41798 :                     panningGains[1] = ptr_tan_0[tbl_len - idx - 1]; // Q15
     670       41798 :                     move16();
     671             :                 }
     672             :                 ELSE
     673             :                 {
     674       42523 :                     panningGains[0] = ptr_tan_0[idx + 1]; // Q15
     675       42523 :                     move16();
     676       42523 :                     panningGains[1] = ptr_tan_0[tbl_len - idx - 2]; // Q15
     677       42523 :                     move16();
     678             :                 }
     679       84321 :                 BREAK;
     680             :             }
     681             :         }
     682      731849 :         ELSE IF( GT_16( sinAngleMapped, ptr_sin[idx] ) )
     683             :         {
     684      384084 :             lim_l = add( idx, 1 );
     685      384084 :             move16();
     686             :         }
     687      347765 :         ELSE IF( LT_16( sinAngleMapped, ptr_sin[idx] ) )
     688             :         {
     689      347765 :             lim_r = sub( idx, 1 );
     690      347765 :             move16();
     691             :         }
     692             :     }
     693      113723 : }
     694             : 
     695             : 
     696       19440 : void ivas_get_stereo_panning_gains_fx(
     697             :     const Word16 aziDeg,   // Q0
     698             :     const Word16 eleDeg,   // Q0
     699             :     Word16 panningGains[2] // Q15
     700             : )
     701             : {
     702             :     /* Convert azi and ele to an azi value of the cone of confusion */
     703       19440 :     Word16 azAddEl = add( aziDeg, eleDeg ); // Q0
     704       19440 :     Word16 azSubEl = sub( aziDeg, eleDeg ); // Q0
     705             : 
     706       19440 :     const Word16 *ptr_sin_az = ivas_sin_az_fx; // Q15
     707             : 
     708       20503 :     WHILE( GT_16( azAddEl, 180 ) )
     709             :     {
     710        1063 :         azAddEl = sub( azAddEl, 360 ); // Q0
     711             :     }
     712       20595 :     WHILE( LT_16( azAddEl, -180 ) )
     713             :     {
     714        1155 :         azAddEl = add( azAddEl, 360 ); // Q0
     715             :     }
     716       20294 :     WHILE( GT_16( azSubEl, 180 ) )
     717             :     {
     718         854 :         azSubEl = sub( azSubEl, 360 ); // Q0
     719             :     }
     720       20298 :     WHILE( LT_16( azSubEl, -180 ) )
     721             :     {
     722         858 :         azSubEl = add( azSubEl, 360 ); // Q0
     723             :     }
     724             :     // sin_az_cos_el = (ptr_sin_az[azAddEl] + ptr_sin_az[azSubEl])/2;
     725             :     Word16 sin_az_cos_el;
     726       19440 :     sin_az_cos_el = extract_l( L_shr( L_add( L_deposit_l( ptr_sin_az[azAddEl + 180] ), L_deposit_l( ptr_sin_az[azSubEl + 180] ) ), 1 ) ); // Q15
     727             : 
     728       19440 :     IF( GE_16( sin_az_cos_el, SIN_30_DEGREES_Q15 ) )
     729             :     {                                      /* Left side */
     730        2999 :         panningGains[0] = (Word16) 0x7fff; // Q15
     731        2999 :         move16();
     732        2999 :         panningGains[1] = 0; // Q15
     733        2999 :         move16();
     734             :     }
     735       16441 :     ELSE IF( LE_16( sin_az_cos_el, SIN_NEG_30_DEGREES_Q15 ) )
     736             :     {                        /* Right side */
     737        3285 :         panningGains[0] = 0; // Q15
     738        3285 :         move16();
     739        3285 :         panningGains[1] = (Word16) 0x7fff; // Q15
     740        3285 :         move16();
     741             :     }
     742             :     ELSE /* Tangent panning law */
     743             :     {
     744       13156 :         get_panning_gain_fx( sin_az_cos_el, panningGains );
     745             :     }
     746             : 
     747       19440 :     return;
     748             : }
     749             : 
     750             : 
     751             : /*---------------------------------------------------------------
     752             :  * calculate_brate_limit_flag()
     753             :  *
     754             :  *
     755             :  *---------------------------------------------------------------*/
     756             : 
     757             : /*! r: limitation flag */
     758        7962 : Word16 calculate_brate_limit_flag_fx(
     759             :     const Word16 ism_imp[], /* i  : ISM importance flags   */
     760             :     const Word16 nchan_ism  /* i  : number of objects      */
     761             : )
     762             : {
     763             :     Word16 n;
     764             :     Word16 brate_limit_flag;
     765             :     Word16 nzeros;
     766             :     Word16 nchan_ism_sat;
     767             : 
     768        7962 :     brate_limit_flag = 0;
     769        7962 :     move16();
     770        7962 :     nzeros = 0;
     771        7962 :     move16();
     772       25807 :     FOR( n = 0; n < nchan_ism; n++ )
     773             :     {
     774       17845 :         brate_limit_flag = add( brate_limit_flag, ism_imp[n] );
     775       17845 :         IF( ism_imp[n] == 0 )
     776             :         {
     777           0 :             nzeros = add( nzeros, 1 );
     778             :         }
     779             :     }
     780        7962 :     nchan_ism_sat = nchan_ism;
     781        7962 :     move16();
     782        7962 :     IF( EQ_16( s_and( nchan_ism, 1 ), 1 ) )
     783             :     {
     784        5373 :         nchan_ism_sat = sub( nchan_ism, 1 );
     785             :     }
     786             : 
     787             : 
     788             :     /* brate_limit_flag >= (int16_t) ( nchan_ism * 2.5f ) */
     789        7962 :     IF( GE_16( i_mult( 2, brate_limit_flag ), add( i_mult( 4, nchan_ism ), nchan_ism_sat ) ) )
     790             :     {
     791        7256 :         brate_limit_flag = 1;
     792        7256 :         move16();
     793             :     }
     794             :     ELSE
     795             :     {
     796         706 :         if ( GE_16( i_mult( 2, nzeros ), nchan_ism ) )
     797             :         {
     798           0 :             brate_limit_flag = -1; /* there is no limitation, on the contrary */
     799           0 :             move16();
     800             :         }
     801             :     }
     802             : 
     803        7962 :     return brate_limit_flag;
     804             : }

Generated by: LCOV version 1.14