LCOV - code coverage report
Current view: top level - lib_com - ivas_masa_com.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 326 335 97.3 %
Date: 2025-05-23 08:37:30 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.h"
      38             : #include "ivas_cnst.h"
      39             : #include "ivas_prot.h"
      40             : #include "ivas_rom_com.h"
      41             : #include "ivas_stat_dec.h"
      42             : #ifdef DEBUGGING
      43             : #include "debug.h"
      44             : #endif
      45             : #include "wmc_auto.h"
      46             : 
      47             : /*---------------------------------------------------------------
      48             :  * Local constants
      49             :  *---------------------------------------------------------------*/
      50             : 
      51             : #define MASA_EXTRA_BAND_META_BITS 40
      52             : 
      53             : #define MASA_SMALL_INC_META_BITS 10
      54             : 
      55             : 
      56             : /*---------------------------------------------------------------
      57             :  * Local prototypes
      58             :  *---------------------------------------------------------------*/
      59             : 
      60             : static int16_t quantize_theta_masa( float x, const int16_t no_cb, float *xhat );
      61             : 
      62             : static int16_t quantize_phi_masa( float phi, const int16_t flag_delta, float *phi_hat, const int16_t n );
      63             : 
      64             : 
      65             : /*---------------------------------------------------------------
      66             :  * ivas_masa_setup()
      67             :  *
      68             :  * Set-up MASA coding elements and bitrates
      69             :  *---------------------------------------------------------------*/
      70             : 
      71      199096 : void ivas_masa_set_elements(
      72             :     const int32_t ivas_total_brate,   /* i  : IVAS total bitrate                      */
      73             :     const int16_t mc_mode,            /* i  : MC format mode                          */
      74             :     const int16_t nchan_transport,    /* i  : number of MASA input/transport channels */
      75             :     IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle                       */
      76             :     int16_t *element_mode,            /* o  : element mode                            */
      77             :     int16_t *nSCE,                    /* o  : number of SCEs                          */
      78             :     int16_t *nCPE,                    /* o  : number of CPEs                          */
      79             :     const int16_t ivas_format,        /* i  : IVAS format                             */
      80             :     const ISM_MODE ism_mode,          /* i  : ISM mode                                */
      81             :     const int32_t ism_total_brate     /* i  : initial ISM total bitrate               */
      82             : )
      83             : {
      84      199096 :     if ( nchan_transport == 2 )
      85             :     {
      86      110351 :         if ( ivas_total_brate >= MCMASA_SEPARATE_BRATE && mc_mode == MC_MODE_MCMASA )
      87             :         {
      88        1976 :             *nCPE = 1;
      89        1976 :             *nSCE = 1;
      90             : 
      91        1976 :             *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*/
      92             :         }
      93      108375 :         else if ( ivas_format == MASA_ISM_FORMAT && ism_mode != ISM_MODE_NONE )
      94             :         {
      95       31542 :             *nCPE = 1;
      96             : 
      97       31542 :             if ( *element_mode == -1 )
      98             :             {
      99       20832 :                 *element_mode = IVAS_CPE_DFT; /* To have it initialized in case it was not already. */
     100             :             }
     101       31542 :             if ( ivas_total_brate > MIN_BRATE_MDCT_STEREO )
     102             :             {
     103       21022 :                 *element_mode = IVAS_CPE_MDCT;
     104       21022 :                 if ( ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) && ( ivas_total_brate - ism_total_brate < MIN_BRATE_MDCT_STEREO ) )
     105             :                 {
     106        2421 :                     *element_mode = IVAS_CPE_DFT;
     107             :                 }
     108             :             }
     109             :         }
     110             :         else
     111             :         {
     112       76833 :             *nCPE = 1;
     113       76833 :             *nSCE = 0;
     114             : 
     115       76833 :             if ( ivas_total_brate > MIN_BRATE_MDCT_STEREO )
     116             :             {
     117       35596 :                 *element_mode = IVAS_CPE_MDCT;
     118             :             }
     119             :         }
     120      110351 :         hQMetaData->bits_frame_nominal = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC );
     121      110351 :         if ( ivas_format == MASA_ISM_FORMAT && ( ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || ism_mode == ISM_MASA_MODE_DISC ) )
     122             :         {
     123       31542 :             hQMetaData->bits_frame_nominal -= (int16_t) ( ism_total_brate / FRAMES_PER_SEC );
     124             :         }
     125             :     }
     126       88745 :     else if ( nchan_transport == 1 )
     127             :     {
     128       88745 :         *nCPE = 0;
     129       88745 :         *nSCE = 1;
     130             : 
     131       88745 :         if ( ivas_total_brate == IVAS_13k2 )
     132             :         {
     133       15601 :             hQMetaData->bits_frame_nominal = ACELP_9k60 / FRAMES_PER_SEC;
     134             :         }
     135       73144 :         else if ( ivas_total_brate <= IVAS_16k4 )
     136             :         {
     137        5261 :             hQMetaData->bits_frame_nominal = ACELP_13k20 / FRAMES_PER_SEC;
     138             :         }
     139       67883 :         else if ( ivas_total_brate <= IVAS_24k4 )
     140             :         {
     141       29275 :             hQMetaData->bits_frame_nominal = ACELP_16k40 / FRAMES_PER_SEC;
     142             :         }
     143       38608 :         else if ( ivas_total_brate <= IVAS_32k )
     144             :         {
     145       11539 :             hQMetaData->bits_frame_nominal = ACELP_24k40 / FRAMES_PER_SEC;
     146             :         }
     147             :         else
     148             :         {
     149       27069 :             hQMetaData->bits_frame_nominal = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC );
     150             :         }
     151       88745 :         *element_mode = IVAS_SCE;
     152             :     }
     153             :     else
     154             :     {
     155           0 :         assert( !"MASA number of transport channels must be 1, or 2" );
     156             :     }
     157             : 
     158      199096 :     return;
     159             : }
     160             : 
     161             : 
     162             : /*---------------------------------------------------------------
     163             :  * generate_gridEq()
     164             :  *
     165             :  * generate Spherical grid
     166             :  *---------------------------------------------------------------*/
     167             : 
     168         782 : void generate_gridEq(
     169             :     SPHERICAL_GRID_DATA *data /* o  : data structure for grid  */
     170             : )
     171             : {
     172             :     int32_t cum_n, cum_n_prev;
     173             :     float theta;
     174             :     int16_t i;
     175             :     int16_t *n;
     176             : 
     177         782 :     n = data->no_phi;
     178         782 :     n[0] = MASA_NO_POINTS_EQUATOR;
     179             : 
     180         782 :     cum_n_prev = 0;
     181             : 
     182       94622 :     for ( i = 1; i < MASA_NO_CIRCLES; i++ )
     183             :     {
     184       93840 :         theta = MASA_ANGLE_AT_EQUATOR * (float) ( i + 0.5f );
     185       93840 :         if ( i == 1 )
     186             :         {
     187         782 :             cum_n = 2 * (int32_t) ceilf( MASA_NTOT2_FAC * ( sinf( theta ) - MASA_ASIN_OFFSET ) );
     188             :         }
     189             :         else
     190             :         {
     191       93058 :             cum_n = 2 * (int32_t) roundf( MASA_NTOT2_FAC * ( sinf( theta ) - MASA_ASIN_OFFSET ) );
     192             :         }
     193       93840 :         n[i] = (int16_t) ( ( cum_n - cum_n_prev ) >> 1 );
     194       93840 :         cum_n_prev = cum_n;
     195             :     }
     196         782 :     n[i] = 1;
     197         782 :     data->no_theta = i + 1;
     198             : 
     199         782 :     return;
     200             : }
     201             : 
     202             : 
     203             : /*---------------------------------------------------------------
     204             :  * ivas_masa_set_coding_config()
     205             :  *
     206             :  * Sets MASA codec parameters based on bitrate, number of directions,
     207             :  * and other metadata properties.
     208             :  *---------------------------------------------------------------*/
     209             : 
     210      187391 : void ivas_masa_set_coding_config(
     211             :     MASA_CODEC_CONFIG *config,      /* i/o: MASA coding config structure                */
     212             :     int16_t *band_mapping,          /* o  : Band mapping used                           */
     213             :     const int32_t ivas_total_brate, /* i  : IVAS total bitrate                          */
     214             :     const int16_t nchan_transport,  /* i  : number of transport channels (mono/stereo)  */
     215             :     const uint8_t isMcMasa          /* i  : toggle for selecting mcMASA specific config */
     216             : )
     217             : {
     218             :     int16_t i;
     219             :     uint8_t nbands;
     220             :     uint8_t nTwoDirBands;
     221             :     const int16_t *masa_bits_table;
     222             : 
     223             :     /* When coming into this function, these values should be already set:
     224             :      *  joinedSubframes;
     225             :      *  useCoherence;
     226             :      *  numberOfDirections;
     227             :      */
     228             : 
     229             :     /* Setup coding parameters based on the bitrate, transport channel count, subframe metadata information,
     230             :      * and number of directions in metadata. */
     231      187391 :     nbands = 0;
     232      187391 :     nTwoDirBands = 0;
     233      187391 :     i = 0;
     234             : 
     235             :     /* First select correct bit budget table */
     236      187391 :     masa_bits_table = masa_bits;
     237      187391 :     if ( isMcMasa )
     238             :     {
     239       35040 :         masa_bits_table = mcmasa_bits;
     240             :     }
     241      152351 :     else if ( ivas_total_brate < IVAS_48k && nchan_transport == 2 )
     242             :     {
     243       45785 :         masa_bits_table = masa_bits_LR_stereo;
     244             :     }
     245             : 
     246     1174865 :     while ( nbands == 0 && i < IVAS_NUM_ACTIVE_BRATES )
     247             :     {
     248      987474 :         if ( ivas_total_brate <= ivas_brate_tbl[i + SIZE_IVAS_BRATE_TBL - IVAS_NUM_ACTIVE_BRATES] )
     249             :         {
     250             :             int16_t idx_bands;
     251      187391 :             if ( ivas_total_brate < IVAS_48k && nchan_transport == 2 && i > 3 )
     252             :             {
     253             :                 /* because it uses the bitallocation for the lower bit rates from 'masa_bits_LR_stereo' and it has 4 elements */
     254        1498 :                 i = 3;
     255             :             }
     256      187391 :             idx_bands = i;
     257             : 
     258      187391 :             if ( config->numberOfDirections > 1 )
     259             :             {
     260       27192 :                 nTwoDirBands = config->joinedSubframes ? masa_twodir_bands_joined[i] : masa_twodir_bands[i];
     261             : 
     262       27192 :                 if ( ( ivas_total_brate > IVAS_96k && !config->joinedSubframes ) || ( ivas_total_brate > IVAS_80k && config->joinedSubframes ) )
     263             :                 {
     264       15471 :                     idx_bands--;
     265             :                 }
     266             :             }
     267             : 
     268      187391 :             if ( config->joinedSubframes )
     269             :             {
     270       21840 :                 nbands = masa_joined_nbands[idx_bands];
     271             :             }
     272             :             else
     273             :             {
     274      165551 :                 nbands = masa_nbands[idx_bands];
     275             :             }
     276             : 
     277      187391 :             config->max_metadata_bits = masa_bits_table[i];
     278             : 
     279      187391 :             if ( ivas_total_brate == IVAS_64k && config->numberOfDirections > 1 )
     280             :             {
     281             :                 /* At 64k, we increase metadata bit budget when there is two directions present. */
     282        2182 :                 config->max_metadata_bits += MASA_EXTRA_BAND_META_BITS;
     283             :             }
     284             : 
     285      187391 :             if ( ( ( ivas_total_brate == IVAS_32k && nchan_transport == 2 ) || ivas_total_brate == IVAS_48k ) && config->joinedSubframes )
     286             :             {
     287             :                 /* At 32k and 48k, we increase metadata bit budget when joinedSubframes. */
     288        4459 :                 config->max_metadata_bits += ( MASA_SMALL_INC_META_BITS );
     289             :             }
     290             :         }
     291      987474 :         i++;
     292             :     }
     293      187391 :     config->numCodingBands = nbands;
     294      187391 :     config->numTwoDirBands = nTwoDirBands;
     295             : 
     296             : #ifdef DEBUGGING
     297             :     assert( nbands > 0 );
     298             : #endif
     299      187391 :     if ( config->joinedSubframes == TRUE )
     300             :     {
     301       21840 :         config->mergeRatiosOverSubframes = FALSE;
     302             :     }
     303             :     else
     304             :     {
     305      165551 :         config->mergeRatiosOverSubframes = TRUE;
     306             :     }
     307             : 
     308             :     /* Setup frequency band mapping based on the number of used coding bands */
     309      187391 :     switch ( config->numCodingBands )
     310             :     {
     311      142665 :         case 5:
     312      142665 :             mvs2s( MASA_band_mapping_24_to_5, band_mapping, 5 + 1 );
     313      142665 :             break;
     314       13637 :         case 8:
     315       13637 :             mvs2s( MASA_band_mapping_24_to_8, band_mapping, 8 + 1 );
     316       13637 :             break;
     317        7948 :         case 12:
     318        7948 :             mvs2s( MASA_band_mapping_24_to_12, band_mapping, 12 + 1 );
     319        7948 :             break;
     320        8717 :         case 18:
     321        8717 :             mvs2s( MASA_band_mapping_24_to_18, band_mapping, 18 + 1 );
     322        8717 :             break;
     323       14424 :         case MASA_FREQUENCY_BANDS:
     324             :             /* With input count of bands, no mapping is needed but for unified processing later, we store normal mapping */
     325      375024 :             for ( i = 0; i < MASA_FREQUENCY_BANDS + 1; i++ )
     326             :             {
     327      360600 :                 band_mapping[i] = i;
     328             :             }
     329       14424 :             break;
     330           0 :         default:
     331           0 :             assert( 0 && "Error: The number of MASA coding bands is not supported" );
     332             :     }
     333             : 
     334      187391 :     config->useCoherence = TRUE;
     335      187391 :     if ( ( !isMcMasa && ivas_total_brate < IVAS_48k ) || ( isMcMasa && ivas_total_brate < IVAS_16k4 ) )
     336             :     {
     337       77384 :         config->useCoherence = FALSE;
     338             :     }
     339             : 
     340      187391 :     return;
     341             : }
     342             : 
     343             : 
     344             : /*---------------------------------------------------------------
     345             :  * masa_sample_rate_band_correction()
     346             :  *
     347             :  *
     348             :  *---------------------------------------------------------------*/
     349             : 
     350      187391 : void masa_sample_rate_band_correction(
     351             :     MASA_CODEC_CONFIG *config,                   /* i/o: MASA codec config                     */
     352             :     int16_t *band_mapping,                       /* i/o: Band mapping used and modified        */
     353             :     IVAS_QMETADATA_HANDLE hQMetaData,            /* i/o: QMetadata structure for modification  */
     354             :     const uint8_t maxBand,                       /* i  : max band                              */
     355             :     uint8_t is_encoder,                          /* i  : signals if called at encoder          */
     356             :     MASA_DECODER_EXT_OUT_META_HANDLE hExtOutMeta /* i/o: MASA decoder metadata ext out buffer  */
     357             : )
     358             : {
     359             :     uint8_t band, sf;
     360             :     int16_t highBand;
     361             :     uint8_t numBands48k;
     362             : 
     363      187391 :     numBands48k = config->numCodingBands;
     364             : 
     365     1412516 :     for ( band = 1; band < config->numCodingBands + 1; band++ )
     366             :     {
     367     1412516 :         highBand = band_mapping[band];
     368             : 
     369     1412516 :         if ( highBand >= maxBand )
     370             :         {
     371      187391 :             config->numCodingBands = band;
     372      187391 :             hQMetaData->numCodingBands = band;
     373             : 
     374      187391 :             if ( is_encoder )
     375             :             {
     376        2276 :                 if ( hQMetaData->q_direction->cfg.nbands > band )
     377             :                 {
     378         300 :                     hQMetaData->q_direction->cfg.nbands = band;
     379             :                 }
     380        2276 :                 if ( hQMetaData->no_directions == 2 && hQMetaData->q_direction[1].cfg.nbands > band )
     381             :                 {
     382         300 :                     hQMetaData->q_direction[1].cfg.nbands = band;
     383             :                 }
     384             :             }
     385             : 
     386      187391 :             band_mapping[band] = maxBand;
     387             : 
     388      187391 :             break;
     389             :         }
     390             :     }
     391             : 
     392             :     /* Set rest of the bands to zero in qmetadata. */
     393      195754 :     for ( ; band < numBands48k; band++ )
     394             :     {
     395       41815 :         for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
     396             :         {
     397       33452 :             hQMetaData->q_direction[0].band_data[band].azimuth[sf] = 0.0f;
     398       33452 :             hQMetaData->q_direction[0].band_data[band].elevation[sf] = 0.0f;
     399       33452 :             hQMetaData->q_direction[0].band_data[band].energy_ratio[sf] = 0.0f;
     400             : 
     401       33452 :             if ( hQMetaData->coherence_flag && hQMetaData->q_direction[0].coherence_band_data != NULL )
     402             :             {
     403       33452 :                 hQMetaData->q_direction[0].coherence_band_data[band].spread_coherence[sf] = 0u;
     404             :             }
     405             : 
     406       33452 :             if ( hQMetaData->no_directions == 2 )
     407             :             {
     408        4512 :                 hQMetaData->q_direction[1].band_data[band].azimuth[sf] = 0.0f;
     409        4512 :                 hQMetaData->q_direction[1].band_data[band].elevation[sf] = 0.0f;
     410        4512 :                 hQMetaData->q_direction[1].band_data[band].energy_ratio[sf] = 0.0f;
     411             : 
     412        4512 :                 if ( hQMetaData->coherence_flag && hQMetaData->q_direction[1].coherence_band_data != NULL )
     413             :                 {
     414        4512 :                     hQMetaData->q_direction[1].coherence_band_data[band].spread_coherence[sf] = 0u;
     415             :                 }
     416             :             }
     417             : 
     418       33452 :             if ( hQMetaData->coherence_flag && hQMetaData->surcoh_band_data != NULL )
     419             :             {
     420       33452 :                 hQMetaData->surcoh_band_data[band].surround_coherence[sf] = 0u;
     421             :             }
     422             :         }
     423             : 
     424        8363 :         if ( hQMetaData->no_directions == 2 )
     425             :         {
     426        1128 :             hQMetaData->twoDirBands[band] = 0;
     427             :         }
     428             :     }
     429             : 
     430      187391 :     if ( hExtOutMeta != NULL )
     431             :     {
     432             :         /* in decoder, zero the EXT out MASA meta buffer */
     433       79305 :         for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
     434             :         {
     435     1048284 :             for ( band = hQMetaData->numCodingBands; band < MASA_FREQUENCY_BANDS; band++ )
     436             :             {
     437      984840 :                 hExtOutMeta->directionIndex[0][sf][band] = SPH_IDX_FRONT;
     438      984840 :                 hExtOutMeta->directToTotalRatio[0][sf][band] = 0u;
     439      984840 :                 hExtOutMeta->spreadCoherence[0][sf][band] = 0u;
     440             : 
     441      984840 :                 hExtOutMeta->directionIndex[1][sf][band] = SPH_IDX_FRONT;
     442      984840 :                 hExtOutMeta->directToTotalRatio[1][sf][band] = 0u;
     443      984840 :                 hExtOutMeta->spreadCoherence[1][sf][band] = 0u;
     444             : 
     445      984840 :                 hExtOutMeta->surroundCoherence[sf][band] = 0u;
     446      984840 :                 hExtOutMeta->diffuseToTotalRatio[sf][band] = UINT8_MAX;
     447             :             }
     448             :         }
     449             :     }
     450             : 
     451      187391 :     return;
     452             : }
     453             : 
     454             : 
     455             : /*-------------------------------------------------------------------------
     456             :  * index_theta_phi_16()
     457             :  *
     458             :  *
     459             :  *------------------------------------------------------------------------*/
     460             : 
     461             : /*! r: output index for direction */
     462      785568 : uint16_t index_theta_phi_16(
     463             :     float *p_theta,                     /* i/o: input elevation to be indexed   */
     464             :     float *p_phi,                       /* i/o: input azimuth to be indexed     */
     465             :     const SPHERICAL_GRID_DATA *gridData /* i  : generated grid data             */
     466             : )
     467             : {
     468             :     float abs_theta;
     469             :     int16_t sign_th, id_phi, id_th;
     470             :     uint16_t idx_sph;
     471             :     uint16_t cum_n;
     472             :     float theta_hat, phi_hat;
     473             :     float theta, phi;
     474             : 
     475      785568 :     theta = *p_theta;
     476      785568 :     phi = *p_phi;
     477      785568 :     phi_hat = 0;
     478      785568 :     theta_hat = 0;
     479      785568 :     phi = phi + 180;
     480             : 
     481      785568 :     if ( theta < 0 )
     482             :     {
     483      224838 :         abs_theta = -theta;
     484      224838 :         sign_th = -1;
     485             :     }
     486             :     else
     487             :     {
     488      560730 :         abs_theta = theta;
     489      560730 :         sign_th = 1;
     490             :     }
     491             : 
     492      785568 :     id_th = quantize_theta_masa( abs_theta, gridData->no_theta, &theta_hat );
     493      785568 :     if ( gridData->no_theta > 1 )
     494             :     {
     495      785568 :         if ( gridData->no_phi[id_th] > 1 )
     496             :         {
     497      784979 :             id_phi = quantize_phi_masa( phi, ( id_th % 2 == 1 ), &phi_hat, gridData->no_phi[id_th] );
     498             :         }
     499             :         else
     500             :         {
     501         589 :             id_phi = 0;
     502         589 :             phi_hat = 180;
     503             :         }
     504             :     }
     505             :     else
     506             :     {
     507           0 :         id_phi = quantize_phi_masa( phi, ( id_th % 2 == 1 ), &phi_hat, gridData->no_phi[id_th] );
     508             :     }
     509      785568 :     *p_theta = sign_th * theta_hat;
     510      785568 :     *p_phi = phi_hat - 180;
     511             : 
     512             :     /* Starting from Equator, alternating positive and negative */
     513      785568 :     if ( id_th == 0 )
     514             :     {
     515      378051 :         idx_sph = id_phi;
     516             :     }
     517             :     else
     518             :     {
     519      407517 :         if ( id_th == gridData->no_theta - 1 )
     520             :         {
     521         589 :             idx_sph = 65534 + ( sign_th < 0 );
     522             :         }
     523             :         else
     524             :         {
     525      406928 :             theta = MASA_ANGLE_AT_EQUATOR * (float) ( id_th + 0.5f );
     526      406928 :             if ( id_th == 1 )
     527             :             {
     528       15141 :                 cum_n = 2 * (uint16_t) ceilf( MASA_NTOT2_FAC * ( sinf( theta ) - MASA_ASIN_OFFSET ) );
     529             :             }
     530             :             else
     531             :             {
     532      391787 :                 cum_n = 2 * (uint16_t) roundf( MASA_NTOT2_FAC * ( sinf( theta ) - MASA_ASIN_OFFSET ) );
     533             :             }
     534             : 
     535      406928 :             cum_n += gridData->no_phi[0];
     536             : 
     537      406928 :             if ( sign_th > 0 )
     538             :             {
     539      184159 :                 cum_n -= 2 * gridData->no_phi[id_th];
     540             :             }
     541             :             else
     542             :             {
     543      222769 :                 cum_n -= gridData->no_phi[id_th];
     544             :             }
     545      406928 :             idx_sph = cum_n + id_phi;
     546             :         }
     547             :     }
     548             : 
     549      785568 :     return idx_sph;
     550             : }
     551             : 
     552             : 
     553             : /*-------------------------------------------------------------------------
     554             :  * quantize_phi_masa()
     555             :  *
     556             :  *
     557             :  *------------------------------------------------------------------------*/
     558             : 
     559             : /*! r: output index */
     560      785568 : static int16_t quantize_theta_masa(
     561             :     float x,             /* i  : theta value to be quantized  */
     562             :     const int16_t no_cb, /* i  : number of codewords          */
     563             :     float *xhat          /* o  : quantized value              */
     564             : )
     565             : {
     566             :     int16_t imin;
     567             :     float diff1, diff2;
     568             : 
     569      785568 :     imin = (int16_t) ( x * MASA_INV_ANGLE_AT_EQUATOR_DEG + 0.5f );
     570             : 
     571      785568 :     if ( imin >= no_cb - 1 )
     572             :     {
     573         591 :         imin = no_cb - 1;
     574         591 :         diff1 = x - 90;
     575         591 :         diff2 = x - MASA_ANGLE_AT_EQUATOR_DEG * ( imin - 1 );
     576         591 :         if ( fabsf( diff1 ) > fabsf( diff2 ) )
     577             :         {
     578           2 :             imin--;
     579           2 :             *xhat = imin * MASA_ANGLE_AT_EQUATOR_DEG;
     580             :         }
     581             :         else
     582             :         {
     583         589 :             *xhat = 90;
     584             :         }
     585             :     }
     586             :     else
     587             :     {
     588      784977 :         *xhat = imin * MASA_ANGLE_AT_EQUATOR_DEG;
     589             :     }
     590             : 
     591      785568 :     return imin;
     592             : }
     593             : 
     594             : 
     595             : /*-------------------------------------------------------------------------
     596             :  * quantize_phi_masa()
     597             :  *
     598             :  *
     599             :  *------------------------------------------------------------------------*/
     600             : 
     601             : /*! r: index azimuth */
     602      784979 : static int16_t quantize_phi_masa(
     603             :     float phi,                /* i  : azimuth value                                                   */
     604             :     const int16_t flag_delta, /* i  : flag indicating if the azimuth codebook is translated or not    */
     605             :     float *phi_hat,           /* o  : quantized azimuth                                               */
     606             :     const int16_t n           /* i  : azimuth codebook size                                           */
     607             : )
     608             : {
     609             :     int16_t id_phi;
     610             :     float dd;
     611             :     float delta_phi;
     612             : 
     613      784979 :     delta_phi = 360.0f / (float) n;
     614             : 
     615      784979 :     if ( n == 1 )
     616             :     {
     617           0 :         *phi_hat = 0;
     618             : 
     619           0 :         return 0;
     620             :     }
     621             : 
     622      784979 :     if ( flag_delta == 1 )
     623             :     {
     624      267553 :         dd = delta_phi / 2.0f;
     625             :     }
     626             :     else
     627             :     {
     628      517426 :         dd = 0;
     629             :     }
     630             : 
     631      784979 :     id_phi = (int16_t) ( ( phi - dd + delta_phi / 2.0f ) / (float) delta_phi );
     632             : 
     633      784979 :     if ( id_phi == n )
     634             :     {
     635          46 :         id_phi = 0;
     636             :     }
     637             : 
     638      784979 :     if ( id_phi == -1 )
     639             :     {
     640           0 :         id_phi = n - 1;
     641             :     }
     642             : 
     643      784979 :     *phi_hat = id_phi * delta_phi + dd;
     644             : 
     645      784979 :     return id_phi;
     646             : }
     647             : 
     648             : 
     649             : /*-------------------------------------------------------------------------
     650             :  * deindex_sph_idx()
     651             :  *
     652             :  *  deindex the MASA metadata from the input metadata file
     653             :  *------------------------------------------------------------------------*/
     654             : 
     655     7222656 : void deindex_sph_idx(
     656             :     const uint16_t sphIndex,             /* i  : Spherical index            */
     657             :     const SPHERICAL_GRID_DATA *gridData, /* i  : Prepared spherical grid    */
     658             :     float *theta,                        /* o  : Elevation                  */
     659             :     float *phi                           /* o  : Azimuth                    */
     660             : )
     661             : {
     662             :     float ba_crt, del_crt, div_crt, a4_crt;
     663             :     float estim;
     664             :     int32_t base_low, base_up;
     665             :     int16_t n_crt;
     666             :     int16_t id_th;
     667             :     int16_t sign_theta;
     668             :     int16_t id_phi;
     669     7222656 :     int16_t no_th = gridData->no_theta;
     670     7222656 :     const int16_t *n = gridData->no_phi;
     671             :     const float ba[3] = { 2.137991118026424e+02f, 1.244854404591542e+02f, 1.228408647140870e+02f };
     672             :     const float del[3] = { 7.998262115303199e+05f, 1.300883976959332e+06f, 1.424072242426373e+06f };
     673             :     const float div[3] = { -0.237662341081474f, -0.100938185496887f, -0.092050209205032f };
     674             :     const float a4[3] = { -8.415300425381099f, -19.814106922515204f, -21.727272727270197f };
     675     7222656 :     const uint16_t limit_index1 = 64964, limit_index2 = 47870;
     676             : 
     677     7222656 :     if ( sphIndex >= limit_index1 )
     678             :     {
     679       17167 :         ba_crt = ba[2];
     680       17167 :         div_crt = div[2];
     681       17167 :         a4_crt = a4[2];
     682       17167 :         del_crt = del[2];
     683             :     }
     684     7205489 :     else if ( sphIndex >= limit_index2 )
     685             :     {
     686      603999 :         ba_crt = ba[1];
     687      603999 :         div_crt = div[1];
     688      603999 :         a4_crt = a4[1];
     689      603999 :         del_crt = del[1];
     690             :     }
     691             :     else
     692             :     {
     693     6601490 :         ba_crt = ba[0];
     694     6601490 :         div_crt = div[0];
     695     6601490 :         a4_crt = a4[0];
     696     6601490 :         del_crt = del[0];
     697             :     }
     698     7222656 :     estim = ba_crt + div_crt * sqrtf( del_crt + a4_crt * sphIndex );
     699             : 
     700     7222656 :     if ( estim > MASA_NO_CIRCLES )
     701             :     {
     702         700 :         estim = MASA_NO_CIRCLES;
     703             :     }
     704             : 
     705     7222656 :     assert( estim > 0 );
     706     7222656 :     id_th = (int16_t) roundf( estim ) - 1;
     707     7222656 :     if ( id_th < 0 )
     708             :     {
     709           0 :         id_th = 0;
     710             :     }
     711             : 
     712     7222656 :     if ( id_th == 0 )
     713             :     {
     714       87462 :         base_low = 0;
     715       87462 :         base_up = n[0];
     716             :     }
     717             :     else
     718             :     {
     719     7135194 :         estim = MASA_ANGLE_AT_EQUATOR * (float) ( id_th - 0.5f );
     720     7135194 :         base_low = n[0];
     721     7135194 :         if ( id_th >= 2 )
     722             :         {
     723     6766219 :             if ( id_th == 2 )
     724             :             {
     725      374498 :                 base_low += 2 * (int16_t) ceilf( MASA_NTOT2_FAC * ( sinf( estim ) - MASA_ASIN_OFFSET ) );
     726             :             }
     727             :             else
     728             :             {
     729     6391721 :                 base_low += 2 * (int16_t) roundf( MASA_NTOT2_FAC * ( sinf( estim ) - MASA_ASIN_OFFSET ) );
     730             :             }
     731             :         }
     732     7135194 :         base_up = base_low + 2 * n[id_th];
     733             :     }
     734             : 
     735     7222656 :     sign_theta = 1;
     736             : 
     737     7222656 :     n_crt = n[id_th];
     738     7222656 :     if ( sphIndex < base_low )
     739             :     {
     740      355036 :         id_th--;
     741      355036 :         n_crt = n[id_th];
     742      355036 :         if ( id_th == 0 )
     743             :         {
     744       96215 :             base_low = 0;
     745       96215 :             base_up = n_crt;
     746             :         }
     747             :         else
     748             :         {
     749      258821 :             base_up = base_low;
     750      258821 :             base_low -= 2 * n[id_th];
     751             :         }
     752      355036 :         assert( sphIndex >= base_low );
     753             :     }
     754     6867620 :     else if ( sphIndex >= base_up )
     755             :     {
     756      226601 :         id_th++;
     757      226601 :         n_crt = n[id_th];
     758      226601 :         base_low = base_up;
     759      226601 :         base_up += 2 * n_crt;
     760      226601 :         assert( sphIndex < base_up );
     761             :     }
     762             : 
     763     7222656 :     id_phi = (int16_t) ( sphIndex - base_low );
     764     7222656 :     if ( sphIndex - base_low >= n_crt )
     765             :     {
     766     4276282 :         id_phi -= n_crt;
     767     4276282 :         sign_theta = -1;
     768             :     }
     769             : 
     770     7222656 :     if ( id_th == 0 )
     771             :     {
     772      183677 :         *theta = 0.f;
     773      183677 :         *phi = (float) sphIndex * 360 / (float) n_crt - 180;
     774             :     }
     775             :     else
     776             :     {
     777     7038979 :         if ( id_th == no_th - 1 )
     778             :         {
     779         321 :             id_phi = 0;
     780         321 :             *phi = -180;
     781         321 :             *theta = 90 * (float) sign_theta;
     782             :         }
     783             :         else
     784             :         {
     785     7038658 :             *theta = id_th * MASA_ANGLE_AT_EQUATOR_DEG * (float) sign_theta;
     786     7038658 :             if ( id_th % 2 == 0 )
     787             :             {
     788     3432836 :                 *phi = (float) id_phi * 360 / (float) n_crt - 180;
     789             :             }
     790             :             else
     791             :             {
     792     3605822 :                 *phi = ( (float) id_phi + 0.5f ) * 360 / (float) n_crt - 180;
     793             :             }
     794             :         }
     795             :     }
     796             : 
     797     7222656 :     return;
     798             : }
     799             : 
     800             : 
     801             : /*---------------------------------------------------------------
     802             :  * valid_ratio_index()
     803             :  *
     804             :  * Checking validity of the index of an ISM ratio index vector,
     805             :  * within the indexing function.
     806             :  *---------------------------------------------------------------*/
     807             : 
     808             : /*! r: valid or not 1/0 */
     809     3658094 : int16_t valid_ratio_index(
     810             :     int16_t index,    /* i  : index to be checked        */
     811             :     const int16_t K,  /* i  : L1 norm to check against   */
     812             :     const int16_t len /* i  : vector length              */
     813             : )
     814             : {
     815             :     int16_t out;
     816             :     int16_t i, sum, elem;
     817             :     int16_t base[4];
     818             : 
     819     3658094 :     sum = 0;
     820     3658094 :     set_s( base, 1, len );
     821             : 
     822             : 
     823    10906718 :     for ( i = 1; i < len; i++ )
     824             :     {
     825     7248624 :         base[i] = base[i - 1] * 10;
     826             :     }
     827     3658094 :     sum = 0;
     828    14564812 :     for ( i = len - 1; i >= 0; i-- )
     829             :     {
     830    10906718 :         elem = index / base[i];
     831    10906718 :         sum += elem;
     832    10906718 :         index -= elem * base[i];
     833             :     }
     834     3658094 :     if ( sum <= K )
     835             :     {
     836     1003953 :         out = 1;
     837             :     }
     838             :     else
     839             :     {
     840     2654141 :         out = 0;
     841             :     }
     842             : 
     843     3658094 :     return out;
     844             : }
     845             : 
     846             : 
     847             : /*---------------------------------------------------------------
     848             :  * reconstruct_ism_ratios()
     849             :  *
     850             :  * Obtains ISM ratio values from the quantized indexes
     851             :  *---------------------------------------------------------------*/
     852             : 
     853      120793 : void reconstruct_ism_ratios(
     854             :     int16_t *ratio_ism_idx,   /* i  : index vector                 */
     855             :     const int16_t nchan_ism,  /* i  : number of components/objects */
     856             :     const float step,         /* i  : quantization step            */
     857             :     float *q_energy_ratio_ism /* o  : reconstructed ISM values     */
     858             : )
     859             : {
     860             :     int16_t i;
     861             :     float sum;
     862             : 
     863      120793 :     sum = 0;
     864      425706 :     for ( i = 0; i < nchan_ism - 1; i++ )
     865             :     {
     866      304913 :         q_energy_ratio_ism[i] = ratio_ism_idx[i] * step;
     867      304913 :         sum += q_energy_ratio_ism[i];
     868             :     }
     869             : 
     870      120793 :     q_energy_ratio_ism[nchan_ism - 1] = 1.0f - sum;
     871             : 
     872      120793 :     if ( q_energy_ratio_ism[nchan_ism - 1] < 0 )
     873             :     {
     874       10762 :         q_energy_ratio_ism[nchan_ism - 1] = 0.0f;
     875             :     }
     876             : 
     877      120793 :     return;
     878             : }
     879             : 
     880             : 
     881             : /*---------------------------------------------------------------
     882             :  * ivas_omasa_modify_masa_energy_ratios()
     883             :  *
     884             :  * Updates energy ratios by taking into account the MASA content contribution
     885             :  * to the total audio scene
     886             :  *---------------------------------------------------------------*/
     887             : 
     888        7364 : void ivas_omasa_modify_masa_energy_ratios(
     889             :     IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle  */
     890             :     float masa_to_total_energy_ratio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_MAXIMUM_CODING_SUBBANDS] )
     891             : {
     892             :     int16_t i, m, d, b;
     893             : 
     894       36820 :     for ( m = 0; m < MAX_PARAM_SPATIAL_SUBFRAMES; m++ )
     895             :     {
     896       29456 :         if ( hQMetaData->q_direction[0].cfg.nblocks == 1 )
     897             :         {
     898        9388 :             i = 0;
     899             :         }
     900             :         else
     901             :         {
     902       20068 :             i = m;
     903             :         }
     904             : 
     905      216072 :         for ( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
     906             :         {
     907      414656 :             for ( d = 0; d < hQMetaData->no_directions; d++ )
     908             :             {
     909      228040 :                 hQMetaData->q_direction[d].band_data[b].energy_ratio[m] = hQMetaData->q_direction[d].band_data[b].energy_ratio[m] * masa_to_total_energy_ratio[i][b];
     910             :             }
     911             :         }
     912             :     }
     913             : 
     914        7364 :     return;
     915             : }
     916             : 
     917             : 
     918             : /*---------------------------------------------------------------
     919             :  * distribute_evenly_ism()
     920             :  *
     921             :  * Obtain ISM ratio indexes for even content distribution bbetween objects
     922             :  *---------------------------------------------------------------*/
     923             : 
     924       14414 : void distribute_evenly_ism(
     925             :     int16_t *idx,           /* o  : index values        */
     926             :     const int16_t K,        /* i  : sum of indexes      */
     927             :     const int16_t nchan_ism /* i  : number of objects   */
     928             : )
     929             : {
     930             :     int16_t i;
     931             :     int16_t sum;
     932             : 
     933       14414 :     sum = 0;
     934       63138 :     for ( i = 0; i < nchan_ism; i++ )
     935             :     {
     936       48724 :         idx[i] = (int16_t) ( K / nchan_ism );
     937       48724 :         sum += idx[i];
     938             :     }
     939             : 
     940       14414 :     assert( sum <= K );
     941             : 
     942       14414 :     i = 0;
     943       43060 :     while ( sum < K )
     944             :     {
     945       28646 :         if ( i == nchan_ism )
     946             :         {
     947           0 :             i = 0;
     948             :         }
     949       28646 :         idx[i]++;
     950       28646 :         sum++;
     951       28646 :         i++;
     952             :     }
     953             : 
     954       14414 :     return;
     955             : }
     956             : 
     957             : 
     958             : /*---------------------------------------------------------------
     959             :  * calculate_cpe_brate_MASA_ISM()
     960             :  *
     961             :  * Calculates bitrate for MASA_ISM mode that is not used for separated objects,
     962             :  * * but for the CPE part (metadata included)
     963             :  *---------------------------------------------------------------*/
     964             : 
     965             : /*! r: CPE bitrate value       */
     966       41677 : int32_t calculate_cpe_brate_MASA_ISM(
     967             :     const ISM_MODE ism_mode,        /* i  : ism mode                */
     968             :     const int32_t ivas_total_brate, /* i  : IVAS total bitrate      */
     969             :     const int16_t nchan_ism         /* i  : number of objects       */
     970             : )
     971             : {
     972             :     int32_t cpe_brate;
     973             :     int16_t k, sce_id;
     974             : 
     975       41677 :     k = 0;
     976      443139 :     while ( k < SIZE_IVAS_BRATE_TBL && ivas_total_brate != ivas_brate_tbl[k] )
     977             :     {
     978      401462 :         k++;
     979             :     }
     980             : 
     981       41677 :     if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
     982             :     {
     983       14033 :         cpe_brate = ivas_total_brate - sep_object_brate[k - 2][0]; /* take data from the first column */
     984             :     }
     985       27644 :     else if ( ism_mode == ISM_MASA_MODE_DISC )
     986             :     {
     987       26323 :         cpe_brate = ivas_total_brate;
     988             : 
     989       97707 :         for ( sce_id = 0; sce_id < nchan_ism; sce_id++ )
     990             :         {
     991       71384 :             cpe_brate -= sep_object_brate[k - 2][nchan_ism - 1];
     992             :         }
     993             :     }
     994             :     else
     995             :     {
     996        1321 :         cpe_brate = ivas_total_brate;
     997             :     }
     998             : 
     999       41677 :     return cpe_brate;
    1000             : }

Generated by: LCOV version 1.14