LCOV - code coverage report
Current view: top level - lib_com - ivas_omasa_com_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 4c82f1d24d39d0296b18d775f18a006f4c7d024b Lines: 276 331 83.4 %
Date: 2025-05-17 01:59:02 Functions: 9 10 90.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        9232 : 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        9232 :     ISM_MODE ism_mode = ISM_MODE_NONE;
      76        9232 :     move32();
      77             : 
      78        9232 :     SWITCH( nchan_ism )
      79             :     {
      80         812 :         case 1:
      81         812 :             IF( GE_32( ivas_total_brate, IVAS_24k4 ) )
      82             :             {
      83         740 :                 ism_mode = ISM_MASA_MODE_DISC;
      84         740 :                 move32();
      85             :             }
      86             :             ELSE
      87             :             {
      88          72 :                 ism_mode = ISM_MODE_NONE;
      89          72 :                 move32();
      90             :             }
      91         812 :             BREAK;
      92         690 :         case 2:
      93         690 :             IF( GE_32( ivas_total_brate, IVAS_48k ) )
      94             :             {
      95         399 :                 ism_mode = ISM_MASA_MODE_DISC;
      96         399 :                 move32();
      97             :             }
      98         291 :             ELSE IF( GE_32( ivas_total_brate, IVAS_32k ) )
      99             :             {
     100         243 :                 ism_mode = ISM_MASA_MODE_PARAM_ONE_OBJ;
     101         243 :                 move32();
     102             :             }
     103             :             ELSE
     104             :             {
     105          48 :                 ism_mode = ISM_MODE_NONE;
     106          48 :                 move32();
     107             :             }
     108         690 :             BREAK;
     109        4041 :         case 3:
     110        4041 :             IF( GE_32( ivas_total_brate, IVAS_96k ) )
     111             :             {
     112        1338 :                 ism_mode = ISM_MASA_MODE_DISC;
     113        1338 :                 move32();
     114             :             }
     115        2703 :             ELSE IF( GE_32( ivas_total_brate, IVAS_64k ) )
     116             :             {
     117        1012 :                 ism_mode = ISM_MASA_MODE_PARAM_ONE_OBJ;
     118        1012 :                 move32();
     119             :             }
     120        1691 :             ELSE IF( GE_32( ivas_total_brate, IVAS_32k ) )
     121             :             {
     122        1321 :                 ism_mode = ISM_MASA_MODE_MASA_ONE_OBJ;
     123        1321 :                 move32();
     124             :             }
     125             :             ELSE
     126             :             {
     127         370 :                 ism_mode = ISM_MODE_NONE;
     128         370 :                 move32();
     129             :             }
     130        4041 :             BREAK;
     131        3689 :         case 4:
     132        3689 :             IF( GE_32( ivas_total_brate, IVAS_128k ) )
     133             :             {
     134        1027 :                 ism_mode = ISM_MASA_MODE_DISC;
     135        1027 :                 move32();
     136             :             }
     137        2662 :             ELSE IF( GE_32( ivas_total_brate, IVAS_64k ) )
     138             :             {
     139        1046 :                 ism_mode = ISM_MASA_MODE_PARAM_ONE_OBJ;
     140        1046 :                 move32();
     141             :             }
     142        1616 :             ELSE IF( GE_32( ivas_total_brate, IVAS_32k ) )
     143             :             {
     144        1316 :                 ism_mode = ISM_MASA_MODE_MASA_ONE_OBJ;
     145        1316 :                 move32();
     146             :             }
     147             :             ELSE
     148             :             {
     149         300 :                 ism_mode = ISM_MODE_NONE;
     150         300 :                 move32();
     151             :             }
     152        3689 :             BREAK;
     153             :     }
     154             : 
     155        9232 :     return ism_mode;
     156             : }
     157             : 
     158             : /*---------------------------------------------------------------
     159             :  * ivas_set_omasa_TC()
     160             :  *
     161             :  * set number of transport channels in OMASA format
     162             :  * ---------------------------------------------------------------*/
     163             : 
     164        1460 : 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        1460 :     SWITCH( ism_mode )
     172             :     {
     173         675 :         case ISM_MASA_MODE_MASA_ONE_OBJ:
     174             :         case ISM_MASA_MODE_PARAM_ONE_OBJ:
     175         675 :             *nCPE = 1;
     176         675 :             move16();
     177         675 :             *nSCE = 1;
     178         675 :             move16();
     179         675 :             BREAK;
     180         391 :         case ISM_MASA_MODE_DISC:
     181         391 :             *nCPE = 1;
     182         391 :             move16();
     183         391 :             *nSCE = nchan_ism;
     184         391 :             move16();
     185         391 :             BREAK;
     186         394 :         case ISM_MODE_NONE:
     187         394 :             *nCPE = 1;
     188         394 :             move16();
     189         394 :             *nSCE = 0;
     190         394 :             move16();
     191         394 :             BREAK;
     192           0 :         default:
     193           0 :             BREAK;
     194             :     }
     195             : 
     196        1460 :     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       10983 : 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       10983 :     nBits = extract_l( Mpy_32_32( element_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) ); /* Q0 */
     218             : 
     219       10983 :     IF( ism_imp == ISM_INACTIVE_IMP )
     220             :     {
     221           0 :         nBits = BITS_ISM_INACTIVE;
     222           0 :         move16();
     223             :     }
     224             :     ELSE
     225             :     {
     226       10983 :         test();
     227       10983 :         test();
     228       10983 :         test();
     229       10983 :         test();
     230       10983 :         test();
     231       10983 :         test();
     232       10983 :         test();
     233       10983 :         test();
     234       10983 :         test();
     235       10983 :         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        1719 :             test();
     238        1719 :             test();
     239        1719 :             test();
     240        1719 :             test();
     241        1719 :             test();
     242        1719 :             test();
     243        1719 :             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        1475 :                 return element_brate;
     246             :             }
     247             : 
     248         244 :             IF( EQ_16( ism_imp, ISM_LOW_IMP ) )
     249             :             {
     250          18 :                 nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_LOW_IMP4_FX, nBits ) );
     251             :             }
     252         226 :             ELSE IF( EQ_16( ism_imp, ISM_MEDIUM_IMP ) )
     253             :             {
     254          76 :                 nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_MEDIUM_IMP4_FX, nBits ) );
     255          76 :                 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         150 :                 nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_HIGH_IMP4_FX, nBits ) );
     263         150 :                 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        9264 :         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        1631 :             test();
     274        1631 :             IF( EQ_16( ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) && EQ_32( element_brate, IVAS_13k2 ) )
     275             :             {
     276         202 :                 IF( EQ_16( ism_imp, ISM_LOW_IMP ) )
     277             :                 {
     278           6 :                     nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_LOW_IMP3_FX, nBits ) );
     279             :                 }
     280         196 :                 ELSE IF( EQ_16( ism_imp, ISM_MEDIUM_IMP ) )
     281             :                 {
     282          50 :                     nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_MEDIUM_IMP3_FX, nBits ) );
     283             :                 }
     284             :                 ELSE /* ISM_HIGH_IMP */
     285             :                 {
     286         146 :                     nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_HIGH_IMP4_FX, nBits ) );
     287             :                 }
     288             :             }
     289             :             ELSE
     290             :             {
     291        1429 :                 IF( EQ_16( ism_imp, ISM_LOW_IMP ) )
     292             :                 {
     293          34 :                     nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_LOW_IMP3_FX, nBits ) );
     294             :                 }
     295        1395 :                 ELSE IF( EQ_16( ism_imp, ISM_MEDIUM_IMP ) )
     296             :                 {
     297         392 :                     nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_MEDIUM_IMP3_FX, nBits ) );
     298             :                 }
     299             :                 ELSE /* ISM_HIGH_IMP */
     300             :                 {
     301        1003 :                     nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_HIGH_IMP3_FX, nBits ) );
     302             :                 }
     303             :             }
     304             :         }
     305        7633 :         ELSE IF( EQ_16( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) && EQ_32( element_brate, 16000 ) )
     306             :         {
     307         933 :             IF( EQ_16( ism_imp, ISM_LOW_IMP ) )
     308             :             {
     309          28 :                 nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_LOW_IMP_FX, nBits ) );
     310             :             }
     311         905 :             ELSE IF( EQ_16( ism_imp, ISM_MEDIUM_IMP ) )
     312             :             {
     313         272 :                 nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_MEDIUM_IMP_FX, nBits ) );
     314             :             }
     315             :             ELSE /* ISM_HIGH_IMP */
     316             :             {
     317         633 :                 nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_HIGH_IMP3_FX, nBits ) );
     318             :             }
     319             :         }
     320             :         ELSE
     321             :         {
     322        6700 :             IF( EQ_16( ism_imp, ISM_LOW_IMP ) )
     323             :             {
     324         282 :                 nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_LOW_IMP_FX, nBits ) );
     325             :             }
     326        6418 :             ELSE IF( EQ_16( ism_imp, ISM_MEDIUM_IMP ) )
     327             :             {
     328        1763 :                 nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_MEDIUM_IMP_FX, nBits ) );
     329             :             }
     330             :             ELSE /* ISM_HIGH_IMP */
     331             :             {
     332        4655 :                 nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_HIGH_IMP_FX, nBits ) );
     333             :             }
     334             :         }
     335             :     }
     336             : 
     337        9508 :     limit_low = MIN_BRATE_SWB_BWE / FRAMES_PER_SEC;
     338        9508 :     move16();
     339        9508 :     IF( ism_imp == ISM_INACTIVE_IMP )
     340             :     {
     341           0 :         limit_low = BITS_ISM_INACTIVE;
     342           0 :         move16();
     343             :     }
     344        9508 :     ELSE IF( GE_32( element_brate, SCE_CORE_16k_LOW_LIMIT ) )
     345             :     {
     346        6608 :         limit_low = SCE_CORE_16k_LOW_LIMIT / FRAMES_PER_SEC;
     347        6608 :         move16();
     348             :     }
     349             : 
     350        9508 :     limit_high = IVAS_512k / FRAMES_PER_SEC;
     351        9508 :     move16();
     352        9508 :     IF( LE_32( element_brate, SCE_CORE_16k_LOW_LIMIT ) )
     353             :     {
     354        2900 :         limit_high = ACELP_12k8_HIGH_LIMIT / FRAMES_PER_SEC;
     355        2900 :         move16();
     356             :     }
     357             : 
     358        9508 :     nBits = check_bounds_s_fx( nBits, limit_low, limit_high );
     359             : 
     360        9508 :     element_brate_out = L_mult0( nBits, FRAMES_PER_SEC );
     361             : 
     362        9508 :     return element_brate_out;
     363             : }
     364             : 
     365             : /*---------------------------------------------------------------
     366             :  * ivas_combined_format_brate_sanity()
     367             :  *
     368             :  * Sanity check in combined format coding
     369             :  * ---------------------------------------------------------------*/
     370             : 
     371          95 : 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          95 :     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          95 :     IF( LT_32( element_brate, ACELP_12k8_HIGH_LIMIT ) )
     390             :     {
     391          34 :         limit_high = ACELP_12k8_HIGH_LIMIT / FRAMES_PER_SEC;
     392          34 :         move16();
     393          34 :         nBits = extract_l( Mpy_32_32( *core_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) );
     394             : 
     395          34 :         *diff_nBits = sub( nBits, limit_high );
     396          34 :         move16();
     397          34 :         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          95 :     IF( core == ACELP_CORE )
     418             :     {
     419          47 :         *inactive_coder_type_flag = 0; /* AVQ by default */
     420          47 :         move16();
     421          47 :         if ( LE_32( L_add( *core_brate, brate_diff ), MAX_GSC_INACTIVE_BRATE ) )
     422             :         {
     423          36 :             *inactive_coder_type_flag = 1; /* GSC */
     424          36 :             move16();
     425             :         }
     426             :     }
     427             : 
     428          95 :     return;
     429             : }
     430             : 
     431             : 
     432             : /*---------------------------------------------------------------
     433             :  * bits_index_ism_ratio()
     434             :  *
     435             :  *
     436             :  * ---------------------------------------------------------------*/
     437             : 
     438             : /*!r : number of bits for ISM ratio index */
     439        1553 : Word16 bits_index_ism_ratio_fx(
     440             :     const Word16 nchan_ism /* i  : number of objects    */
     441             : )
     442             : {
     443             :     Word16 bits_index;
     444             : 
     445        1553 :     bits_index = 0;
     446        1553 :     move16();
     447        1553 :     IF( EQ_16( nchan_ism, 2 ) )
     448             :     {
     449         154 :         bits_index = 3;
     450         154 :         move16();
     451             :     }
     452        1399 :     ELSE IF( EQ_16( nchan_ism, 3 ) )
     453             :     {
     454         650 :         bits_index = 6;
     455         650 :         move16();
     456             :     }
     457         749 :     ELSE IF( EQ_16( nchan_ism, 4 ) )
     458             :     {
     459         749 :         bits_index = 7;
     460         749 :         move16();
     461             :     }
     462             :     ELSE
     463             :     {
     464           0 :         assert( ( nchan_ism >= 2 && nchan_ism <= 4 ) && "Wrong number of objects for MASA_ISM." );
     465             :     }
     466             : 
     467        1553 :     return bits_index;
     468             : }
     469             : 
     470             : /*---------------------------------------------------------------
     471             :  * calculate_nbits_meta()
     472             :  *
     473             :  *
     474             :  * ---------------------------------------------------------------*/
     475             : 
     476        5346 : static Word16 get_bits_ism_fx(
     477             :     Word32 val // Q29
     478             : )
     479             : {
     480             :     Word16 res;
     481        5346 :     test();
     482        5346 :     test();
     483        5346 :     test();
     484        5346 :     test();
     485        5346 :     test();
     486        5346 :     test();
     487             :     /* Considering only 3 points after decimal point, and replacing the other digits with 9 after that*/
     488        5346 :     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        1857 :         res = 0;
     492        1857 :         move16();
     493             :     }
     494        3489 :     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         628 :         res = 1;
     498         628 :         move16();
     499             :     }
     500        2861 :     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         611 :         res = 2;
     504         611 :         move16();
     505             :     }
     506        2250 :     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         644 :         res = 3;
     510         644 :         move16();
     511             :     }
     512        1606 :     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         633 :         res = 4;
     516         633 :         move16();
     517             :     }
     518         973 :     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         938 :         res = 5;
     523         938 :         move16();
     524             :     }
     525             :     ELSE
     526             :     {
     527          35 :         res = 6;
     528          35 :         move16();
     529             :     }
     530        5346 :     return res;
     531             : }
     532             : 
     533             : 
     534        1597 : 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        1597 :     IF( GT_16( nchan_ism, 1 ) )
     548             :     {
     549        1597 :         set32_fx( priority, 0, nchan_ism );
     550        6374 :         FOR( sf = 0; sf < numSf; sf++ )
     551             :         {
     552       30883 :             FOR( band = 0; band < numCodingBands; band++ )
     553             :             {
     554      116678 :                 FOR( obj = 0; obj < nchan_ism; obj++ )
     555             :                 {
     556       90572 :                     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       90572 :                     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        1597 :     maximum_32_fx( priority, nchan_ism, &max_p );
     570        6943 :     FOR( obj = 0; obj < nchan_ism; obj++ )
     571             :     {
     572        5346 :         IF( EQ_16( obj, idx_sep_obj ) )
     573             :         {
     574        1597 :             IF( EQ_16( ism_imp, 3 ) )
     575             :             {
     576        1120 :                 priority[obj] = ONE_IN_Q29; /* 1.0f in Q29 */
     577        1120 :                 move32();
     578             :             }
     579         477 :             ELSE IF( EQ_16( ism_imp, 2 ) )
     580             :             {
     581         437 :                 priority[obj] = L_shr( L_add( ONE_IN_Q29, max_p ), 1 ); // Q29
     582         437 :                 move32();
     583             :             }
     584             :             ELSE
     585             :             {
     586          40 :                 priority[obj] = max_p; /* Q29 */
     587          40 :                 move32();
     588             :             }
     589             :         }
     590        5346 :         bits_ism[obj] = sub( bits_direction_masa[0], get_bits_ism_fx( priority[obj] ) );
     591        5346 :         move16();
     592             :     }
     593        1597 :     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      100567 : 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      100567 :     const Word16 *ptr_sin = &ivas_sine_panning_tbl_fx[0];   // Q15
     613      100567 :     const Word16 *ptr_tan_0 = ivas_tan_panning_gain_tbl_fx; // Q15
     614             : 
     615      100567 :     tbl_len = 601;
     616      100567 :     move16();
     617      100567 :     idx = shr( tbl_len, 1 );
     618      100567 :     lim_l = 0;
     619      100567 :     move16();
     620      100567 :     lim_r = tbl_len;
     621      100567 :     move16();
     622             : 
     623             :     WHILE( 1 )
     624             :     {
     625      760978 :         idx = shr( add( lim_l, lim_r ), 1 );
     626      760978 :         test();
     627      760978 :         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      760978 :         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      760978 :         ELSE IF( LE_16( sinAngleMapped, ptr_sin[idx + 1] ) && GE_16( sinAngleMapped, ptr_sin[idx] ) )
     644             :         {
     645      100567 :             IF( EQ_16( sinAngleMapped, ptr_sin[idx + 1] ) )
     646             :             {
     647        7740 :                 panningGains[0] = ptr_tan_0[idx + 1]; // Q15
     648        7740 :                 move16();
     649        7740 :                 panningGains[1] = ptr_tan_0[tbl_len - idx - 2]; // Q15
     650        7740 :                 move16();
     651        7740 :                 BREAK;
     652             :             }
     653       92827 :             ELSE IF( EQ_16( sinAngleMapped, ptr_sin[idx] ) )
     654             :             {
     655       16678 :                 panningGains[0] = ptr_tan_0[idx]; // Q15
     656       16678 :                 move16();
     657       16678 :                 panningGains[1] = ptr_tan_0[tbl_len - idx - 1]; // Q15
     658       16678 :                 move16();
     659       16678 :                 BREAK;
     660             :             }
     661             :             ELSE
     662             :             {
     663             :                 Word16 mid;
     664       76149 :                 mid = extract_l( L_shr( L_add( L_deposit_l( ptr_sin[idx] ), L_deposit_l( ptr_sin[idx + 1] ) ), 1 ) );
     665       76149 :                 IF( LE_16( sinAngleMapped, mid ) )
     666             :                 {
     667       37784 :                     panningGains[0] = ptr_tan_0[idx]; // Q15
     668       37784 :                     move16();
     669       37784 :                     panningGains[1] = ptr_tan_0[tbl_len - idx - 1]; // Q15
     670       37784 :                     move16();
     671             :                 }
     672             :                 ELSE
     673             :                 {
     674       38365 :                     panningGains[0] = ptr_tan_0[idx + 1]; // Q15
     675       38365 :                     move16();
     676       38365 :                     panningGains[1] = ptr_tan_0[tbl_len - idx - 2]; // Q15
     677       38365 :                     move16();
     678             :                 }
     679       76149 :                 BREAK;
     680             :             }
     681             :         }
     682      660411 :         ELSE IF( GT_16( sinAngleMapped, ptr_sin[idx] ) )
     683             :         {
     684      345690 :             lim_l = add( idx, 1 );
     685      345690 :             move16();
     686             :         }
     687      314721 :         ELSE IF( LT_16( sinAngleMapped, ptr_sin[idx] ) )
     688             :         {
     689      314721 :             lim_r = sub( idx, 1 );
     690      314721 :             move16();
     691             :         }
     692             :     }
     693      100567 : }
     694             : 
     695             : 
     696           0 : 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           0 :     Word16 azAddEl = add( aziDeg, eleDeg ); // Q0
     704           0 :     Word16 azSubEl = sub( aziDeg, eleDeg ); // Q0
     705             : 
     706           0 :     const Word16 *ptr_sin_az = ivas_sin_az_fx; // Q15
     707             : 
     708           0 :     WHILE( GT_16( azAddEl, 180 ) )
     709             :     {
     710           0 :         azAddEl = sub( azAddEl, 360 ); // Q0
     711             :     }
     712           0 :     WHILE( LT_16( azAddEl, -180 ) )
     713             :     {
     714           0 :         azAddEl = add( azAddEl, 360 ); // Q0
     715             :     }
     716           0 :     WHILE( GT_16( azSubEl, 180 ) )
     717             :     {
     718           0 :         azSubEl = sub( azSubEl, 360 ); // Q0
     719             :     }
     720           0 :     WHILE( LT_16( azSubEl, -180 ) )
     721             :     {
     722           0 :         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           0 :     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           0 :     IF( GE_16( sin_az_cos_el, SIN_30_DEGREES_Q15 ) )
     729             :     {                                      /* Left side */
     730           0 :         panningGains[0] = (Word16) 0x7fff; // Q15
     731           0 :         move16();
     732           0 :         panningGains[1] = 0; // Q15
     733           0 :         move16();
     734             :     }
     735           0 :     ELSE IF( LE_16( sin_az_cos_el, SIN_NEG_30_DEGREES_Q15 ) )
     736             :     {                        /* Right side */
     737           0 :         panningGains[0] = 0; // Q15
     738           0 :         move16();
     739           0 :         panningGains[1] = (Word16) 0x7fff; // Q15
     740           0 :         move16();
     741             :     }
     742             :     ELSE /* Tangent panning law */
     743             :     {
     744           0 :         get_panning_gain_fx( sin_az_cos_el, panningGains );
     745             :     }
     746             : 
     747           0 :     return;
     748             : }
     749             : 
     750             : 
     751             : /*---------------------------------------------------------------
     752             :  * calculate_brate_limit_flag()
     753             :  *
     754             :  *
     755             :  *---------------------------------------------------------------*/
     756             : 
     757             : /*! r: limitation flag */
     758        2766 : 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        2766 :     brate_limit_flag = 0;
     769        2766 :     move16();
     770        2766 :     nzeros = 0;
     771        2766 :     move16();
     772       10097 :     FOR( n = 0; n < nchan_ism; n++ )
     773             :     {
     774        7331 :         brate_limit_flag = add( brate_limit_flag, ism_imp[n] );
     775        7331 :         IF( ism_imp[n] == 0 )
     776             :         {
     777           0 :             nzeros = add( nzeros, 1 );
     778             :         }
     779             :     }
     780        2766 :     nchan_ism_sat = nchan_ism;
     781        2766 :     move16();
     782        2766 :     IF( EQ_16( s_and( nchan_ism, 1 ), 1 ) )
     783             :     {
     784        1663 :         nchan_ism_sat = sub( nchan_ism, 1 );
     785             :     }
     786             : 
     787             : 
     788             :     /* brate_limit_flag >= (int16_t) ( nchan_ism * 2.5f ) */
     789        2766 :     IF( GE_16( i_mult( 2, brate_limit_flag ), add( i_mult( 4, nchan_ism ), nchan_ism_sat ) ) )
     790             :     {
     791        2468 :         brate_limit_flag = 1;
     792        2468 :         move16();
     793             :     }
     794             :     ELSE
     795             :     {
     796         298 :         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        2766 :     return brate_limit_flag;
     804             : }

Generated by: LCOV version 1.14