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

Generated by: LCOV version 1.14