LCOV - code coverage report
Current view: top level - lib_com - ivas_masa_com_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ e18c9336de3662840bcb0d2c4165c799124141cb Lines: 525 541 97.0 %
Date: 2025-10-29 23:34:44 Functions: 13 13 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 "prot_fx.h"
      38             : #include "ivas_cnst.h"
      39             : #include "ivas_rom_com.h"
      40             : #include "ivas_stat_dec.h"
      41             : #include "wmc_auto.h"
      42             : #include "ivas_prot_fx.h"
      43             : 
      44             : 
      45             : /*---------------------------------------------------------------
      46             :  * Local constants
      47             :  *---------------------------------------------------------------*/
      48             : 
      49             : #define MASA_EXTRA_BAND_META_BITS 40
      50             : 
      51             : #define MASA_SMALL_INC_META_BITS 10
      52             : 
      53             : 
      54             : /*---------------------------------------------------------------
      55             :  * Local prototypes
      56             :  *---------------------------------------------------------------*/
      57             : 
      58             : static Word16 quantize_theta_masa_fx(
      59             :     const Word32 x_fx,  /* i  : theta value to be quantized  Q22*/
      60             :     const Word16 no_cb, /* i  : number of codewords          */
      61             :     Word32 *xhat_fx     /* o  : quantized value              Q22*/
      62             : );
      63             : 
      64             : static Word16 quantize_phi_masa_fx(
      65             :     const Word32 phi_fx,     /* i  : azimuth value                                                  Q22 */
      66             :     const Word16 flag_delta, /* i  : flag indicating if the azimuth codebook is translated or not    */
      67             :     Word32 *phi_hat_fx,      /* o  : quantized azimuth                                              Q22 */
      68             :     const Word16 n           /* i  : azimuth codebook size                                           */
      69             : );
      70             : 
      71             : static Word32 estim_round[MASA_NO_CIRCLES + 1] = {
      72             :     /* Q0 */
      73             :     -423,
      74             :     0,
      75             :     422,
      76             :     845,
      77             :     1267,
      78             :     1689,
      79             :     2111,
      80             :     2532,
      81             :     2953,
      82             :     3373,
      83             :     3793,
      84             :     4212,
      85             :     4630,
      86             :     5047,
      87             :     5464,
      88             :     5880,
      89             :     6294,
      90             :     6708,
      91             :     7120,
      92             :     7532,
      93             :     7941,
      94             :     8350,
      95             :     8757,
      96             :     9163,
      97             :     9567,
      98             :     9969,
      99             :     10370,
     100             :     10769,
     101             :     11166,
     102             :     11561,
     103             :     11955,
     104             :     12346,
     105             :     12735,
     106             :     13122,
     107             :     13507,
     108             :     13890,
     109             :     14270,
     110             :     14648,
     111             :     15023,
     112             :     15396,
     113             :     15766,
     114             :     16134,
     115             :     16499,
     116             :     16861,
     117             :     17220,
     118             :     17576,
     119             :     17930,
     120             :     18280,
     121             :     18627,
     122             :     18971,
     123             :     19312,
     124             :     19650,
     125             :     19984,
     126             :     20315,
     127             :     20643,
     128             :     20967,
     129             :     21288,
     130             :     21605,
     131             :     21918,
     132             :     22228,
     133             :     22534,
     134             :     22836,
     135             :     23135,
     136             :     23429,
     137             :     23720,
     138             :     24007,
     139             :     24289,
     140             :     24568,
     141             :     24842,
     142             :     25112,
     143             :     25378,
     144             :     25640,
     145             :     25898,
     146             :     26151,
     147             :     26400,
     148             :     26644,
     149             :     26884,
     150             :     27119,
     151             :     27350,
     152             :     27576,
     153             :     27798,
     154             :     28015,
     155             :     28227,
     156             :     28435,
     157             :     28637,
     158             :     28835,
     159             :     29029,
     160             :     29217,
     161             :     29400,
     162             :     29579,
     163             :     29752,
     164             :     29921,
     165             :     30084,
     166             :     30243,
     167             :     30396,
     168             :     30544,
     169             :     30688,
     170             :     30826,
     171             :     30959,
     172             :     31086,
     173             :     31209,
     174             :     31326,
     175             :     31438,
     176             :     31545,
     177             :     31647,
     178             :     31743,
     179             :     31834,
     180             :     31919,
     181             :     32000,
     182             :     32075,
     183             :     32144,
     184             :     32208,
     185             :     32267,
     186             :     32320,
     187             :     32368,
     188             :     32411,
     189             :     32448,
     190             :     32480,
     191             :     32506,
     192             :     32527,
     193             :     32542,
     194             :     32552
     195             : };
     196             : 
     197             : static Word32 estim_ceil[MASA_NO_CIRCLES + 1] = {
     198             :     /* Q0 */
     199             :     -422,
     200             :     0,
     201             :     423,
     202             :     845,
     203             :     1268,
     204             :     1690,
     205             :     2111,
     206             :     2532,
     207             :     2953,
     208             :     3374,
     209             :     3793,
     210             :     4212,
     211             :     4630,
     212             :     5048,
     213             :     5465,
     214             :     5880,
     215             :     6295,
     216             :     6708,
     217             :     7121,
     218             :     7532,
     219             :     7942,
     220             :     8350,
     221             :     8758,
     222             :     9163,
     223             :     9567,
     224             :     9970,
     225             :     10371,
     226             :     10770,
     227             :     11167,
     228             :     11562,
     229             :     11955,
     230             :     12347,
     231             :     12736,
     232             :     13123,
     233             :     13508,
     234             :     13890,
     235             :     14270,
     236             :     14648,
     237             :     15024,
     238             :     15396,
     239             :     15767,
     240             :     16134,
     241             :     16499,
     242             :     16861,
     243             :     17220,
     244             :     17577,
     245             :     17930,
     246             :     18280,
     247             :     18628,
     248             :     18972,
     249             :     19313,
     250             :     19650,
     251             :     19985,
     252             :     20316,
     253             :     20644,
     254             :     20968,
     255             :     21288,
     256             :     21605,
     257             :     21919,
     258             :     22229,
     259             :     22535,
     260             :     22837,
     261             :     23135,
     262             :     23430,
     263             :     23720,
     264             :     24007,
     265             :     24290,
     266             :     24568,
     267             :     24843,
     268             :     25113,
     269             :     25379,
     270             :     25641,
     271             :     25898,
     272             :     26151,
     273             :     26400,
     274             :     26644,
     275             :     26884,
     276             :     27120,
     277             :     27350,
     278             :     27577,
     279             :     27798,
     280             :     28015,
     281             :     28228,
     282             :     28435,
     283             :     28638,
     284             :     28836,
     285             :     29029,
     286             :     29217,
     287             :     29401,
     288             :     29579,
     289             :     29753,
     290             :     29921,
     291             :     30085,
     292             :     30243,
     293             :     30397,
     294             :     30545,
     295             :     30688,
     296             :     30826,
     297             :     30959,
     298             :     31087,
     299             :     31210,
     300             :     31327,
     301             :     31439,
     302             :     31546,
     303             :     31647,
     304             :     31743,
     305             :     31834,
     306             :     31920,
     307             :     32000,
     308             :     32075,
     309             :     32145,
     310             :     32209,
     311             :     32268,
     312             :     32321,
     313             :     32369,
     314             :     32411,
     315             :     32449,
     316             :     32480,
     317             :     32506,
     318             :     32527,
     319             :     32543,
     320             :     32552
     321             : };
     322             : 
     323             : 
     324             : /*---------------------------------------------------------------
     325             :  * ivas_masa_setup()
     326             :  *
     327             :  * Set-up MASA coding elements and bitrates
     328             :  *---------------------------------------------------------------*/
     329             : 
     330       94049 : void ivas_masa_set_elements_fx(
     331             :     const Word32 ivas_total_brate,    /* i  : IVAS total bitrate                      */
     332             :     const Word16 mc_mode,             /* i  : MC format mode                          */
     333             :     const Word16 nchan_transport,     /* i  : number of MASA input/transport channels */
     334             :     IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle                       */
     335             :     Word16 *element_mode,             /* o  : element mode                            */
     336             :     Word16 *nSCE,                     /* o  : number of SCEs                          */
     337             :     Word16 *nCPE,                     /* o  : number of CPEs                          */
     338             :     const Word16 ivas_format,         /* i  : IVAS format                             */
     339             :     const ISM_MODE ism_mode,          /* i  : ISM mode                                */
     340             :     const Word32 ism_total_brate      /* i  : initial ISM total bitrate               */
     341             : )
     342             : {
     343             :     Word16 tmp;
     344             : 
     345       94049 :     IF( EQ_16( nchan_transport, 2 ) )
     346             :     {
     347       54295 :         test();
     348       54295 :         test();
     349       54295 :         IF( GE_32( ivas_total_brate, MCMASA_SEPARATE_BRATE ) && EQ_16( mc_mode, MC_MODE_MCMASA ) )
     350             :         {
     351         663 :             *nCPE = 1;
     352         663 :             move16();
     353         663 :             *nSCE = 1;
     354         663 :             move16();
     355             : 
     356         663 :             *element_mode = IVAS_SCE; /* This is needed for the initialization phase to initialize codec mode to SCE, since it is written first to the file*/
     357         663 :             move16();
     358             :         }
     359       53632 :         ELSE IF( EQ_16( ivas_format, MASA_ISM_FORMAT ) && ism_mode != ISM_MODE_NONE )
     360             :         {
     361       15244 :             *nCPE = 1;
     362       15244 :             move16();
     363             : 
     364       15244 :             if ( EQ_16( *element_mode, -1 ) )
     365             :             {
     366        6944 :                 *element_mode = IVAS_CPE_DFT; /* To have it initialized in case it was not already. */
     367        6944 :                 move16();
     368             :             }
     369       15244 :             IF( GT_32( ivas_total_brate, MIN_BRATE_MDCT_STEREO ) )
     370             :             {
     371       10166 :                 *element_mode = IVAS_CPE_MDCT;
     372       10166 :                 move16();
     373       10166 :                 test();
     374       10166 :                 test();
     375       10166 :                 test();
     376       10166 :                 if ( ( EQ_16( ism_mode, ISM_MASA_MODE_DISC ) || EQ_16( ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) || EQ_16( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) ) && LT_32( L_sub( ivas_total_brate, ism_total_brate ), MIN_BRATE_MDCT_STEREO ) )
     377             :                 {
     378        1105 :                     *element_mode = IVAS_CPE_DFT;
     379        1105 :                     move16();
     380             :                 }
     381             :             }
     382             :         }
     383             :         ELSE
     384             :         {
     385       38388 :             *nCPE = 1;
     386       38388 :             move16();
     387       38388 :             *nSCE = 0;
     388       38388 :             move16();
     389             : 
     390       38388 :             if ( GT_32( ivas_total_brate, MIN_BRATE_MDCT_STEREO ) )
     391             :             {
     392       17860 :                 *element_mode = IVAS_CPE_MDCT;
     393       17860 :                 move16();
     394             :             }
     395             :         }
     396             :         /* hQMetaData->bits_frame_nominal = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC ); */
     397       54295 :         hQMetaData->bits_frame_nominal = extract_l( Mpy_32_32( ivas_total_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) );
     398       54295 :         test();
     399       54295 :         test();
     400       54295 :         test();
     401       54295 :         if ( EQ_16( ivas_format, MASA_ISM_FORMAT ) && ( EQ_16( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_16( ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) || EQ_16( ism_mode, ISM_MASA_MODE_DISC ) ) )
     402             :         {
     403             :             /* hQMetaData->bits_frame_nominal -= (int16_t) ( ism_total_brate / FRAMES_PER_SEC ); */
     404       15244 :             tmp = extract_l( Mpy_32_32( ism_total_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) );
     405       15244 :             hQMetaData->bits_frame_nominal = sub( hQMetaData->bits_frame_nominal, tmp );
     406             :         }
     407             :     }
     408       39754 :     ELSE IF( GE_16( nchan_transport, 1 ) )
     409             :     {
     410       39754 :         *nCPE = 0;
     411       39754 :         move16();
     412       39754 :         *nSCE = 1;
     413       39754 :         move16();
     414             : 
     415       39754 :         IF( EQ_32( ivas_total_brate, IVAS_13k2 ) )
     416             :         {
     417        7491 :             hQMetaData->bits_frame_nominal = ACELP_9k60 / FRAMES_PER_SEC;
     418        7491 :             move16();
     419             :         }
     420       32263 :         ELSE IF( LE_32( ivas_total_brate, IVAS_16k4 ) )
     421             :         {
     422        2503 :             hQMetaData->bits_frame_nominal = ACELP_13k20 / FRAMES_PER_SEC;
     423        2503 :             move16();
     424             :         }
     425       29760 :         ELSE IF( LE_32( ivas_total_brate, IVAS_24k4 ) )
     426             :         {
     427       11614 :             hQMetaData->bits_frame_nominal = ACELP_16k40 / FRAMES_PER_SEC;
     428       11614 :             move16();
     429             :         }
     430       18146 :         ELSE IF( LE_32( ivas_total_brate, IVAS_32k ) )
     431             :         {
     432        4547 :             hQMetaData->bits_frame_nominal = ACELP_24k40 / FRAMES_PER_SEC;
     433        4547 :             move16();
     434             :         }
     435             :         ELSE
     436             :         {
     437       13599 :             hQMetaData->bits_frame_nominal = extract_l( Mpy_32_32( ivas_total_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) );
     438             :         }
     439       39754 :         *element_mode = IVAS_SCE;
     440       39754 :         move16();
     441             :     }
     442             :     ELSE
     443             :     {
     444           0 :         assert( !"MASA number of transport channels must be 1, or 2" );
     445             :     }
     446             : 
     447       94049 :     return;
     448             : }
     449             : 
     450             : 
     451             : /*---------------------------------------------------------------
     452             :  * generate_gridEq()
     453             :  *
     454             :  * generate Spherical grid
     455             :  *---------------------------------------------------------------*/
     456             : 
     457         635 : void generate_gridEq_fx(
     458             :     SPHERICAL_GRID_DATA *data /* o  : data structure for grid  */
     459             : )
     460             : {
     461             :     /***************************************************************/
     462             :     /* NOTE: created LUT from float code. The lookup table depends */
     463             :     /* on the following macros:                                    */
     464             :     /*          - MASA_NO_CIRCLES                                  */
     465             :     /*          - MASA_NO_POINTS_EQUATOR                           */
     466             :     /*          - MASA_ANGLE_AT_EQUATOR                            */
     467             :     /*          - MASA_NTOT2_FAC                                   */
     468             :     /*          - MASA_ASIN_OFFSET                                 */
     469             :     /***************************************************************/
     470             : 
     471         635 :     Copy( gridEq_Table, data->no_phi, NO_THETA16_MAX );
     472             : 
     473         635 :     data->no_theta = NO_THETA16_MAX;
     474         635 :     move16();
     475             : 
     476         635 :     return;
     477             : }
     478             : 
     479             : 
     480             : /*---------------------------------------------------------------
     481             :  * ivas_masa_set_coding_config()
     482             :  *
     483             :  * Sets MASA codec parameters based on bitrate, number of directions,
     484             :  * and other metadata properties.
     485             :  *---------------------------------------------------------------*/
     486             : 
     487       89040 : void ivas_masa_set_coding_config_fx(
     488             :     MASA_CODEC_CONFIG *config,     /* i/o: MASA coding config structure                */
     489             :     Word16 *band_mapping,          /* o  : Band mapping used                           */
     490             :     const Word32 ivas_total_brate, /* i  : IVAS total bitrate                          */
     491             :     const Word16 nchan_transport,  /* i  : number of transport channels (mono/stereo)  */
     492             :     const UWord8 isMcMasa          /* i  : toggle for selecting mcMASA specific config */
     493             : )
     494             : {
     495             :     Word16 i;
     496             :     UWord8 nbands;
     497             :     UWord8 nTwoDirBands;
     498             :     const Word16 *masa_bits_table;
     499             : 
     500             :     /* When coming into this function, these values should be already set:
     501             :      *  joinedSubframes;
     502             :      *  useCoherence;
     503             :      *  numberOfDirections;
     504             :      */
     505             : 
     506             :     /* Setup coding parameters based on the bitrate, transport channel count, subframe metadata information,
     507             :      * and number of directions in metadata. */
     508       89040 :     nbands = 0;
     509       89040 :     move16();
     510       89040 :     nTwoDirBands = 0;
     511       89040 :     move16();
     512       89040 :     i = 0;
     513       89040 :     move16();
     514             : 
     515             :     /* First select correct bit budget table */
     516       89040 :     masa_bits_table = masa_bits;
     517             : 
     518       89040 :     test();
     519       89040 :     IF( isMcMasa )
     520             :     {
     521       11790 :         masa_bits_table = mcmasa_bits;
     522             :     }
     523       77250 :     ELSE IF( LT_32( ivas_total_brate, IVAS_48k ) && EQ_16( nchan_transport, 2 ) )
     524             :     {
     525       23253 :         masa_bits_table = masa_bits_LR_stereo;
     526             :     }
     527             : 
     528      567433 :     WHILE( nbands == 0 && LT_16( i, IVAS_NUM_ACTIVE_BRATES ) )
     529             :     {
     530      478393 :         test();
     531      478393 :         IF( LE_32( ivas_total_brate, ivas_brate_tbl[i + SIZE_IVAS_BRATE_TBL - IVAS_NUM_ACTIVE_BRATES] ) )
     532             :         {
     533             :             Word16 idx_bands;
     534             : 
     535       89040 :             test();
     536       89040 :             test();
     537       89040 :             if ( LT_32( ivas_total_brate, IVAS_48k ) && EQ_16( nchan_transport, 2 ) && GT_16( i, 3 ) )
     538             :             {
     539             :                 /* because it uses the bitallocation for the lower bit rates from 'masa_bits_LR_stereo' and it has 4 elements */
     540         750 :                 i = 3;
     541         750 :                 move16();
     542             :             }
     543       89040 :             idx_bands = i;
     544       89040 :             move16();
     545             : 
     546       89040 :             IF( GT_16( config->numberOfDirections, 1 ) )
     547             :             {
     548       15664 :                 IF( config->joinedSubframes )
     549             :                 {
     550        2764 :                     nTwoDirBands = masa_twodir_bands_joined[i];
     551        2764 :                     move16();
     552             :                 }
     553             :                 ELSE
     554             :                 {
     555       12900 :                     nTwoDirBands = masa_twodir_bands[i];
     556       12900 :                     move16();
     557             :                 }
     558             : 
     559       15664 :                 test();
     560       15664 :                 test();
     561       15664 :                 test();
     562       15664 :                 if ( ( GT_32( ivas_total_brate, IVAS_96k ) && !config->joinedSubframes ) || ( GT_32( ivas_total_brate, IVAS_80k ) && config->joinedSubframes ) )
     563             :                 {
     564        7761 :                     idx_bands = sub( idx_bands, 1 );
     565             :                 }
     566             :             }
     567             : 
     568       89040 :             IF( config->joinedSubframes )
     569             :             {
     570       10980 :                 nbands = masa_joined_nbands[idx_bands];
     571       10980 :                 move16();
     572             :             }
     573             :             ELSE
     574             :             {
     575       78060 :                 nbands = masa_nbands[idx_bands];
     576       78060 :                 move16();
     577             :             }
     578             : 
     579       89040 :             config->max_metadata_bits = (UWord16) masa_bits_table[i];
     580       89040 :             move16();
     581             : 
     582       89040 :             test();
     583       89040 :             if ( EQ_32( ivas_total_brate, IVAS_64k ) && GT_16( config->numberOfDirections, 1 ) )
     584             :             {
     585             :                 /* At 64k, we increase metadata bit budget when there is two directions present. */
     586        1094 :                 config->max_metadata_bits = (UWord16) add( config->max_metadata_bits, MASA_EXTRA_BAND_META_BITS );
     587        1094 :                 move16();
     588             :             }
     589             : 
     590       89040 :             test();
     591       89040 :             test();
     592       89040 :             test();
     593       89040 :             if ( ( ( EQ_32( ivas_total_brate, IVAS_32k ) && EQ_16( nchan_transport, 2 ) ) || EQ_32( ivas_total_brate, IVAS_48k ) ) && config->joinedSubframes )
     594             :             {
     595             :                 /* At 32k and 48k, we increase metadata bit budget when joinedSubframes. */
     596        2241 :                 config->max_metadata_bits = (UWord16) add( config->max_metadata_bits, MASA_SMALL_INC_META_BITS );
     597        2241 :                 move16();
     598             :             }
     599             :         }
     600      478393 :         i = add( i, 1 );
     601             :     }
     602       89040 :     config->numCodingBands = nbands;
     603       89040 :     move16();
     604       89040 :     config->numTwoDirBands = nTwoDirBands;
     605       89040 :     move16();
     606             : 
     607       89040 :     IF( EQ_16( config->joinedSubframes, TRUE ) )
     608             :     {
     609       10980 :         config->mergeRatiosOverSubframes = FALSE;
     610       10980 :         move16();
     611             :     }
     612             :     ELSE
     613             :     {
     614       78060 :         config->mergeRatiosOverSubframes = TRUE;
     615       78060 :         move16();
     616             :     }
     617             : 
     618             :     /* Setup frequency band mapping based on the number of used coding bands */
     619       89040 :     SWITCH( config->numCodingBands )
     620             :     {
     621       66578 :         case 5:
     622       66578 :             Copy( MASA_band_mapping_24_to_5, band_mapping, 5 + 1 );
     623       66578 :             BREAK;
     624        6855 :         case 8:
     625        6855 :             Copy( MASA_band_mapping_24_to_8, band_mapping, 8 + 1 );
     626        6855 :             BREAK;
     627        3996 :         case 12:
     628        3996 :             Copy( MASA_band_mapping_24_to_12, band_mapping, 12 + 1 );
     629        3996 :             BREAK;
     630        4375 :         case 18:
     631        4375 :             Copy( MASA_band_mapping_24_to_18, band_mapping, 18 + 1 );
     632        4375 :             BREAK;
     633        7236 :         case MASA_FREQUENCY_BANDS:
     634             :             /* With input count of bands, no mapping is needed but for unified processing later, we store normal mapping */
     635      188136 :             FOR( i = 0; i < MASA_FREQUENCY_BANDS + 1; i++ )
     636             :             {
     637      180900 :                 band_mapping[i] = i;
     638      180900 :                 move16();
     639             :             }
     640        7236 :             BREAK;
     641           0 :         default:
     642           0 :             assert( 0 && "Error: The number of MASA coding bands is not supported" );
     643             :     }
     644             : 
     645       89040 :     config->useCoherence = TRUE;
     646       89040 :     move16();
     647       89040 :     test();
     648       89040 :     test();
     649       89040 :     test();
     650       89040 :     if ( ( !isMcMasa && LT_32( ivas_total_brate, IVAS_48k ) ) || ( isMcMasa && LT_32( ivas_total_brate, IVAS_16k4 ) ) )
     651             :     {
     652       38951 :         config->useCoherence = FALSE;
     653       38951 :         move16();
     654             :     }
     655             : 
     656       89040 :     return;
     657             : }
     658             : 
     659             : 
     660             : /*---------------------------------------------------------------
     661             :  * masa_sample_rate_band_correction()
     662             :  *
     663             :  *
     664             :  *---------------------------------------------------------------*/
     665             : 
     666       89040 : void masa_sample_rate_band_correction_fx(
     667             :     MASA_CODEC_CONFIG *config,                   /* i/o: MASA codec config                     */
     668             :     Word16 *band_mapping,                        /* i/o: Band mapping used and modified        */
     669             :     IVAS_QMETADATA_HANDLE hQMetaData,            /* i/o: QMetadata structure for modification  */
     670             :     const UWord8 maxBand,                        /* i  : max band                              */
     671             :     UWord8 is_encoder,                           /* i  : signals if called at encoder          */
     672             :     MASA_DECODER_EXT_OUT_META_HANDLE hExtOutMeta /* i/o: MASA decoder metadata ext out buffer  */
     673             : )
     674             : {
     675             :     UWord8 band, sf;
     676             :     Word16 highBand;
     677             :     UWord8 numBands48k;
     678             : 
     679       89040 :     numBands48k = config->numCodingBands;
     680       89040 :     move16();
     681             : 
     682      684663 :     FOR( band = 1; band < config->numCodingBands + 1; band++ )
     683             :     {
     684      684663 :         highBand = band_mapping[band];
     685      684663 :         move16();
     686             : 
     687      684663 :         IF( GE_16( highBand, (Word16) maxBand ) )
     688             :         {
     689       89040 :             config->numCodingBands = band;
     690       89040 :             move16();
     691       89040 :             hQMetaData->numCodingBands = band;
     692       89040 :             move16();
     693             : 
     694       89040 :             IF( is_encoder )
     695             :             {
     696        2276 :                 if ( GT_16( hQMetaData->q_direction->cfg.nbands, (Word16) band ) )
     697             :                 {
     698         300 :                     hQMetaData->q_direction->cfg.nbands = band;
     699         300 :                     move16();
     700             :                 }
     701        2276 :                 test();
     702        2276 :                 if ( EQ_16( (Word16) hQMetaData->no_directions, 2 ) && GT_16( hQMetaData->q_direction[1].cfg.nbands, (Word16) band ) )
     703             :                 {
     704         300 :                     hQMetaData->q_direction[1].cfg.nbands = band;
     705         300 :                     move16();
     706             :                 }
     707             :             }
     708             : 
     709       89040 :             band_mapping[band] = maxBand;
     710       89040 :             move16();
     711             : 
     712       89040 :             BREAK;
     713             :         }
     714             :     }
     715             : 
     716             :     /* Set rest of the bands to zero in qmetadata. */
     717       92473 :     FOR( ; band < numBands48k; band++ )
     718             :     {
     719       17165 :         FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
     720             :         {
     721       13732 :             hQMetaData->q_direction[0].band_data[band].azimuth_fx[sf] = 0;
     722       13732 :             move32();
     723       13732 :             hQMetaData->q_direction[0].band_data[band].elevation_fx[sf] = 0;
     724       13732 :             move32();
     725       13732 :             hQMetaData->q_direction[0].band_data[band].energy_ratio_fx[sf] = 0;
     726       13732 :             move32();
     727             : 
     728       13732 :             test();
     729       13732 :             if ( hQMetaData->coherence_flag && hQMetaData->q_direction[0].coherence_band_data != NULL )
     730             :             {
     731       13732 :                 hQMetaData->q_direction[0].coherence_band_data[band].spread_coherence[sf] = 0u;
     732       13732 :                 move16();
     733             :             }
     734             : 
     735       13732 :             IF( EQ_16( (Word16) hQMetaData->no_directions, 2 ) )
     736             :             {
     737        2304 :                 hQMetaData->q_direction[1].band_data[band].azimuth_fx[sf] = 0;
     738        2304 :                 move32();
     739        2304 :                 hQMetaData->q_direction[1].band_data[band].elevation_fx[sf] = 0;
     740        2304 :                 move32();
     741        2304 :                 hQMetaData->q_direction[1].band_data[band].energy_ratio_fx[sf] = 0;
     742        2304 :                 move32();
     743             : 
     744        2304 :                 test();
     745        2304 :                 if ( hQMetaData->coherence_flag && hQMetaData->q_direction[1].coherence_band_data != NULL )
     746             :                 {
     747        2304 :                     hQMetaData->q_direction[1].coherence_band_data[band].spread_coherence[sf] = 0u;
     748        2304 :                     move16();
     749             :                 }
     750             :             }
     751             : 
     752       13732 :             test();
     753       13732 :             if ( hQMetaData->coherence_flag && hQMetaData->surcoh_band_data != NULL )
     754             :             {
     755       13732 :                 hQMetaData->surcoh_band_data[band].surround_coherence[sf] = 0u;
     756       13732 :                 move16();
     757             :             }
     758             :         }
     759             : 
     760        3433 :         if ( EQ_16( (Word16) hQMetaData->no_directions, 2 ) )
     761             :         {
     762         576 :             hQMetaData->twoDirBands[band] = 0;
     763         576 :             move16();
     764             :         }
     765             :     }
     766             : 
     767       89040 :     IF( hExtOutMeta != NULL )
     768             :     {
     769             :         /* in decoder, zero the EXT out MASA meta buffer */
     770       26525 :         FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
     771             :         {
     772      350868 :             FOR( band = hQMetaData->numCodingBands; band < MASA_FREQUENCY_BANDS; band++ )
     773             :             {
     774      329648 :                 hExtOutMeta->directionIndex[0][sf][band] = SPH_IDX_FRONT;
     775      329648 :                 move16();
     776      329648 :                 hExtOutMeta->directToTotalRatio[0][sf][band] = 0u;
     777      329648 :                 move16();
     778      329648 :                 hExtOutMeta->spreadCoherence[0][sf][band] = 0u;
     779      329648 :                 move16();
     780             : 
     781      329648 :                 hExtOutMeta->directionIndex[1][sf][band] = SPH_IDX_FRONT;
     782      329648 :                 move16();
     783      329648 :                 hExtOutMeta->directToTotalRatio[1][sf][band] = 0u;
     784      329648 :                 move16();
     785      329648 :                 hExtOutMeta->spreadCoherence[1][sf][band] = 0u;
     786      329648 :                 move16();
     787             : 
     788      329648 :                 hExtOutMeta->surroundCoherence[sf][band] = 0u;
     789      329648 :                 move16();
     790      329648 :                 hExtOutMeta->diffuseToTotalRatio[sf][band] = UINT8_MAX;
     791      329648 :                 move16();
     792             :             }
     793             :         }
     794             :     }
     795             : 
     796       89040 :     return;
     797             : }
     798             : 
     799             : 
     800             : /*-------------------------------------------------------------------------
     801             :  * index_theta_phi_16()
     802             :  *
     803             :  *
     804             :  *------------------------------------------------------------------------*/
     805             : 
     806             : /*! r: output index for direction */
     807      285945 : UWord16 index_theta_phi_16_fx(
     808             :     Word32 *p_theta,                    /* i/o: input elevation to be indexed  Q22 */
     809             :     Word32 *p_phi,                      /* i/o: input azimuth to be indexed    Q22 */
     810             :     const SPHERICAL_GRID_DATA *gridData /* i  : generated grid data             */
     811             : )
     812             : {
     813             :     Word32 abs_theta_fx;
     814             :     Word16 sign_th, id_phi, id_th;
     815             :     UWord16 idx_sph;
     816             :     UWord16 cum_n;
     817             :     Word32 theta_hat_fx, phi_hat_fx;
     818             :     Word32 theta_fx, phi_fx;
     819             : 
     820      285945 :     theta_fx = *p_theta; // Q22
     821      285945 :     move32();
     822      285945 :     phi_fx = *p_phi; // Q22
     823      285945 :     move32();
     824      285945 :     phi_hat_fx = 0;
     825      285945 :     move32();
     826      285945 :     theta_hat_fx = 0;
     827      285945 :     move32();
     828      285945 :     phi_fx = L_add( phi_fx, L_shl( 180, Q22 ) ); // Q22
     829             : 
     830      285945 :     IF( theta_fx < 0 )
     831             :     {
     832       85360 :         abs_theta_fx = L_negate( theta_fx ); // Q22
     833       85360 :         sign_th = -1;
     834       85360 :         move16();
     835             :     }
     836             :     ELSE
     837             :     {
     838      200585 :         abs_theta_fx = theta_fx; // Q22
     839      200585 :         move32();
     840      200585 :         sign_th = 1;
     841      200585 :         move16();
     842             :     }
     843             : 
     844      285945 :     id_th = quantize_theta_masa_fx( abs_theta_fx, gridData->no_theta, &theta_hat_fx );
     845      285945 :     IF( GT_16( gridData->no_theta, 1 ) )
     846             :     {
     847      285945 :         IF( GT_16( gridData->no_phi[id_th], 1 ) )
     848             :         {
     849      285727 :             id_phi = quantize_phi_masa_fx( phi_fx, (Word16) EQ_16( s_and( id_th, 1 ), 1 ), &phi_hat_fx, gridData->no_phi[id_th] );
     850             :         }
     851             :         ELSE
     852             :         {
     853         218 :             id_phi = 0;
     854         218 :             move16();
     855         218 :             phi_hat_fx = L_shl( 180, Q22 ); // Q22
     856             :         }
     857             :     }
     858             :     ELSE
     859             :     {
     860           0 :         id_phi = quantize_phi_masa_fx( phi_fx, (Word16) EQ_16( s_and( id_th, 1 ), 1 ), &phi_hat_fx, gridData->no_phi[id_th] );
     861             :     }
     862             : 
     863      285945 :     *p_theta = theta_hat_fx;
     864      285945 :     move32();
     865      285945 :     if ( EQ_16( sign_th, -1 ) )
     866             :     {
     867       85360 :         *p_theta = L_negate( theta_hat_fx ); // Q22
     868       85360 :         move32();
     869             :     }
     870      285945 :     *p_phi = L_sub( phi_hat_fx, L_shl( 180, Q22 ) ); // Q22
     871      285945 :     move32();
     872             : 
     873             :     /* Starting from Equator, alternating positive and negative */
     874      285945 :     IF( id_th == 0 )
     875             :     {
     876      126962 :         idx_sph = id_phi;
     877      126962 :         move16();
     878             :     }
     879             :     ELSE
     880             :     {
     881      158983 :         IF( EQ_16( id_th, sub( gridData->no_theta, 1 ) ) )
     882             :         {
     883         218 :             idx_sph = 65534; // Q0
     884         218 :             move16();
     885         218 :             if ( sign_th < 0 )
     886             :             {
     887         184 :                 idx_sph = 65535; // Q0
     888         184 :                 move16();
     889             :             }
     890             :         }
     891             :         ELSE
     892             :         {
     893      158765 :             cum_n = cum_n_for_id_th[id_th]; // Q0
     894      158765 :             move16();
     895             : 
     896      158765 :             cum_n = (UWord16) L_add( cum_n, gridData->no_phi[0] ); // Q0
     897             : 
     898      158765 :             IF( sign_th > 0 )
     899             :             {
     900       74343 :                 cum_n = (UWord16) L_sub( cum_n, shl( gridData->no_phi[id_th], 1 ) ); // Q0
     901             :             }
     902             :             ELSE
     903             :             {
     904       84422 :                 cum_n = (UWord16) L_sub( cum_n, gridData->no_phi[id_th] ); // Q0
     905             :             }
     906      158765 :             idx_sph = (UWord16) L_add( cum_n, id_phi ); // Q0
     907             :         }
     908             :     }
     909             : 
     910      285945 :     return idx_sph; // Q0
     911             : }
     912             : 
     913             : 
     914             : /*-------------------------------------------------------------------------
     915             :  * quantize_theta_masa()
     916             :  *
     917             :  *
     918             :  *------------------------------------------------------------------------*/
     919             : 
     920             : /*! r: output index */
     921      285945 : static Word16 quantize_theta_masa_fx(
     922             :     const Word32 x_fx,  /* i  : theta value to be quantized  Q22*/
     923             :     const Word16 no_cb, /* i  : number of codewords          */
     924             :     Word32 *xhat_fx     /* o  : quantized value              Q22*/
     925             : )
     926             : {
     927             :     Word16 imin;
     928             :     Word32 diff1_fx, diff2_fx;
     929             : 
     930      285945 :     imin = extract_l( L_shr( L_add( Mpy_32_32( x_fx, MASA_INV_ANGLE_AT_EQUATOR_DEG_Q30 ), ONE_IN_Q20 ), 21 ) ); // 22 + 30 - 31 = 21 -> Q21 - 21 = Q0
     931             : 
     932      285945 :     IF( GE_16( imin, sub( no_cb, 1 ) ) )
     933             :     {
     934         223 :         imin = sub( no_cb, 1 );
     935         223 :         diff1_fx = L_sub( x_fx, L_shl( 90, Q22 ) );                                                       // Q22
     936         223 :         diff2_fx = L_sub( x_fx, Mpy_32_16_1( MASA_ANGLE_AT_EQUATOR_DEG_Q31, shl( sub( imin, 1 ), 6 ) ) ); // q31 + q0+6 - 15 = q22
     937         223 :         IF( GT_32( L_abs( diff1_fx ), L_abs( diff2_fx ) ) )
     938             :         {
     939           5 :             imin = sub( imin, 1 );
     940           5 :             *xhat_fx = Mpy_32_16_1( MASA_ANGLE_AT_EQUATOR_DEG_Q31, shl( imin, 6 ) ); // 31 + 6 - 15 = Q22
     941           5 :             move32();
     942             :         }
     943             :         ELSE
     944             :         {
     945         218 :             *xhat_fx = L_shl( 90, Q22 ); // Q22
     946         218 :             move32();
     947             :         }
     948             :     }
     949             :     ELSE
     950             :     {
     951      285722 :         *xhat_fx = Mpy_32_16_1( MASA_ANGLE_AT_EQUATOR_DEG_Q31, shl( imin, 6 ) ); // 31 + 6 - 15 = Q22
     952      285722 :         move32();
     953             :     }
     954             : 
     955      285945 :     return imin;
     956             : }
     957             : 
     958             : 
     959             : /*-------------------------------------------------------------------------
     960             :  * quantize_phi_masa()
     961             :  *
     962             :  *
     963             :  *------------------------------------------------------------------------*/
     964             : 
     965             : /*! r: index azimuth */
     966      285727 : static Word16 quantize_phi_masa_fx(
     967             :     const Word32 phi_fx,     /* i  : azimuth value                                                  Q22 */
     968             :     const Word16 flag_delta, /* i  : flag indicating if the azimuth codebook is translated or not    */
     969             :     Word32 *phi_hat_fx,      /* o  : quantized azimuth                                              Q22 */
     970             :     const Word16 n           /* i  : azimuth codebook size                                           */
     971             : )
     972             : {
     973             :     Word16 id_phi;
     974             : 
     975             :     Word32 dd_fx;
     976             :     Word32 delta_phi_fx;
     977             :     Word32 tmp32;
     978             :     Word16 tmp_e, delta_phi_e;
     979             : 
     980      285727 :     delta_phi_fx = BASOP_Util_Divide3232_Scale_newton( 360, n, &delta_phi_e );
     981      285727 :     delta_phi_fx = L_shr( delta_phi_fx, sub( sub( 31, delta_phi_e ), 22 ) ); // Q22
     982             : 
     983      285727 :     IF( EQ_16( n, 1 ) )
     984             :     {
     985           0 :         *phi_hat_fx = 0;
     986           0 :         move32();
     987             : 
     988           0 :         return 0;
     989             :     }
     990             : 
     991      285727 :     IF( EQ_16( flag_delta, 1 ) )
     992             :     {
     993      101291 :         dd_fx = L_shr( delta_phi_fx, 1 ); // Q22
     994             :     }
     995             :     ELSE
     996             :     {
     997      184436 :         dd_fx = 0;
     998      184436 :         move32();
     999             :     }
    1000             : 
    1001      285727 :     tmp32 = L_add( L_sub( phi_fx, dd_fx ), L_shr( delta_phi_fx, 1 ) );
    1002      285727 :     tmp32 = BASOP_Util_Divide3232_Scale_newton( tmp32, delta_phi_fx, &tmp_e );
    1003      285727 :     id_phi = extract_l( L_shr( tmp32, sub( 31, tmp_e ) ) ); // Q0
    1004             : 
    1005      285727 :     if ( EQ_16( id_phi, n ) )
    1006             :     {
    1007          22 :         id_phi = 0;
    1008          22 :         move16();
    1009             :     }
    1010             : 
    1011      285727 :     if ( EQ_16( id_phi, -1 ) )
    1012             :     {
    1013           0 :         id_phi = sub( n, 1 );
    1014             :     }
    1015             : 
    1016      285727 :     delta_phi_fx = BASOP_Util_Divide3232_Scale_newton( L_mult0( 360, id_phi ), n, &delta_phi_e );
    1017      285727 :     delta_phi_fx = L_shr( delta_phi_fx, sub( sub( 31, delta_phi_e ), 22 ) ); // Q22
    1018             : 
    1019      285727 :     *phi_hat_fx = L_add( delta_phi_fx, dd_fx ); // Q22
    1020      285727 :     move32();
    1021             : 
    1022      285727 :     return id_phi; // Q0
    1023             : }
    1024             : 
    1025             : 
    1026             : /*-------------------------------------------------------------------------
    1027             :  * deindex_sph_idx()
    1028             :  *
    1029             :  *  deindex the MASA metadata from the input metadata file
    1030             :  *------------------------------------------------------------------------*/
    1031             : 
    1032     5932416 : void deindex_sph_idx_fx(
    1033             :     const UWord16 sphIndex,              /* i  : Spherical index            */
    1034             :     const SPHERICAL_GRID_DATA *gridData, /* i  : Prepared spherical grid    */
    1035             :     Word32 *theta_fx,                    /* o  : Elevation                  Q22*/
    1036             :     Word32 *phi_fx                       /* o  : Azimuth                   Q22 */
    1037             : )
    1038             : {
    1039             :     Word32 ba_crt_fx, del_crt_fx, div_crt_fx, a4_crt_fx;
    1040             :     Word32 estim_fx;
    1041             :     Word32 base_low, base_up;
    1042             :     Word16 n_crt;
    1043             :     Word16 id_th;
    1044             :     Word16 sign_theta;
    1045             :     Word16 id_phi;
    1046     5932416 :     Word16 no_th = gridData->no_theta;
    1047     5932416 :     const Word16 *n = gridData->no_phi;
    1048             :     const Word32 ba_fx[3] = { 1793476992, 1044259584, 1030463872 };   /* Q23 */
    1049             :     const Word32 del_fx[3] = { 819022016, 1332105216, 1458249984 };   /* Q10 */
    1050             :     const Word32 div_fx[3] = { -510376000, -216763104, -197676320 };  /* Q31 */
    1051             :     const Word32 a4_fx[3] = { -564741248, -1329702144, -1458092544 }; /* Q26 */
    1052     5932416 :     const UWord16 limit_index1 = 64964, limit_index2 = 47870;
    1053             :     Word32 tmp32;
    1054             :     Word16 tmp16, tmp_e;
    1055     5932416 :     move16();
    1056     5932416 :     move16();
    1057     5932416 :     move16();
    1058     5932416 :     move32();
    1059     5932416 :     move32();
    1060     5932416 :     move32();
    1061     5932416 :     move32();
    1062     5932416 :     move32();
    1063     5932416 :     move32();
    1064     5932416 :     move32();
    1065     5932416 :     move32();
    1066     5932416 :     move32();
    1067     5932416 :     move32();
    1068     5932416 :     move32();
    1069     5932416 :     move32();
    1070             : 
    1071     5932416 :     IF( GE_32( sphIndex, limit_index1 ) )
    1072             :     {
    1073       15726 :         ba_crt_fx = ba_fx[2];
    1074       15726 :         move32();
    1075       15726 :         div_crt_fx = div_fx[2];
    1076       15726 :         move32();
    1077       15726 :         a4_crt_fx = a4_fx[2];
    1078       15726 :         move32();
    1079       15726 :         del_crt_fx = del_fx[2];
    1080       15726 :         move32();
    1081             :     }
    1082     5916690 :     ELSE IF( GE_32( sphIndex, limit_index2 ) )
    1083             :     {
    1084      545381 :         ba_crt_fx = ba_fx[1];
    1085      545381 :         move32();
    1086      545381 :         div_crt_fx = div_fx[1];
    1087      545381 :         move32();
    1088      545381 :         a4_crt_fx = a4_fx[1];
    1089      545381 :         move32();
    1090      545381 :         del_crt_fx = del_fx[1];
    1091      545381 :         move32();
    1092             :     }
    1093             :     ELSE
    1094             :     {
    1095     5371309 :         ba_crt_fx = ba_fx[0];
    1096     5371309 :         move32();
    1097     5371309 :         div_crt_fx = div_fx[0];
    1098     5371309 :         move32();
    1099     5371309 :         a4_crt_fx = a4_fx[0];
    1100     5371309 :         move32();
    1101     5371309 :         del_crt_fx = del_fx[0];
    1102     5371309 :         move32();
    1103             :     }
    1104     5932416 :     tmp32 = Mpy_32_32( a4_crt_fx, L_shl_sat( sphIndex, Q15 ) ); /* Q10 */
    1105     5932416 :     tmp32 = L_add( del_crt_fx, tmp32 );                         /* Q10 */
    1106     5932416 :     tmp16 = Q31 - Q10;
    1107     5932416 :     move16();
    1108     5932416 :     tmp32 = Sqrt32( tmp32, &tmp16 );          // Q31-tmp16
    1109     5932416 :     tmp32 = Mpy_32_32( div_crt_fx, tmp32 );   // Q31-tmp16
    1110     5932416 :     tmp32 = L_shr( tmp32, sub( Q8, tmp16 ) ); /* Q23 */
    1111     5932416 :     estim_fx = L_add( ba_crt_fx, tmp32 );     /* Q23 */
    1112             : 
    1113     5932416 :     if ( GT_32( estim_fx, MASA_NO_CIRCLES_Q23 ) )
    1114             :     {
    1115         640 :         estim_fx = MASA_NO_CIRCLES_Q23; // Q23
    1116         640 :         move32();
    1117             :     }
    1118             : 
    1119     5932416 :     assert( estim_fx > 0 );
    1120     5932416 :     id_th = sub( extract_l( L_shr_r( estim_fx, Q23 ) ), 1 ); /* Q0 */
    1121     5932416 :     if ( id_th < 0 )
    1122             :     {
    1123           0 :         id_th = 0;
    1124           0 :         move16();
    1125             :     }
    1126             : 
    1127     5932416 :     IF( id_th == 0 )
    1128             :     {
    1129       69244 :         base_low = 0;
    1130       69244 :         move32();
    1131       69244 :         base_up = n[0];
    1132       69244 :         move32();
    1133             :     }
    1134             :     ELSE
    1135             :     {
    1136     5863172 :         base_low = n[0];
    1137     5863172 :         move32();
    1138     5863172 :         IF( GE_16( id_th, 2 ) )
    1139             :         {
    1140     5574546 :             IF( EQ_16( id_th, 2 ) )
    1141             :             {
    1142      293749 :                 base_low = L_add( base_low, L_shl( estim_ceil[id_th], 1 ) ); /* Q0 */
    1143             :             }
    1144             :             ELSE
    1145             :             {
    1146     5280797 :                 base_low = L_add( base_low, L_shl( estim_round[id_th], 1 ) ); /* Q0 */
    1147             :             }
    1148             :         }
    1149     5863172 :         base_up = L_add( base_low, L_shl( n[id_th], 1 ) );
    1150             :     }
    1151             : 
    1152     5932416 :     sign_theta = 1;
    1153     5932416 :     move16();
    1154             : 
    1155     5932416 :     n_crt = n[id_th];
    1156     5932416 :     move16();
    1157     5932416 :     IF( LT_32( sphIndex, base_low ) )
    1158             :     {
    1159      299227 :         id_th = sub( id_th, 1 );
    1160      299227 :         n_crt = n[id_th];
    1161      299227 :         move16();
    1162      299227 :         IF( id_th == 0 )
    1163             :         {
    1164       74926 :             base_low = 0;
    1165       74926 :             move32();
    1166       74926 :             base_up = n_crt;
    1167       74926 :             move32();
    1168             :         }
    1169             :         ELSE
    1170             :         {
    1171      224301 :             base_up = base_low;
    1172      224301 :             move32();
    1173      224301 :             base_low = L_sub( base_low, shl( n[id_th], 1 ) );
    1174             :         }
    1175      299227 :         assert( sphIndex >= base_low );
    1176             :     }
    1177     5633189 :     ELSE IF( GE_32( sphIndex, base_up ) )
    1178             :     {
    1179      188638 :         id_th = add( id_th, 1 );
    1180      188638 :         n_crt = n[id_th];
    1181      188638 :         move16();
    1182      188638 :         base_low = base_up;
    1183      188638 :         move32();
    1184      188638 :         base_up = L_add( base_up, shl( n_crt, 1 ) );
    1185      188638 :         assert( sphIndex < base_up );
    1186             :     }
    1187             : 
    1188     5932416 :     id_phi = extract_l( L_sub( sphIndex, base_low ) );
    1189     5932416 :     IF( GE_32( L_sub( sphIndex, base_low ), n_crt ) )
    1190             :     {
    1191     3578401 :         id_phi = sub( id_phi, n_crt );
    1192     3578401 :         sign_theta = -1;
    1193     3578401 :         move16();
    1194             :     }
    1195             : 
    1196     5932416 :     IF( id_th == 0 )
    1197             :     {
    1198      144170 :         *theta_fx = 0;
    1199      144170 :         move32();
    1200      144170 :         tmp32 = imult3216( sphIndex, 360 );
    1201      144170 :         tmp16 = BASOP_Util_Divide3232_Scale( tmp32, n_crt, &tmp_e );
    1202      144170 :         tmp32 = L_shl( tmp16, add( Q7, tmp_e ) ); /* Q22 */
    1203      144170 :         *phi_fx = L_sub( tmp32, 180 << Q22 );     /* Q22 */
    1204      144170 :         move32();
    1205             :     }
    1206             :     ELSE
    1207             :     {
    1208     5788246 :         IF( EQ_16( id_th, sub( no_th, 1 ) ) )
    1209             :         {
    1210         273 :             id_phi = 0;
    1211         273 :             move16();
    1212         273 :             *phi_fx = -754974720; /* -180 in Q22 */
    1213         273 :             move32();
    1214         273 :             *theta_fx = L_shl( L_mult0( 90, sign_theta ), Q22 ); /* Q22 */
    1215         273 :             move32();
    1216             :         }
    1217             :         ELSE
    1218             :         {
    1219     5787973 :             *theta_fx = Mpy_32_32( L_shl( id_th, Q22 ), MASA_ANGLE_AT_EQUATOR_DEG_Q31 ); /* Q22 */
    1220     5787973 :             move32();
    1221     5787973 :             if ( EQ_16( sign_theta, -1 ) )
    1222             :             {
    1223     3578217 :                 *theta_fx = L_negate( *theta_fx ); /* Q22 */
    1224     3578217 :                 move32();
    1225             :             }
    1226     5787973 :             IF( id_th % 2 == 0 )
    1227             :             {
    1228     2826907 :                 tmp32 = L_mult0( id_phi, 360 );
    1229     2826907 :                 tmp16 = BASOP_Util_Divide3232_Scale( tmp32, n_crt, &tmp_e );
    1230     2826907 :                 tmp32 = L_shl( tmp16, add( Q7, tmp_e ) ); /* Q22 */
    1231     2826907 :                 *phi_fx = L_sub( tmp32, 180 << Q22 );     /* Q22 */
    1232     2826907 :                 move32();
    1233             :             }
    1234             :             ELSE
    1235             :             {
    1236     2961066 :                 tmp32 = L_add( L_mult0( id_phi, 360 ), 180 );
    1237     2961066 :                 tmp16 = BASOP_Util_Divide3232_Scale( tmp32, n_crt, &tmp_e );
    1238     2961066 :                 tmp32 = L_shl( tmp16, add( Q7, tmp_e ) ); /* Q22 */
    1239     2961066 :                 *phi_fx = L_sub( tmp32, 180 << Q22 );     /* Q22 */
    1240     2961066 :                 move32();
    1241             :             }
    1242             :         }
    1243             :     }
    1244     5932416 :     return;
    1245             : }
    1246             : /*---------------------------------------------------------------
    1247             :  * valid_ratio_index()
    1248             :  *
    1249             :  * Checking validity of the index of an ISM ratio index vector,
    1250             :  * within the indexing function.
    1251             :  *---------------------------------------------------------------*/
    1252             : 
    1253             : /*! r: valid or not 1/0 */
    1254     1833696 : Word16 valid_ratio_index_fx(
    1255             :     Word16 index,    /* i  : index to be checked        */
    1256             :     const Word16 K,  /* i  : L1 norm to check against   */
    1257             :     const Word16 len /* i  : vector length              */
    1258             : )
    1259             : {
    1260             :     Word16 out;
    1261             :     Word16 i, sum, elem;
    1262             :     Word16 base[4];
    1263             : 
    1264     1833696 :     sum = 0;
    1265     1833696 :     move16();
    1266     1833696 :     set16_fx( base, 1, len );
    1267             : 
    1268     5467216 :     FOR( i = 1; i < len; i++ )
    1269             :     {
    1270     3633520 :         base[i] = i_mult( base[i - 1], 10 );
    1271     3633520 :         move16();
    1272             :     }
    1273     1833696 :     sum = 0;
    1274     1833696 :     move16();
    1275     7300912 :     FOR( i = len - 1; i >= 0; i-- )
    1276             :     {
    1277     5467216 :         IF( index == 0 )
    1278             :         {
    1279      229017 :             elem = 0;
    1280      229017 :             move16();
    1281             :         }
    1282             :         ELSE
    1283             :         {
    1284     5238199 :             elem = idiv1616( index, base[i] );
    1285             :         }
    1286     5467216 :         sum = add( sum, elem );
    1287     5467216 :         index = sub( index, i_mult( elem, base[i] ) );
    1288             :     }
    1289     1833696 :     IF( LE_16( sum, K ) )
    1290             :     {
    1291      502747 :         out = 1;
    1292      502747 :         move16();
    1293             :     }
    1294             :     ELSE
    1295             :     {
    1296     1330949 :         out = 0;
    1297     1330949 :         move16();
    1298             :     }
    1299             : 
    1300     1833696 :     return out;
    1301             : }
    1302             : 
    1303             : 
    1304             : /*---------------------------------------------------------------
    1305             :  * reconstruct_ism_ratios()
    1306             :  *
    1307             :  * Obtains ISM ratio values from the quantized indexes
    1308             :  *---------------------------------------------------------------*/
    1309             : 
    1310       60559 : void reconstruct_ism_ratios_fx(
    1311             :     Word16 *ratio_ism_idx,     /* i  : index vector                 Q0  */
    1312             :     const Word16 nchan_ism,    /* i  : number of components/objects Q0  */
    1313             :     const Word32 step,         /* i  : quantization step            Q31 */
    1314             :     Word32 *q_energy_ratio_ism /* o  : reconstructed ISM values     Q30 */
    1315             : )
    1316             : {
    1317             :     Word16 i;
    1318             :     Word32 sum;
    1319             : 
    1320       60559 :     sum = 0;
    1321       60559 :     move32();
    1322             : 
    1323      213350 :     FOR( i = 0; i < nchan_ism - 1; i++ )
    1324             :     {
    1325      152791 :         q_energy_ratio_ism[i] = W_extract_l( W_shr( W_mult_32_16( step, ratio_ism_idx[i] ), 2 ) ); // q0 + q31 + 1 - 2 = q30;
    1326      152791 :         move32();
    1327             : 
    1328      152791 :         sum = L_add( sum, q_energy_ratio_ism[i] ); // Q30
    1329             :     }
    1330             : 
    1331       60559 :     q_energy_ratio_ism[nchan_ism - 1] = L_sub( ONE_IN_Q30, sum );
    1332       60559 :     move32();
    1333             : 
    1334       60559 :     if ( q_energy_ratio_ism[nchan_ism - 1] < 0 )
    1335             :     {
    1336           0 :         q_energy_ratio_ism[nchan_ism - 1] = 0;
    1337           0 :         move32();
    1338             :     }
    1339             : 
    1340       60559 :     return;
    1341             : }
    1342             : 
    1343             : 
    1344             : /*---------------------------------------------------------------
    1345             :  * ivas_omasa_modify_masa_energy_ratios()
    1346             :  *
    1347             :  * Updates energy ratios by taking into account the MASA content contribution
    1348             :  * to the total audio scene
    1349             :  *---------------------------------------------------------------*/
    1350             : 
    1351        3696 : void ivas_omasa_modify_masa_energy_ratios_fx(
    1352             :     IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle  */
    1353             :     Word32 masa_to_total_energy_ratio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_MAXIMUM_CODING_SUBBANDS] /* Q30 */ )
    1354             : {
    1355             :     Word16 i, m, d, b;
    1356             : 
    1357       18480 :     FOR( m = 0; m < MAX_PARAM_SPATIAL_SUBFRAMES; m++ )
    1358             :     {
    1359       14784 :         IF( EQ_16( hQMetaData->q_direction[0].cfg.nblocks, 1 ) )
    1360             :         {
    1361        4740 :             i = 0;
    1362        4740 :             move16();
    1363             :         }
    1364             :         ELSE
    1365             :         {
    1366       10044 :             i = m;
    1367       10044 :             move16();
    1368             :         }
    1369             : 
    1370      108616 :         FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
    1371             :         {
    1372      208544 :             FOR( d = 0; d < hQMetaData->no_directions; d++ )
    1373             :             {
    1374      114712 :                 hQMetaData->q_direction[d].band_data[b].energy_ratio_fx[m] = L_shl(
    1375      114712 :                     Mpy_32_32( hQMetaData->q_direction[d].band_data[b].energy_ratio_fx[m],
    1376      114712 :                                masa_to_total_energy_ratio_fx[i][b] ),
    1377             :                     1 ); // Q30 + Q30 - 31 = Q29 + 1 = Q30
    1378      114712 :                 move32();
    1379             :             }
    1380             :         }
    1381             :     }
    1382             : 
    1383        3696 :     return;
    1384             : }
    1385             : 
    1386             : 
    1387             : /*---------------------------------------------------------------
    1388             :  * distribute_evenly_ism()
    1389             :  *
    1390             :  * Obtain ISM ratio indexes for even content distribution bbetween objects
    1391             :  *---------------------------------------------------------------*/
    1392             : 
    1393        7192 : void distribute_evenly_ism_fx(
    1394             :     Word16 *idx,           /* o  : index values       Q0 */
    1395             :     const Word16 K,        /* i  : sum of indexes      Q0*/
    1396             :     const Word16 nchan_ism /* i  : number of objects  Q0 */
    1397             : )
    1398             : {
    1399             :     Word16 i;
    1400             :     Word16 sum;
    1401             : 
    1402        7192 :     sum = 0;
    1403        7192 :     move16();
    1404       31486 :     FOR( i = 0; i < nchan_ism; i++ )
    1405             :     {
    1406       24294 :         IF( K == 0 )
    1407             :         {
    1408           0 :             idx[i] = 0;
    1409           0 :             move16();
    1410             :         }
    1411             :         ELSE
    1412             :         {
    1413       24294 :             idx[i] = idiv1616( K, nchan_ism ); // Q0
    1414       24294 :             move16();
    1415             :         }
    1416       24294 :         sum = add( sum, idx[i] );
    1417             :     }
    1418             : 
    1419        7192 :     assert( LE_16( sum, K ) );
    1420             : 
    1421        7192 :     i = 0;
    1422        7192 :     move16();
    1423       21468 :     WHILE( LT_16( sum, K ) )
    1424             :     {
    1425       14276 :         if ( EQ_16( i, nchan_ism ) )
    1426             :         {
    1427           0 :             i = 0;
    1428           0 :             move16();
    1429             :         }
    1430       14276 :         idx[i] = add( idx[i], 1 );
    1431       14276 :         move16();
    1432       14276 :         sum = add( sum, 1 );
    1433       14276 :         i = add( i, 1 );
    1434             :     }
    1435             : 
    1436        7192 :     return;
    1437             : }
    1438             : 
    1439             : 
    1440             : /*---------------------------------------------------------------
    1441             :  * calculate_cpe_brate_MASA_ISM()
    1442             :  *
    1443             :  * Calculates bitrate for MASA_ISM mode that is not used for separated objects,
    1444             :  * * but for the CPE part (metadata included)
    1445             :  *---------------------------------------------------------------*/
    1446             : 
    1447             : /*! r: CPE bitrate value       */
    1448       18111 : Word32 calculate_cpe_brate_MASA_ISM_fx(
    1449             :     const ISM_MODE ism_mode,       /* i  : ism mode                */
    1450             :     const Word32 ivas_total_brate, /* i  : IVAS total bitrate      */
    1451             :     const Word16 nchan_ism         /* i  : number of objects       */
    1452             : )
    1453             : {
    1454             :     Word32 cpe_brate;
    1455             :     Word16 k, sce_id;
    1456             : 
    1457       18111 :     k = 0;
    1458       18111 :     move16();
    1459             : 
    1460      201275 :     WHILE( LT_16( k, SIZE_IVAS_BRATE_TBL ) && NE_32( ivas_total_brate, ivas_brate_tbl[k] ) )
    1461             :     {
    1462      183164 :         test();
    1463      183164 :         k = add( k, 1 );
    1464             :     }
    1465             : 
    1466       18111 :     test();
    1467       18111 :     IF( EQ_16( ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) || EQ_16( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
    1468             :     {
    1469        4691 :         cpe_brate = L_sub( ivas_total_brate, sep_object_brate[k - 2][0] ); /* take data from the first column */
    1470             :     }
    1471       13420 :     ELSE IF( EQ_16( ism_mode, ISM_MASA_MODE_DISC ) )
    1472             :     {
    1473       12975 :         cpe_brate = ivas_total_brate;
    1474       12975 :         move32();
    1475             : 
    1476       48081 :         FOR( sce_id = 0; sce_id < nchan_ism; sce_id++ )
    1477             :         {
    1478       35106 :             cpe_brate = L_sub( cpe_brate, sep_object_brate[k - 2][nchan_ism - 1] );
    1479             :         }
    1480             :     }
    1481             :     ELSE
    1482             :     {
    1483         445 :         cpe_brate = ivas_total_brate;
    1484         445 :         move32();
    1485             :     }
    1486             : 
    1487       18111 :     return cpe_brate;
    1488             : }

Generated by: LCOV version 1.14