LCOV - code coverage report
Current view: top level - lib_com - ivas_masa_com_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 633e3f2e309758d10805ef21e0436356fe719b7a Lines: 519 541 95.9 %
Date: 2025-08-23 01:22:27 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       51854 : 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       51854 :     IF( EQ_16( nchan_transport, 2 ) )
     347             :     {
     348       27374 :         test();
     349       27374 :         test();
     350       27374 :         IF( GE_32( ivas_total_brate, MCMASA_SEPARATE_BRATE ) && EQ_16( mc_mode, MC_MODE_MCMASA ) )
     351             :         {
     352         606 :             *nCPE = 1;
     353         606 :             move16();
     354         606 :             *nSCE = 1;
     355         606 :             move16();
     356             : 
     357         606 :             *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         606 :             move16();
     359             :         }
     360       26768 :         ELSE IF( EQ_16( ivas_format, MASA_ISM_FORMAT ) && ism_mode != ISM_MODE_NONE )
     361             :         {
     362        7577 :             *nCPE = 1;
     363        7577 :             move16();
     364             : 
     365        7577 :             if ( EQ_16( *element_mode, -1 ) )
     366             :             {
     367        6423 :                 *element_mode = IVAS_CPE_DFT; /* To have it initialized in case it was not already. */
     368        6423 :                 move16();
     369             :             }
     370        7577 :             IF( GT_32( ivas_total_brate, MIN_BRATE_MDCT_STEREO ) )
     371             :             {
     372        4935 :                 *element_mode = IVAS_CPE_MDCT;
     373        4935 :                 move16();
     374        4935 :                 test();
     375        4935 :                 test();
     376        4935 :                 test();
     377        4935 :                 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         650 :                     *element_mode = IVAS_CPE_DFT;
     380         650 :                     move16();
     381             :                 }
     382             :             }
     383             :         }
     384             :         ELSE
     385             :         {
     386       19191 :             *nCPE = 1;
     387       19191 :             move16();
     388       19191 :             *nSCE = 0;
     389       19191 :             move16();
     390             : 
     391       19191 :             if ( GT_32( ivas_total_brate, MIN_BRATE_MDCT_STEREO ) )
     392             :             {
     393        8886 :                 *element_mode = IVAS_CPE_MDCT;
     394        8886 :                 move16();
     395             :             }
     396             :         }
     397             :         /* hQMetaData->bits_frame_nominal = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC ); */
     398       27374 :         hQMetaData->bits_frame_nominal = extract_l( Mpy_32_32( ivas_total_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) );
     399       27374 :         test();
     400       27374 :         test();
     401       27374 :         test();
     402       27374 :         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        7577 :             tmp = extract_l( Mpy_32_32( ism_total_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) );
     406        7577 :             hQMetaData->bits_frame_nominal = sub( hQMetaData->bits_frame_nominal, tmp );
     407             :         }
     408             :     }
     409       24480 :     ELSE IF( GE_16( nchan_transport, 1 ) )
     410             :     {
     411       24480 :         *nCPE = 0;
     412       24480 :         move16();
     413       24480 :         *nSCE = 1;
     414       24480 :         move16();
     415             : 
     416       24480 :         IF( EQ_32( ivas_total_brate, IVAS_13k2 ) )
     417             :         {
     418        4070 :             hQMetaData->bits_frame_nominal = ACELP_9k60 / FRAMES_PER_SEC;
     419        4070 :             move16();
     420             :         }
     421       20410 :         ELSE IF( LE_32( ivas_total_brate, IVAS_16k4 ) )
     422             :         {
     423        1379 :             hQMetaData->bits_frame_nominal = ACELP_13k20 / FRAMES_PER_SEC;
     424        1379 :             move16();
     425             :         }
     426       19031 :         ELSE IF( LE_32( ivas_total_brate, IVAS_24k4 ) )
     427             :         {
     428        8831 :             hQMetaData->bits_frame_nominal = ACELP_16k40 / FRAMES_PER_SEC;
     429        8831 :             move16();
     430             :         }
     431       10200 :         ELSE IF( LE_32( ivas_total_brate, IVAS_32k ) )
     432             :         {
     433        3460 :             hQMetaData->bits_frame_nominal = ACELP_24k40 / FRAMES_PER_SEC;
     434        3460 :             move16();
     435             :         }
     436             :         ELSE
     437             :         {
     438        6740 :             hQMetaData->bits_frame_nominal = extract_l( Mpy_32_32( ivas_total_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) );
     439             :         }
     440       24480 :         *element_mode = IVAS_SCE;
     441       24480 :         move16();
     442             :     }
     443             :     ELSE
     444             :     {
     445           0 :         assert( !"MASA number of transport channels must be 1, or 2" );
     446             :     }
     447             : 
     448       51854 :     return;
     449             : }
     450             : 
     451             : 
     452             : /*---------------------------------------------------------------
     453             :  * generate_gridEq()
     454             :  *
     455             :  * generate Spherical grid
     456             :  *---------------------------------------------------------------*/
     457             : 
     458          99 : 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          99 :     Copy( gridEq_Table, data->no_phi, NO_THETA16_MAX );
     473             : 
     474          99 :     data->no_theta = NO_THETA16_MAX;
     475          99 :     move16();
     476             : 
     477          99 :     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       48598 : 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       48598 :     nbands = 0;
     510       48598 :     move16();
     511       48598 :     nTwoDirBands = 0;
     512       48598 :     move16();
     513       48598 :     i = 0;
     514       48598 :     move16();
     515             : 
     516             :     /* First select correct bit budget table */
     517       48598 :     masa_bits_table = masa_bits;
     518             : 
     519       48598 :     test();
     520       48598 :     IF( isMcMasa )
     521             :     {
     522       11531 :         masa_bits_table = mcmasa_bits;
     523             :     }
     524       37067 :     ELSE IF( LT_32( ivas_total_brate, IVAS_48k ) && EQ_16( nchan_transport, 2 ) )
     525             :     {
     526       11197 :         masa_bits_table = masa_bits_LR_stereo;
     527             :     }
     528             : 
     529      299395 :     WHILE( nbands == 0 && LT_16( i, IVAS_NUM_ACTIVE_BRATES ) )
     530             :     {
     531      250797 :         test();
     532      250797 :         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       48598 :             test();
     537       48598 :             test();
     538       48598 :             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         368 :                 i = 3;
     542         368 :                 move16();
     543             :             }
     544       48598 :             idx_bands = i;
     545       48598 :             move16();
     546             : 
     547       48598 :             IF( GT_16( config->numberOfDirections, 1 ) )
     548             :             {
     549        5307 :                 IF( config->joinedSubframes )
     550             :                 {
     551         978 :                     nTwoDirBands = masa_twodir_bands_joined[i];
     552         978 :                     move16();
     553             :                 }
     554             :                 ELSE
     555             :                 {
     556        4329 :                     nTwoDirBands = masa_twodir_bands[i];
     557        4329 :                     move16();
     558             :                 }
     559             : 
     560        5307 :                 test();
     561        5307 :                 test();
     562        5307 :                 test();
     563        5307 :                 if ( ( GT_32( ivas_total_brate, IVAS_96k ) && !config->joinedSubframes ) || ( GT_32( ivas_total_brate, IVAS_80k ) && config->joinedSubframes ) )
     564             :                 {
     565        3709 :                     idx_bands = sub( idx_bands, 1 );
     566             :                 }
     567             :             }
     568             : 
     569       48598 :             IF( config->joinedSubframes )
     570             :             {
     571        5480 :                 nbands = masa_joined_nbands[idx_bands];
     572        5480 :                 move16();
     573             :             }
     574             :             ELSE
     575             :             {
     576       43118 :                 nbands = masa_nbands[idx_bands];
     577       43118 :                 move16();
     578             :             }
     579             : 
     580       48598 :             config->max_metadata_bits = (UWord16) masa_bits_table[i];
     581       48598 :             move16();
     582             : 
     583       48598 :             test();
     584       48598 :             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         544 :                 config->max_metadata_bits = (UWord16) add( config->max_metadata_bits, MASA_EXTRA_BAND_META_BITS );
     588         544 :                 move16();
     589             :             }
     590             : 
     591       48598 :             test();
     592       48598 :             test();
     593       48598 :             test();
     594       48598 :             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        1118 :                 config->max_metadata_bits = (UWord16) add( config->max_metadata_bits, MASA_SMALL_INC_META_BITS );
     598        1118 :                 move16();
     599             :             }
     600             :         }
     601      250797 :         i = add( i, 1 );
     602             :     }
     603       48598 :     config->numCodingBands = nbands;
     604       48598 :     move16();
     605       48598 :     config->numTwoDirBands = nTwoDirBands;
     606       48598 :     move16();
     607             : 
     608       48598 :     IF( EQ_16( config->joinedSubframes, TRUE ) )
     609             :     {
     610        5480 :         config->mergeRatiosOverSubframes = FALSE;
     611        5480 :         move16();
     612             :     }
     613             :     ELSE
     614             :     {
     615       43118 :         config->mergeRatiosOverSubframes = TRUE;
     616       43118 :         move16();
     617             :     }
     618             : 
     619             :     /* Setup frequency band mapping based on the number of used coding bands */
     620       48598 :     SWITCH( config->numCodingBands )
     621             :     {
     622       37439 :         case 5:
     623       37439 :             Copy( MASA_band_mapping_24_to_5, band_mapping, 5 + 1 );
     624       37439 :             BREAK;
     625        3400 :         case 8:
     626        3400 :             Copy( MASA_band_mapping_24_to_8, band_mapping, 8 + 1 );
     627        3400 :             BREAK;
     628        1988 :         case 12:
     629        1988 :             Copy( MASA_band_mapping_24_to_12, band_mapping, 12 + 1 );
     630        1988 :             BREAK;
     631        2179 :         case 18:
     632        2179 :             Copy( MASA_band_mapping_24_to_18, band_mapping, 18 + 1 );
     633        2179 :             BREAK;
     634        3592 :         case MASA_FREQUENCY_BANDS:
     635             :             /* With input count of bands, no mapping is needed but for unified processing later, we store normal mapping */
     636       93392 :             FOR( i = 0; i < MASA_FREQUENCY_BANDS + 1; i++ )
     637             :             {
     638       89800 :                 band_mapping[i] = i;
     639       89800 :                 move16();
     640             :             }
     641        3592 :             BREAK;
     642           0 :         default:
     643           0 :             assert( 0 && "Error: The number of MASA coding bands is not supported" );
     644             :     }
     645             : 
     646       48598 :     config->useCoherence = TRUE;
     647       48598 :     move16();
     648       48598 :     test();
     649       48598 :     test();
     650       48598 :     test();
     651       48598 :     if ( ( !isMcMasa && LT_32( ivas_total_brate, IVAS_48k ) ) || ( isMcMasa && LT_32( ivas_total_brate, IVAS_16k4 ) ) )
     652             :     {
     653       19171 :         config->useCoherence = FALSE;
     654       19171 :         move16();
     655             :     }
     656             : 
     657       48598 :     return;
     658             : }
     659             : 
     660             : 
     661             : /*---------------------------------------------------------------
     662             :  * masa_sample_rate_band_correction()
     663             :  *
     664             :  *
     665             :  *---------------------------------------------------------------*/
     666             : 
     667       48598 : 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       48598 :     numBands48k = config->numCodingBands;
     681       48598 :     move16();
     682             : 
     683      361214 :     FOR( band = 1; band < config->numCodingBands + 1; band++ )
     684             :     {
     685      361214 :         highBand = band_mapping[band];
     686      361214 :         move16();
     687             : 
     688      361214 :         IF( GE_16( highBand, (Word16) maxBand ) )
     689             :         {
     690       48598 :             config->numCodingBands = band;
     691       48598 :             move16();
     692       48598 :             hQMetaData->numCodingBands = band;
     693       48598 :             move16();
     694             : 
     695       48598 :             IF( is_encoder )
     696             :             {
     697           0 :                 if ( GT_16( hQMetaData->q_direction->cfg.nbands, (Word16) band ) )
     698             :                 {
     699           0 :                     hQMetaData->q_direction->cfg.nbands = band;
     700           0 :                     move16();
     701             :                 }
     702           0 :                 test();
     703           0 :                 if ( EQ_16( (Word16) hQMetaData->no_directions, 2 ) && GT_16( hQMetaData->q_direction[1].cfg.nbands, (Word16) band ) )
     704             :                 {
     705           0 :                     hQMetaData->q_direction[1].cfg.nbands = band;
     706           0 :                     move16();
     707             :                 }
     708             :             }
     709             : 
     710       48598 :             band_mapping[band] = maxBand;
     711       48598 :             move16();
     712             : 
     713       48598 :             BREAK;
     714             :         }
     715             :     }
     716             : 
     717             :     /* Set rest of the bands to zero in qmetadata. */
     718       51065 :     FOR( ; band < numBands48k; band++ )
     719             :     {
     720       12335 :         FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
     721             :         {
     722        9868 :             hQMetaData->q_direction[0].band_data[band].azimuth_fx[sf] = 0;
     723        9868 :             move32();
     724        9868 :             hQMetaData->q_direction[0].band_data[band].elevation_fx[sf] = 0;
     725        9868 :             move32();
     726        9868 :             hQMetaData->q_direction[0].band_data[band].energy_ratio_fx[sf] = 0;
     727        9868 :             move32();
     728             : 
     729        9868 :             test();
     730        9868 :             if ( hQMetaData->coherence_flag && hQMetaData->q_direction[0].coherence_band_data != NULL )
     731             :             {
     732        9868 :                 hQMetaData->q_direction[0].coherence_band_data[band].spread_coherence[sf] = 0u;
     733        9868 :                 move16();
     734             :             }
     735             : 
     736        9868 :             IF( EQ_16( (Word16) hQMetaData->no_directions, 2 ) )
     737             :             {
     738        1112 :                 hQMetaData->q_direction[1].band_data[band].azimuth_fx[sf] = 0;
     739        1112 :                 move32();
     740        1112 :                 hQMetaData->q_direction[1].band_data[band].elevation_fx[sf] = 0;
     741        1112 :                 move32();
     742        1112 :                 hQMetaData->q_direction[1].band_data[band].energy_ratio_fx[sf] = 0;
     743        1112 :                 move32();
     744             : 
     745        1112 :                 test();
     746        1112 :                 if ( hQMetaData->coherence_flag && hQMetaData->q_direction[1].coherence_band_data != NULL )
     747             :                 {
     748        1112 :                     hQMetaData->q_direction[1].coherence_band_data[band].spread_coherence[sf] = 0u;
     749        1112 :                     move16();
     750             :                 }
     751             :             }
     752             : 
     753        9868 :             test();
     754        9868 :             if ( hQMetaData->coherence_flag && hQMetaData->surcoh_band_data != NULL )
     755             :             {
     756        9868 :                 hQMetaData->surcoh_band_data[band].surround_coherence[sf] = 0u;
     757        9868 :                 move16();
     758             :             }
     759             :         }
     760             : 
     761        2467 :         if ( EQ_16( (Word16) hQMetaData->no_directions, 2 ) )
     762             :         {
     763         278 :             hQMetaData->twoDirBands[band] = 0;
     764         278 :             move16();
     765             :         }
     766             :     }
     767             : 
     768       48598 :     IF( hExtOutMeta != NULL )
     769             :     {
     770             :         /* in decoder, zero the EXT out MASA meta buffer */
     771       26435 :         FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
     772             :         {
     773      349428 :             FOR( band = hQMetaData->numCodingBands; band < MASA_FREQUENCY_BANDS; band++ )
     774             :             {
     775      328280 :                 hExtOutMeta->directionIndex[0][sf][band] = SPH_IDX_FRONT;
     776      328280 :                 move16();
     777      328280 :                 hExtOutMeta->directToTotalRatio[0][sf][band] = 0u;
     778      328280 :                 move16();
     779      328280 :                 hExtOutMeta->spreadCoherence[0][sf][band] = 0u;
     780      328280 :                 move16();
     781             : 
     782      328280 :                 hExtOutMeta->directionIndex[1][sf][band] = SPH_IDX_FRONT;
     783      328280 :                 move16();
     784      328280 :                 hExtOutMeta->directToTotalRatio[1][sf][band] = 0u;
     785      328280 :                 move16();
     786      328280 :                 hExtOutMeta->spreadCoherence[1][sf][band] = 0u;
     787      328280 :                 move16();
     788             : 
     789      328280 :                 hExtOutMeta->surroundCoherence[sf][band] = 0u;
     790      328280 :                 move16();
     791      328280 :                 hExtOutMeta->diffuseToTotalRatio[sf][band] = UINT8_MAX;
     792      328280 :                 move16();
     793             :             }
     794             :         }
     795             :     }
     796             : 
     797       48598 :     return;
     798             : }
     799             : 
     800             : 
     801             : /*-------------------------------------------------------------------------
     802             :  * index_theta_phi_16()
     803             :  *
     804             :  *
     805             :  *------------------------------------------------------------------------*/
     806             : 
     807             : /*! r: output index for direction */
     808      285856 : 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      285856 :     theta_fx = *p_theta; // Q22
     822      285856 :     move32();
     823      285856 :     phi_fx = *p_phi; // Q22
     824      285856 :     move32();
     825      285856 :     phi_hat_fx = 0;
     826      285856 :     move32();
     827      285856 :     theta_hat_fx = 0;
     828      285856 :     move32();
     829      285856 :     phi_fx = L_add( phi_fx, L_shl( 180, Q22 ) ); // Q22
     830             : 
     831      285856 :     IF( theta_fx < 0 )
     832             :     {
     833       85282 :         abs_theta_fx = L_negate( theta_fx ); // Q22
     834       85282 :         sign_th = -1;
     835       85282 :         move16();
     836             :     }
     837             :     ELSE
     838             :     {
     839      200574 :         abs_theta_fx = theta_fx; // Q22
     840      200574 :         move32();
     841      200574 :         sign_th = 1;
     842      200574 :         move16();
     843             :     }
     844             : 
     845      285856 :     id_th = quantize_theta_masa_fx( abs_theta_fx, gridData->no_theta, &theta_hat_fx );
     846      285856 :     IF( GT_16( gridData->no_theta, 1 ) )
     847             :     {
     848      285856 :         IF( GT_16( gridData->no_phi[id_th], 1 ) )
     849             :         {
     850      285638 :             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         218 :             id_phi = 0;
     855         218 :             move16();
     856         218 :             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      285856 :     *p_theta = theta_hat_fx;
     865      285856 :     move32();
     866      285856 :     if ( EQ_16( sign_th, -1 ) )
     867             :     {
     868       85282 :         *p_theta = L_negate( theta_hat_fx ); // Q22
     869       85282 :         move32();
     870             :     }
     871      285856 :     *p_phi = L_sub( phi_hat_fx, L_shl( 180, Q22 ) ); // Q22
     872      285856 :     move32();
     873             : 
     874             :     /* Starting from Equator, alternating positive and negative */
     875      285856 :     IF( id_th == 0 )
     876             :     {
     877      126967 :         idx_sph = id_phi;
     878      126967 :         move16();
     879             :     }
     880             :     ELSE
     881             :     {
     882      158889 :         IF( EQ_16( id_th, sub( gridData->no_theta, 1 ) ) )
     883             :         {
     884         218 :             idx_sph = 65534; // Q0
     885         218 :             move16();
     886         218 :             if ( sign_th < 0 )
     887             :             {
     888         184 :                 idx_sph = 65535; // Q0
     889         184 :                 move16();
     890             :             }
     891             :         }
     892             :         ELSE
     893             :         {
     894      158671 :             cum_n = cum_n_for_id_th[id_th]; // Q0
     895      158671 :             move16();
     896             : 
     897      158671 :             cum_n = (UWord16) L_add( cum_n, gridData->no_phi[0] ); // Q0
     898             : 
     899      158671 :             IF( sign_th > 0 )
     900             :             {
     901       74331 :                 cum_n = (UWord16) L_sub( cum_n, shl( gridData->no_phi[id_th], 1 ) ); // Q0
     902             :             }
     903             :             ELSE
     904             :             {
     905       84340 :                 cum_n = (UWord16) L_sub( cum_n, gridData->no_phi[id_th] ); // Q0
     906             :             }
     907      158671 :             idx_sph = (UWord16) L_add( cum_n, id_phi ); // Q0
     908             :         }
     909             :     }
     910             : 
     911      285856 :     return idx_sph; // Q0
     912             : }
     913             : 
     914             : 
     915             : /*-------------------------------------------------------------------------
     916             :  * quantize_theta_masa()
     917             :  *
     918             :  *
     919             :  *------------------------------------------------------------------------*/
     920             : 
     921             : /*! r: output index */
     922      285856 : 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      285856 :     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      285856 :     IF( GE_16( imin, sub( no_cb, 1 ) ) )
     934             :     {
     935         223 :         imin = sub( no_cb, 1 );
     936         223 :         diff1_fx = L_sub( x_fx, L_shl( 90, Q22 ) );                                                       // Q22
     937         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
     938         223 :         IF( GT_32( L_abs( diff1_fx ), L_abs( diff2_fx ) ) )
     939             :         {
     940           5 :             imin = sub( imin, 1 );
     941           5 :             *xhat_fx = Mpy_32_16_1( MASA_ANGLE_AT_EQUATOR_DEG_Q31, shl( imin, 6 ) ); // 31 + 6 - 15 = Q22
     942           5 :             move32();
     943             :         }
     944             :         ELSE
     945             :         {
     946         218 :             *xhat_fx = L_shl( 90, Q22 ); // Q22
     947         218 :             move32();
     948             :         }
     949             :     }
     950             :     ELSE
     951             :     {
     952      285633 :         *xhat_fx = Mpy_32_16_1( MASA_ANGLE_AT_EQUATOR_DEG_Q31, shl( imin, 6 ) ); // 31 + 6 - 15 = Q22
     953      285633 :         move32();
     954             :     }
     955             : 
     956      285856 :     return imin;
     957             : }
     958             : 
     959             : 
     960             : /*-------------------------------------------------------------------------
     961             :  * quantize_phi_masa()
     962             :  *
     963             :  *
     964             :  *------------------------------------------------------------------------*/
     965             : 
     966             : /*! r: index azimuth */
     967      285638 : 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      285638 :     delta_phi_fx = BASOP_Util_Divide3232_Scale_newton( 360, n, &delta_phi_e );
     982      285638 :     delta_phi_fx = L_shr( delta_phi_fx, sub( sub( 31, delta_phi_e ), 22 ) ); // Q22
     983             : 
     984      285638 :     IF( EQ_16( n, 1 ) )
     985             :     {
     986           0 :         *phi_hat_fx = 0;
     987           0 :         move32();
     988             : 
     989           0 :         return 0;
     990             :     }
     991             : 
     992      285638 :     IF( EQ_16( flag_delta, 1 ) )
     993             :     {
     994      101205 :         dd_fx = L_shr( delta_phi_fx, 1 ); // Q22
     995             :     }
     996             :     ELSE
     997             :     {
     998      184433 :         dd_fx = 0;
     999      184433 :         move32();
    1000             :     }
    1001             : 
    1002      285638 :     tmp32 = L_add( L_sub( phi_fx, dd_fx ), L_shr( delta_phi_fx, 1 ) );
    1003      285638 :     tmp32 = BASOP_Util_Divide3232_Scale_newton( tmp32, delta_phi_fx, &tmp_e );
    1004      285638 :     id_phi = extract_l( L_shr( tmp32, sub( 31, tmp_e ) ) ); // Q0
    1005             : 
    1006      285638 :     if ( EQ_16( id_phi, n ) )
    1007             :     {
    1008          22 :         id_phi = 0;
    1009          22 :         move16();
    1010             :     }
    1011             : 
    1012      285638 :     if ( EQ_16( id_phi, -1 ) )
    1013             :     {
    1014           1 :         id_phi = sub( n, 1 );
    1015             :     }
    1016             : 
    1017      285638 :     delta_phi_fx = BASOP_Util_Divide3232_Scale_newton( L_mult0( 360, id_phi ), n, &delta_phi_e );
    1018      285638 :     delta_phi_fx = L_shr( delta_phi_fx, sub( sub( 31, delta_phi_e ), 22 ) ); // Q22
    1019             : 
    1020      285638 :     *phi_hat_fx = L_add( delta_phi_fx, dd_fx ); // Q22
    1021      285638 :     move32();
    1022             : 
    1023      285638 :     return id_phi; // Q0
    1024             : }
    1025             : 
    1026             : 
    1027             : /*-------------------------------------------------------------------------
    1028             :  * deindex_sph_idx()
    1029             :  *
    1030             :  *  deindex the MASA metadata from the input metadata file
    1031             :  *------------------------------------------------------------------------*/
    1032             : 
    1033     1177632 : void deindex_sph_idx_fx(
    1034             :     const UWord16 sphIndex,              /* i  : Spherical index            */
    1035             :     const SPHERICAL_GRID_DATA *gridData, /* i  : Prepared spherical grid    */
    1036             :     Word32 *theta_fx,                    /* o  : Elevation                  Q22*/
    1037             :     Word32 *phi_fx                       /* o  : Azimuth                   Q22 */
    1038             : )
    1039             : {
    1040             :     Word32 ba_crt_fx, del_crt_fx, div_crt_fx, a4_crt_fx;
    1041             :     Word32 estim_fx;
    1042             :     Word32 base_low, base_up;
    1043             :     Word16 n_crt;
    1044             :     Word16 id_th;
    1045             :     Word16 sign_theta;
    1046             :     Word16 id_phi;
    1047     1177632 :     Word16 no_th = gridData->no_theta;
    1048     1177632 :     const Word16 *n = gridData->no_phi;
    1049             :     const Word32 ba_fx[3] = { 1793476992, 1044259584, 1030463872 };   /* Q23 */
    1050             :     const Word32 del_fx[3] = { 819022016, 1332105216, 1458249984 };   /* Q10 */
    1051             :     const Word32 div_fx[3] = { -510376000, -216763104, -197676320 };  /* Q31 */
    1052             :     const Word32 a4_fx[3] = { -564741248, -1329702144, -1458092544 }; /* Q26 */
    1053     1177632 :     const UWord16 limit_index1 = 64964, limit_index2 = 47870;
    1054             :     Word32 tmp32;
    1055             :     Word16 tmp16, tmp_e;
    1056     1177632 :     move16();
    1057     1177632 :     move16();
    1058     1177632 :     move16();
    1059     1177632 :     move32();
    1060     1177632 :     move32();
    1061     1177632 :     move32();
    1062     1177632 :     move32();
    1063     1177632 :     move32();
    1064     1177632 :     move32();
    1065     1177632 :     move32();
    1066     1177632 :     move32();
    1067     1177632 :     move32();
    1068     1177632 :     move32();
    1069     1177632 :     move32();
    1070     1177632 :     move32();
    1071             : 
    1072     1177632 :     IF( GE_32( sphIndex, limit_index1 ) )
    1073             :     {
    1074        1176 :         ba_crt_fx = ba_fx[2];
    1075        1176 :         move32();
    1076        1176 :         div_crt_fx = div_fx[2];
    1077        1176 :         move32();
    1078        1176 :         a4_crt_fx = a4_fx[2];
    1079        1176 :         move32();
    1080        1176 :         del_crt_fx = del_fx[2];
    1081        1176 :         move32();
    1082             :     }
    1083     1176456 :     ELSE IF( GE_32( sphIndex, limit_index2 ) )
    1084             :     {
    1085       50058 :         ba_crt_fx = ba_fx[1];
    1086       50058 :         move32();
    1087       50058 :         div_crt_fx = div_fx[1];
    1088       50058 :         move32();
    1089       50058 :         a4_crt_fx = a4_fx[1];
    1090       50058 :         move32();
    1091       50058 :         del_crt_fx = del_fx[1];
    1092       50058 :         move32();
    1093             :     }
    1094             :     ELSE
    1095             :     {
    1096     1126398 :         ba_crt_fx = ba_fx[0];
    1097     1126398 :         move32();
    1098     1126398 :         div_crt_fx = div_fx[0];
    1099     1126398 :         move32();
    1100     1126398 :         a4_crt_fx = a4_fx[0];
    1101     1126398 :         move32();
    1102     1126398 :         del_crt_fx = del_fx[0];
    1103     1126398 :         move32();
    1104             :     }
    1105     1177632 :     tmp32 = Mpy_32_32( a4_crt_fx, L_shl_sat( sphIndex, Q15 ) ); /* Q10 */
    1106     1177632 :     tmp32 = L_add( del_crt_fx, tmp32 );                         /* Q10 */
    1107     1177632 :     tmp16 = Q31 - Q10;
    1108     1177632 :     move16();
    1109     1177632 :     tmp32 = Sqrt32( tmp32, &tmp16 );          // Q31-tmp16
    1110     1177632 :     tmp32 = Mpy_32_32( div_crt_fx, tmp32 );   // Q31-tmp16
    1111     1177632 :     tmp32 = L_shr( tmp32, sub( Q8, tmp16 ) ); /* Q23 */
    1112     1177632 :     estim_fx = L_add( ba_crt_fx, tmp32 );     /* Q23 */
    1113             : 
    1114     1177632 :     if ( GT_32( estim_fx, MASA_NO_CIRCLES_Q23 ) )
    1115             :     {
    1116          54 :         estim_fx = MASA_NO_CIRCLES_Q23; // Q23
    1117          54 :         move32();
    1118             :     }
    1119             : 
    1120     1177632 :     assert( estim_fx > 0 );
    1121     1177632 :     id_th = sub( extract_l( L_shr_r( estim_fx, Q23 ) ), 1 ); /* Q0 */
    1122     1177632 :     if ( id_th < 0 )
    1123             :     {
    1124           0 :         id_th = 0;
    1125           0 :         move16();
    1126             :     }
    1127             : 
    1128     1177632 :     IF( id_th == 0 )
    1129             :     {
    1130       16679 :         base_low = 0;
    1131       16679 :         move32();
    1132       16679 :         base_up = n[0];
    1133       16679 :         move32();
    1134             :     }
    1135             :     ELSE
    1136             :     {
    1137     1160953 :         base_low = n[0];
    1138     1160953 :         move32();
    1139     1160953 :         IF( GE_16( id_th, 2 ) )
    1140             :         {
    1141     1087230 :             IF( EQ_16( id_th, 2 ) )
    1142             :             {
    1143       73208 :                 base_low = L_add( base_low, L_shl( estim_ceil[id_th], 1 ) ); /* Q0 */
    1144             :             }
    1145             :             ELSE
    1146             :             {
    1147     1014022 :                 base_low = L_add( base_low, L_shl( estim_round[id_th], 1 ) ); /* Q0 */
    1148             :             }
    1149             :         }
    1150     1160953 :         base_up = L_add( base_low, L_shl( n[id_th], 1 ) );
    1151             :     }
    1152             : 
    1153     1177632 :     sign_theta = 1;
    1154     1177632 :     move16();
    1155             : 
    1156     1177632 :     n_crt = n[id_th];
    1157     1177632 :     move16();
    1158     1177632 :     IF( LT_32( sphIndex, base_low ) )
    1159             :     {
    1160       53239 :         id_th = sub( id_th, 1 );
    1161       53239 :         n_crt = n[id_th];
    1162       53239 :         move16();
    1163       53239 :         IF( id_th == 0 )
    1164             :         {
    1165       19588 :             base_low = 0;
    1166       19588 :             move32();
    1167       19588 :             base_up = n_crt;
    1168       19588 :             move32();
    1169             :         }
    1170             :         ELSE
    1171             :         {
    1172       33651 :             base_up = base_low;
    1173       33651 :             move32();
    1174       33651 :             base_low = L_sub( base_low, shl( n[id_th], 1 ) );
    1175             :         }
    1176       53239 :         assert( sphIndex >= base_low );
    1177             :     }
    1178     1124393 :     ELSE IF( GE_32( sphIndex, base_up ) )
    1179             :     {
    1180       34241 :         id_th = add( id_th, 1 );
    1181       34241 :         n_crt = n[id_th];
    1182       34241 :         move16();
    1183       34241 :         base_low = base_up;
    1184       34241 :         move32();
    1185       34241 :         base_up = L_add( base_up, shl( n_crt, 1 ) );
    1186       34241 :         assert( sphIndex < base_up );
    1187             :     }
    1188             : 
    1189     1177632 :     id_phi = extract_l( L_sub( sphIndex, base_low ) );
    1190     1177632 :     IF( GE_32( L_sub( sphIndex, base_low ), n_crt ) )
    1191             :     {
    1192      632165 :         id_phi = sub( id_phi, n_crt );
    1193      632165 :         sign_theta = -1;
    1194      632165 :         move16();
    1195             :     }
    1196             : 
    1197     1177632 :     IF( id_th == 0 )
    1198             :     {
    1199       36267 :         *theta_fx = 0;
    1200       36267 :         move32();
    1201       36267 :         tmp32 = imult3216( sphIndex, 360 );
    1202       36267 :         tmp16 = BASOP_Util_Divide3232_Scale( tmp32, n_crt, &tmp_e );
    1203       36267 :         tmp32 = L_shl( tmp16, add( Q7, tmp_e ) ); /* Q22 */
    1204       36267 :         *phi_fx = L_sub( tmp32, 180 << Q22 );     /* Q22 */
    1205       36267 :         move32();
    1206             :     }
    1207             :     ELSE
    1208             :     {
    1209     1141365 :         IF( EQ_16( id_th, sub( no_th, 1 ) ) )
    1210             :         {
    1211          48 :             id_phi = 0;
    1212          48 :             move16();
    1213          48 :             *phi_fx = -754974720; /* -180 in Q22 */
    1214          48 :             move32();
    1215          48 :             *theta_fx = L_shl( L_mult0( 90, sign_theta ), Q22 ); /* Q22 */
    1216          48 :             move32();
    1217             :         }
    1218             :         ELSE
    1219             :         {
    1220     1141317 :             *theta_fx = Mpy_32_32( L_shl( id_th, Q22 ), MASA_ANGLE_AT_EQUATOR_DEG_Q31 ); /* Q22 */
    1221     1141317 :             move32();
    1222     1141317 :             if ( EQ_16( sign_theta, -1 ) )
    1223             :             {
    1224      632141 :                 *theta_fx = L_negate( *theta_fx ); /* Q22 */
    1225      632141 :                 move32();
    1226             :             }
    1227     1141317 :             IF( id_th % 2 == 0 )
    1228             :             {
    1229      552791 :                 tmp32 = L_mult0( id_phi, 360 );
    1230      552791 :                 tmp16 = BASOP_Util_Divide3232_Scale( tmp32, n_crt, &tmp_e );
    1231      552791 :                 tmp32 = L_shl( tmp16, add( Q7, tmp_e ) ); /* Q22 */
    1232      552791 :                 *phi_fx = L_sub( tmp32, 180 << Q22 );     /* Q22 */
    1233      552791 :                 move32();
    1234             :             }
    1235             :             ELSE
    1236             :             {
    1237      588526 :                 tmp32 = L_add( L_mult0( id_phi, 360 ), 180 );
    1238      588526 :                 tmp16 = BASOP_Util_Divide3232_Scale( tmp32, n_crt, &tmp_e );
    1239      588526 :                 tmp32 = L_shl( tmp16, add( Q7, tmp_e ) ); /* Q22 */
    1240      588526 :                 *phi_fx = L_sub( tmp32, 180 << Q22 );     /* Q22 */
    1241      588526 :                 move32();
    1242             :             }
    1243             :         }
    1244             :     }
    1245     1177632 :     return;
    1246             : }
    1247             : /*---------------------------------------------------------------
    1248             :  * valid_ratio_index()
    1249             :  *
    1250             :  * Checking validity of the index of an ISM ratio index vector,
    1251             :  * within the indexing function.
    1252             :  *---------------------------------------------------------------*/
    1253             : 
    1254             : /*! r: valid or not 1/0 */
    1255      787351 : Word16 valid_ratio_index_fx(
    1256             :     Word16 index,    /* i  : index to be checked        */
    1257             :     const Word16 K,  /* i  : L1 norm to check against   */
    1258             :     const Word16 len /* i  : vector length              */
    1259             : )
    1260             : {
    1261             :     Word16 out;
    1262             :     Word16 i, sum, elem;
    1263             :     Word16 base[4];
    1264             : 
    1265      787351 :     sum = 0;
    1266      787351 :     move16();
    1267      787351 :     set16_fx( base, 1, len );
    1268             : 
    1269     2345372 :     FOR( i = 1; i < len; i++ )
    1270             :     {
    1271     1558021 :         base[i] = i_mult( base[i - 1], 10 );
    1272     1558021 :         move16();
    1273             :     }
    1274      787351 :     sum = 0;
    1275      787351 :     move16();
    1276     3132723 :     FOR( i = len - 1; i >= 0; i-- )
    1277             :     {
    1278     2345372 :         IF( index == 0 )
    1279             :         {
    1280       98743 :             elem = 0;
    1281       98743 :             move16();
    1282             :         }
    1283             :         ELSE
    1284             :         {
    1285     2246629 :             elem = idiv1616( index, base[i] );
    1286             :         }
    1287     2345372 :         sum = add( sum, elem );
    1288     2345372 :         index = sub( index, i_mult( elem, base[i] ) );
    1289             :     }
    1290      787351 :     IF( LE_16( sum, K ) )
    1291             :     {
    1292      217319 :         out = 1;
    1293      217319 :         move16();
    1294             :     }
    1295             :     ELSE
    1296             :     {
    1297      570032 :         out = 0;
    1298      570032 :         move16();
    1299             :     }
    1300             : 
    1301      787351 :     return out;
    1302             : }
    1303             : 
    1304             : 
    1305             : /*---------------------------------------------------------------
    1306             :  * reconstruct_ism_ratios()
    1307             :  *
    1308             :  * Obtains ISM ratio values from the quantized indexes
    1309             :  *---------------------------------------------------------------*/
    1310             : 
    1311       26906 : void reconstruct_ism_ratios_fx(
    1312             :     Word16 *ratio_ism_idx,     /* i  : index vector                 Q0  */
    1313             :     const Word16 nchan_ism,    /* i  : number of components/objects Q0  */
    1314             :     const Word32 step,         /* i  : quantization step            Q31 */
    1315             :     Word32 *q_energy_ratio_ism /* o  : reconstructed ISM values     Q30 */
    1316             : )
    1317             : {
    1318             :     Word16 i;
    1319             :     Word32 sum;
    1320             : 
    1321       26906 :     sum = 0;
    1322       26906 :     move32();
    1323             : 
    1324       93772 :     FOR( i = 0; i < nchan_ism - 1; i++ )
    1325             :     {
    1326       66866 :         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;
    1327       66866 :         move32();
    1328             : 
    1329       66866 :         sum = L_add( sum, q_energy_ratio_ism[i] ); // Q30
    1330             :     }
    1331             : 
    1332       26906 :     q_energy_ratio_ism[nchan_ism - 1] = L_sub( ONE_IN_Q30, sum );
    1333       26906 :     move32();
    1334             : 
    1335       26906 :     if ( q_energy_ratio_ism[nchan_ism - 1] < 0 )
    1336             :     {
    1337           0 :         q_energy_ratio_ism[nchan_ism - 1] = 0;
    1338           0 :         move32();
    1339             :     }
    1340             : 
    1341       26906 :     return;
    1342             : }
    1343             : 
    1344             : 
    1345             : /*---------------------------------------------------------------
    1346             :  * ivas_omasa_modify_masa_energy_ratios()
    1347             :  *
    1348             :  * Updates energy ratios by taking into account the MASA content contribution
    1349             :  * to the total audio scene
    1350             :  *---------------------------------------------------------------*/
    1351             : 
    1352        1637 : void ivas_omasa_modify_masa_energy_ratios_fx(
    1353             :     IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle  */
    1354             :     Word32 masa_to_total_energy_ratio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_MAXIMUM_CODING_SUBBANDS] /* Q30 */ )
    1355             : {
    1356             :     Word16 i, m, d, b;
    1357             : 
    1358        8185 :     FOR( m = 0; m < MAX_PARAM_SPATIAL_SUBFRAMES; m++ )
    1359             :     {
    1360        6548 :         IF( EQ_16( hQMetaData->q_direction[0].cfg.nblocks, 1 ) )
    1361             :         {
    1362        2148 :             i = 0;
    1363        2148 :             move16();
    1364             :         }
    1365             :         ELSE
    1366             :         {
    1367        4400 :             i = m;
    1368        4400 :             move16();
    1369             :         }
    1370             : 
    1371       49132 :         FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
    1372             :         {
    1373       92420 :             FOR( d = 0; d < hQMetaData->no_directions; d++ )
    1374             :             {
    1375       49836 :                 hQMetaData->q_direction[d].band_data[b].energy_ratio_fx[m] = L_shl(
    1376       49836 :                     Mpy_32_32( hQMetaData->q_direction[d].band_data[b].energy_ratio_fx[m],
    1377       49836 :                                masa_to_total_energy_ratio_fx[i][b] ),
    1378             :                     1 ); // Q30 + Q30 - 31 = Q29 + 1 = Q30
    1379       49836 :                 move32();
    1380             :             }
    1381             :         }
    1382             :     }
    1383             : 
    1384        1637 :     return;
    1385             : }
    1386             : 
    1387             : 
    1388             : /*---------------------------------------------------------------
    1389             :  * distribute_evenly_ism()
    1390             :  *
    1391             :  * Obtain ISM ratio indexes for even content distribution bbetween objects
    1392             :  *---------------------------------------------------------------*/
    1393             : 
    1394        3111 : void distribute_evenly_ism_fx(
    1395             :     Word16 *idx,           /* o  : index values       Q0 */
    1396             :     const Word16 K,        /* i  : sum of indexes      Q0*/
    1397             :     const Word16 nchan_ism /* i  : number of objects  Q0 */
    1398             : )
    1399             : {
    1400             :     Word16 i;
    1401             :     Word16 sum;
    1402             : 
    1403        3111 :     sum = 0;
    1404        3111 :     move16();
    1405       13467 :     FOR( i = 0; i < nchan_ism; i++ )
    1406             :     {
    1407       10356 :         IF( K == 0 )
    1408             :         {
    1409           0 :             idx[i] = 0;
    1410           0 :             move16();
    1411             :         }
    1412             :         ELSE
    1413             :         {
    1414       10356 :             idx[i] = idiv1616( K, nchan_ism ); // Q0
    1415       10356 :             move16();
    1416             :         }
    1417       10356 :         sum = add( sum, idx[i] );
    1418             :     }
    1419             : 
    1420        3111 :     assert( LE_16( sum, K ) );
    1421             : 
    1422        3111 :     i = 0;
    1423        3111 :     move16();
    1424        8932 :     WHILE( LT_16( sum, K ) )
    1425             :     {
    1426        5821 :         if ( EQ_16( i, nchan_ism ) )
    1427             :         {
    1428           0 :             i = 0;
    1429           0 :             move16();
    1430             :         }
    1431        5821 :         idx[i] = add( idx[i], 1 );
    1432        5821 :         move16();
    1433        5821 :         sum = add( sum, 1 );
    1434        5821 :         i = add( i, 1 );
    1435             :     }
    1436             : 
    1437        3111 :     return;
    1438             : }
    1439             : 
    1440             : 
    1441             : /*---------------------------------------------------------------
    1442             :  * calculate_cpe_brate_MASA_ISM()
    1443             :  *
    1444             :  * Calculates bitrate for MASA_ISM mode that is not used for separated objects,
    1445             :  * * but for the CPE part (metadata included)
    1446             :  *---------------------------------------------------------------*/
    1447             : 
    1448             : /*! r: CPE bitrate value       */
    1449       10825 : Word32 calculate_cpe_brate_MASA_ISM_fx(
    1450             :     const ISM_MODE ism_mode,       /* i  : ism mode                */
    1451             :     const Word32 ivas_total_brate, /* i  : IVAS total bitrate      */
    1452             :     const Word16 nchan_ism         /* i  : number of objects       */
    1453             : )
    1454             : {
    1455             :     Word32 cpe_brate;
    1456             :     Word16 k, sce_id;
    1457             : 
    1458       10825 :     k = 0;
    1459       10825 :     move16();
    1460             : 
    1461      110731 :     WHILE( LT_16( k, SIZE_IVAS_BRATE_TBL ) && NE_32( ivas_total_brate, ivas_brate_tbl[k] ) )
    1462             :     {
    1463       99906 :         test();
    1464       99906 :         k = add( k, 1 );
    1465             :     }
    1466             : 
    1467       10825 :     test();
    1468       10825 :     IF( EQ_16( ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) || EQ_16( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
    1469             :     {
    1470        4440 :         cpe_brate = L_sub( ivas_total_brate, sep_object_brate[k - 2][0] ); /* take data from the first column */
    1471             :     }
    1472        6385 :     ELSE IF( EQ_16( ism_mode, ISM_MASA_MODE_DISC ) )
    1473             :     {
    1474        5972 :         cpe_brate = ivas_total_brate;
    1475        5972 :         move32();
    1476             : 
    1477       22115 :         FOR( sce_id = 0; sce_id < nchan_ism; sce_id++ )
    1478             :         {
    1479       16143 :             cpe_brate = L_sub( cpe_brate, sep_object_brate[k - 2][nchan_ism - 1] );
    1480             :         }
    1481             :     }
    1482             :     ELSE
    1483             :     {
    1484         413 :         cpe_brate = ivas_total_brate;
    1485         413 :         move32();
    1486             :     }
    1487             : 
    1488       10825 :     return cpe_brate;
    1489             : }

Generated by: LCOV version 1.14