LCOV - code coverage report
Current view: top level - lib_com - ivas_masa_com.c (source / functions) Hit Total Coverage
Test: Coverage on main -- merged total coverage @ 9b04ec3cb36f5e8dc438cf854fa3e349998fa1e9 Lines: 326 335 97.3 %
Date: 2025-10-31 05:45:46 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     5275427 : 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     5275427 :     if ( nchan_transport == 2 )
      85             :     {
      86     3818346 :         if ( ivas_total_brate >= MCMASA_SEPARATE_BRATE && mc_mode == MC_MODE_MCMASA )
      87             :         {
      88      133108 :             *nCPE = 1;
      89      133108 :             *nSCE = 1;
      90             : 
      91      133108 :             *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     3685238 :         else if ( ivas_format == MASA_ISM_FORMAT && ism_mode != ISM_MODE_NONE )
      94             :         {
      95     1463735 :             *nCPE = 1;
      96             : 
      97     1463735 :             if ( *element_mode == -1 )
      98             :             {
      99     1069596 :                 *element_mode = IVAS_CPE_DFT; /* To have it initialized in case it was not already. */
     100             :             }
     101     1463735 :             if ( ivas_total_brate > MIN_BRATE_MDCT_STEREO )
     102             :             {
     103     1008215 :                 *element_mode = IVAS_CPE_MDCT;
     104     1008215 :                 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       85726 :                     *element_mode = IVAS_CPE_DFT;
     107             :                 }
     108             :             }
     109             :         }
     110             :         else
     111             :         {
     112     2221503 :             *nCPE = 1;
     113     2221503 :             *nSCE = 0;
     114             : 
     115     2221503 :             if ( ivas_total_brate > MIN_BRATE_MDCT_STEREO )
     116             :             {
     117     1027092 :                 *element_mode = IVAS_CPE_MDCT;
     118             :             }
     119             :         }
     120     3818346 :         hQMetaData->bits_frame_nominal = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC );
     121     3818346 :         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     1463735 :             hQMetaData->bits_frame_nominal -= (int16_t) ( ism_total_brate / FRAMES_PER_SEC );
     124             :         }
     125             :     }
     126     1457081 :     else if ( nchan_transport == 1 )
     127             :     {
     128     1457081 :         *nCPE = 0;
     129     1457081 :         *nSCE = 1;
     130             : 
     131     1457081 :         if ( ivas_total_brate == IVAS_13k2 )
     132             :         {
     133      200844 :             hQMetaData->bits_frame_nominal = ACELP_9k60 / FRAMES_PER_SEC;
     134             :         }
     135     1256237 :         else if ( ivas_total_brate <= IVAS_16k4 )
     136             :         {
     137      100053 :             hQMetaData->bits_frame_nominal = ACELP_13k20 / FRAMES_PER_SEC;
     138             :         }
     139     1156184 :         else if ( ivas_total_brate <= IVAS_24k4 )
     140             :         {
     141      396082 :             hQMetaData->bits_frame_nominal = ACELP_16k40 / FRAMES_PER_SEC;
     142             :         }
     143      760102 :         else if ( ivas_total_brate <= IVAS_32k )
     144             :         {
     145      194272 :             hQMetaData->bits_frame_nominal = ACELP_24k40 / FRAMES_PER_SEC;
     146             :         }
     147             :         else
     148             :         {
     149      565830 :             hQMetaData->bits_frame_nominal = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC );
     150             :         }
     151     1457081 :         *element_mode = IVAS_SCE;
     152             :     }
     153             :     else
     154             :     {
     155           0 :         assert( !"MASA number of transport channels must be 1, or 2" );
     156             :     }
     157             : 
     158     5275427 :     return;
     159             : }
     160             : 
     161             : 
     162             : /*---------------------------------------------------------------
     163             :  * generate_gridEq()
     164             :  *
     165             :  * generate Spherical grid
     166             :  *---------------------------------------------------------------*/
     167             : 
     168       17458 : 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       17458 :     n = data->no_phi;
     178       17458 :     n[0] = MASA_NO_POINTS_EQUATOR;
     179             : 
     180       17458 :     cum_n_prev = 0;
     181             : 
     182     2112418 :     for ( i = 1; i < MASA_NO_CIRCLES; i++ )
     183             :     {
     184     2094960 :         theta = MASA_ANGLE_AT_EQUATOR * (float) ( i + 0.5f );
     185     2094960 :         if ( i == 1 )
     186             :         {
     187       17458 :             cum_n = 2 * (int32_t) ceilf( MASA_NTOT2_FAC * ( sinf( theta ) - MASA_ASIN_OFFSET ) );
     188             :         }
     189             :         else
     190             :         {
     191     2077502 :             cum_n = 2 * (int32_t) roundf( MASA_NTOT2_FAC * ( sinf( theta ) - MASA_ASIN_OFFSET ) );
     192             :         }
     193     2094960 :         n[i] = (int16_t) ( ( cum_n - cum_n_prev ) >> 1 );
     194     2094960 :         cum_n_prev = cum_n;
     195             :     }
     196       17458 :     n[i] = 1;
     197       17458 :     data->no_theta = i + 1;
     198             : 
     199       17458 :     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     5023944 : 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     5023944 :     nbands = 0;
     232     5023944 :     nTwoDirBands = 0;
     233     5023944 :     i = 0;
     234             : 
     235             :     /* First select correct bit budget table */
     236     5023944 :     masa_bits_table = masa_bits;
     237     5023944 :     if ( isMcMasa )
     238             :     {
     239      652186 :         masa_bits_table = mcmasa_bits;
     240             :     }
     241     4371758 :     else if ( ivas_total_brate < IVAS_48k && nchan_transport == 2 )
     242             :     {
     243     1436613 :         masa_bits_table = masa_bits_LR_stereo;
     244             :     }
     245             : 
     246    35164481 :     while ( nbands == 0 && i < IVAS_NUM_ACTIVE_BRATES )
     247             :     {
     248    30140537 :         if ( ivas_total_brate <= ivas_brate_tbl[i + SIZE_IVAS_BRATE_TBL - IVAS_NUM_ACTIVE_BRATES] )
     249             :         {
     250             :             int16_t idx_bands;
     251     5023944 :             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       49901 :                 i = 3;
     255             :             }
     256     5023944 :             idx_bands = i;
     257             : 
     258     5023944 :             if ( config->numberOfDirections > 1 )
     259             :             {
     260      911090 :                 nTwoDirBands = config->joinedSubframes ? masa_twodir_bands_joined[i] : masa_twodir_bands[i];
     261             : 
     262      911090 :                 if ( ( ivas_total_brate > IVAS_96k && !config->joinedSubframes ) || ( ivas_total_brate > IVAS_80k && config->joinedSubframes ) )
     263             :                 {
     264      452240 :                     idx_bands--;
     265             :                 }
     266             :             }
     267             : 
     268     5023944 :             if ( config->joinedSubframes )
     269             :             {
     270     1204564 :                 nbands = masa_joined_nbands[idx_bands];
     271             :             }
     272             :             else
     273             :             {
     274     3819380 :                 nbands = masa_nbands[idx_bands];
     275             :             }
     276             : 
     277     5023944 :             config->max_metadata_bits = masa_bits_table[i];
     278             : 
     279     5023944 :             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       95688 :                 config->max_metadata_bits += MASA_EXTRA_BAND_META_BITS;
     283             :             }
     284             : 
     285     5023944 :             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      228344 :                 config->max_metadata_bits += ( MASA_SMALL_INC_META_BITS );
     289             :             }
     290             :         }
     291    30140537 :         i++;
     292             :     }
     293     5023944 :     config->numCodingBands = nbands;
     294     5023944 :     config->numTwoDirBands = nTwoDirBands;
     295             : 
     296             : #ifdef DEBUGGING
     297             :     assert( nbands > 0 );
     298             : #endif
     299     5023944 :     if ( config->joinedSubframes == TRUE )
     300             :     {
     301     1204564 :         config->mergeRatiosOverSubframes = FALSE;
     302             :     }
     303             :     else
     304             :     {
     305     3819380 :         config->mergeRatiosOverSubframes = TRUE;
     306             :     }
     307             : 
     308             :     /* Setup frequency band mapping based on the number of used coding bands */
     309     5023944 :     switch ( config->numCodingBands )
     310             :     {
     311     3288051 :         case 5:
     312     3288051 :             mvs2s( MASA_band_mapping_24_to_5, band_mapping, 5 + 1 );
     313     3288051 :             break;
     314      375732 :         case 8:
     315      375732 :             mvs2s( MASA_band_mapping_24_to_8, band_mapping, 8 + 1 );
     316      375732 :             break;
     317      393260 :         case 12:
     318      393260 :             mvs2s( MASA_band_mapping_24_to_12, band_mapping, 12 + 1 );
     319      393260 :             break;
     320      424258 :         case 18:
     321      424258 :             mvs2s( MASA_band_mapping_24_to_18, band_mapping, 18 + 1 );
     322      424258 :             break;
     323      542643 :         case MASA_FREQUENCY_BANDS:
     324             :             /* With input count of bands, no mapping is needed but for unified processing later, we store normal mapping */
     325    14108718 :             for ( i = 0; i < MASA_FREQUENCY_BANDS + 1; i++ )
     326             :             {
     327    13566075 :                 band_mapping[i] = i;
     328             :             }
     329      542643 :             break;
     330           0 :         default:
     331           0 :             assert( 0 && "Error: The number of MASA coding bands is not supported" );
     332             :     }
     333             : 
     334     5023944 :     config->useCoherence = TRUE;
     335     5023944 :     if ( ( !isMcMasa && ivas_total_brate < IVAS_48k ) || ( isMcMasa && ivas_total_brate < IVAS_16k4 ) )
     336             :     {
     337     1916811 :         config->useCoherence = FALSE;
     338             :     }
     339             : 
     340     5023944 :     return;
     341             : }
     342             : 
     343             : 
     344             : /*---------------------------------------------------------------
     345             :  * masa_sample_rate_band_correction()
     346             :  *
     347             :  *
     348             :  *---------------------------------------------------------------*/
     349             : 
     350     5023944 : 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     5023944 :     numBands48k = config->numCodingBands;
     364             : 
     365    44263650 :     for ( band = 1; band < config->numCodingBands + 1; band++ )
     366             :     {
     367    44263650 :         highBand = band_mapping[band];
     368             : 
     369    44263650 :         if ( highBand >= maxBand )
     370             :         {
     371     5023944 :             config->numCodingBands = band;
     372     5023944 :             hQMetaData->numCodingBands = band;
     373             : 
     374     5023944 :             if ( is_encoder )
     375             :             {
     376       67592 :                 if ( hQMetaData->q_direction->cfg.nbands > band )
     377             :                 {
     378       14970 :                     hQMetaData->q_direction->cfg.nbands = band;
     379             :                 }
     380       67592 :                 if ( hQMetaData->no_directions == 2 && hQMetaData->q_direction[1].cfg.nbands > band )
     381             :                 {
     382        5146 :                     hQMetaData->q_direction[1].cfg.nbands = band;
     383             :                 }
     384             :             }
     385             : 
     386     5023944 :             band_mapping[band] = maxBand;
     387             : 
     388     5023944 :             break;
     389             :         }
     390             :     }
     391             : 
     392             :     /* Set rest of the bands to zero in qmetadata. */
     393     5585601 :     for ( ; band < numBands48k; band++ )
     394             :     {
     395     2808285 :         for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
     396             :         {
     397     2246628 :             hQMetaData->q_direction[0].band_data[band].azimuth[sf] = 0.0f;
     398     2246628 :             hQMetaData->q_direction[0].band_data[band].elevation[sf] = 0.0f;
     399     2246628 :             hQMetaData->q_direction[0].band_data[band].energy_ratio[sf] = 0.0f;
     400             : 
     401     2246628 :             if ( hQMetaData->coherence_flag && hQMetaData->q_direction[0].coherence_band_data != NULL )
     402             :             {
     403     2239152 :                 hQMetaData->q_direction[0].coherence_band_data[band].spread_coherence[sf] = 0u;
     404             :             }
     405             : 
     406     2246628 :             if ( hQMetaData->no_directions == 2 )
     407             :             {
     408      360908 :                 hQMetaData->q_direction[1].band_data[band].azimuth[sf] = 0.0f;
     409      360908 :                 hQMetaData->q_direction[1].band_data[band].elevation[sf] = 0.0f;
     410      360908 :                 hQMetaData->q_direction[1].band_data[band].energy_ratio[sf] = 0.0f;
     411             : 
     412      360908 :                 if ( hQMetaData->coherence_flag && hQMetaData->q_direction[1].coherence_band_data != NULL )
     413             :                 {
     414      360908 :                     hQMetaData->q_direction[1].coherence_band_data[band].spread_coherence[sf] = 0u;
     415             :                 }
     416             :             }
     417             : 
     418     2246628 :             if ( hQMetaData->coherence_flag && hQMetaData->surcoh_band_data != NULL )
     419             :             {
     420     2239152 :                 hQMetaData->surcoh_band_data[band].surround_coherence[sf] = 0u;
     421             :             }
     422             :         }
     423             : 
     424      561657 :         if ( hQMetaData->no_directions == 2 )
     425             :         {
     426       90227 :             hQMetaData->twoDirBands[band] = 0;
     427             :         }
     428             :     }
     429             : 
     430     5023944 :     if ( hExtOutMeta != NULL )
     431             :     {
     432             :         /* in decoder, zero the EXT out MASA meta buffer */
     433     2639780 :         for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
     434             :         {
     435    29177148 :             for ( band = hQMetaData->numCodingBands; band < MASA_FREQUENCY_BANDS; band++ )
     436             :             {
     437    27065324 :                 hExtOutMeta->directionIndex[0][sf][band] = SPH_IDX_FRONT;
     438    27065324 :                 hExtOutMeta->directToTotalRatio[0][sf][band] = 0u;
     439    27065324 :                 hExtOutMeta->spreadCoherence[0][sf][band] = 0u;
     440             : 
     441    27065324 :                 hExtOutMeta->directionIndex[1][sf][band] = SPH_IDX_FRONT;
     442    27065324 :                 hExtOutMeta->directToTotalRatio[1][sf][band] = 0u;
     443    27065324 :                 hExtOutMeta->spreadCoherence[1][sf][band] = 0u;
     444             : 
     445    27065324 :                 hExtOutMeta->surroundCoherence[sf][band] = 0u;
     446    27065324 :                 hExtOutMeta->diffuseToTotalRatio[sf][band] = UINT8_MAX;
     447             :             }
     448             :         }
     449             :     }
     450             : 
     451     5023944 :     return;
     452             : }
     453             : 
     454             : 
     455             : /*-------------------------------------------------------------------------
     456             :  * index_theta_phi_16()
     457             :  *
     458             :  *
     459             :  *------------------------------------------------------------------------*/
     460             : 
     461             : /*! r: output index for direction */
     462    93249174 : 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    93249174 :     theta = *p_theta;
     476    93249174 :     phi = *p_phi;
     477    93249174 :     phi_hat = 0;
     478    93249174 :     theta_hat = 0;
     479    93249174 :     phi = phi + 180;
     480             : 
     481    93249174 :     if ( theta < 0 )
     482             :     {
     483    36147343 :         abs_theta = -theta;
     484    36147343 :         sign_th = -1;
     485             :     }
     486             :     else
     487             :     {
     488    57101831 :         abs_theta = theta;
     489    57101831 :         sign_th = 1;
     490             :     }
     491             : 
     492    93249174 :     id_th = quantize_theta_masa( abs_theta, gridData->no_theta, &theta_hat );
     493    93249174 :     if ( gridData->no_theta > 1 )
     494             :     {
     495    93249174 :         if ( gridData->no_phi[id_th] > 1 )
     496             :         {
     497    93237195 :             id_phi = quantize_phi_masa( phi, ( id_th % 2 == 1 ), &phi_hat, gridData->no_phi[id_th] );
     498             :         }
     499             :         else
     500             :         {
     501       11979 :             id_phi = 0;
     502       11979 :             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    93249174 :     *p_theta = sign_th * theta_hat;
     510    93249174 :     *p_phi = phi_hat - 180;
     511             : 
     512             :     /* Starting from Equator, alternating positive and negative */
     513    93249174 :     if ( id_th == 0 )
     514             :     {
     515    24437313 :         idx_sph = id_phi;
     516             :     }
     517             :     else
     518             :     {
     519    68811861 :         if ( id_th == gridData->no_theta - 1 )
     520             :         {
     521       11979 :             idx_sph = 65534 + ( sign_th < 0 );
     522             :         }
     523             :         else
     524             :         {
     525    68799882 :             theta = MASA_ANGLE_AT_EQUATOR * (float) ( id_th + 0.5f );
     526    68799882 :             if ( id_th == 1 )
     527             :             {
     528     2332694 :                 cum_n = 2 * (uint16_t) ceilf( MASA_NTOT2_FAC * ( sinf( theta ) - MASA_ASIN_OFFSET ) );
     529             :             }
     530             :             else
     531             :             {
     532    66467188 :                 cum_n = 2 * (uint16_t) roundf( MASA_NTOT2_FAC * ( sinf( theta ) - MASA_ASIN_OFFSET ) );
     533             :             }
     534             : 
     535    68799882 :             cum_n += gridData->no_phi[0];
     536             : 
     537    68799882 :             if ( sign_th > 0 )
     538             :             {
     539    32966296 :                 cum_n -= 2 * gridData->no_phi[id_th];
     540             :             }
     541             :             else
     542             :             {
     543    35833586 :                 cum_n -= gridData->no_phi[id_th];
     544             :             }
     545    68799882 :             idx_sph = cum_n + id_phi;
     546             :         }
     547             :     }
     548             : 
     549    93249174 :     return idx_sph;
     550             : }
     551             : 
     552             : 
     553             : /*-------------------------------------------------------------------------
     554             :  * quantize_phi_masa()
     555             :  *
     556             :  *
     557             :  *------------------------------------------------------------------------*/
     558             : 
     559             : /*! r: output index */
     560    93249174 : 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    93249174 :     imin = (int16_t) ( x * MASA_INV_ANGLE_AT_EQUATOR_DEG + 0.5f );
     570             : 
     571    93249174 :     if ( imin >= no_cb - 1 )
     572             :     {
     573       12516 :         imin = no_cb - 1;
     574       12516 :         diff1 = x - 90;
     575       12516 :         diff2 = x - MASA_ANGLE_AT_EQUATOR_DEG * ( imin - 1 );
     576       12516 :         if ( fabsf( diff1 ) > fabsf( diff2 ) )
     577             :         {
     578         537 :             imin--;
     579         537 :             *xhat = imin * MASA_ANGLE_AT_EQUATOR_DEG;
     580             :         }
     581             :         else
     582             :         {
     583       11979 :             *xhat = 90;
     584             :         }
     585             :     }
     586             :     else
     587             :     {
     588    93236658 :         *xhat = imin * MASA_ANGLE_AT_EQUATOR_DEG;
     589             :     }
     590             : 
     591    93249174 :     return imin;
     592             : }
     593             : 
     594             : 
     595             : /*-------------------------------------------------------------------------
     596             :  * quantize_phi_masa()
     597             :  *
     598             :  *
     599             :  *------------------------------------------------------------------------*/
     600             : 
     601             : /*! r: index azimuth */
     602    93237195 : 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    93237195 :     delta_phi = 360.0f / (float) n;
     614             : 
     615    93237195 :     if ( n == 1 )
     616             :     {
     617           0 :         *phi_hat = 0;
     618             : 
     619           0 :         return 0;
     620             :     }
     621             : 
     622    93237195 :     if ( flag_delta == 1 )
     623             :     {
     624    37067212 :         dd = delta_phi / 2.0f;
     625             :     }
     626             :     else
     627             :     {
     628    56169983 :         dd = 0;
     629             :     }
     630             : 
     631    93237195 :     id_phi = (int16_t) ( ( phi - dd + delta_phi / 2.0f ) / (float) delta_phi );
     632             : 
     633    93237195 :     if ( id_phi == n )
     634             :     {
     635        7811 :         id_phi = 0;
     636             :     }
     637             : 
     638    93237195 :     if ( id_phi == -1 )
     639             :     {
     640           0 :         id_phi = n - 1;
     641             :     }
     642             : 
     643    93237195 :     *phi_hat = id_phi * delta_phi + dd;
     644             : 
     645    93237195 :     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  1156427106 : 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  1156427106 :     int16_t no_th = gridData->no_theta;
     670  1156427106 :     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  1156427106 :     const uint16_t limit_index1 = 64964, limit_index2 = 47870;
     676             : 
     677  1156427106 :     if ( sphIndex >= limit_index1 )
     678             :     {
     679     1215213 :         ba_crt = ba[2];
     680     1215213 :         div_crt = div[2];
     681     1215213 :         a4_crt = a4[2];
     682     1215213 :         del_crt = del[2];
     683             :     }
     684  1155211893 :     else if ( sphIndex >= limit_index2 )
     685             :     {
     686    74592091 :         ba_crt = ba[1];
     687    74592091 :         div_crt = div[1];
     688    74592091 :         a4_crt = a4[1];
     689    74592091 :         del_crt = del[1];
     690             :     }
     691             :     else
     692             :     {
     693  1080619802 :         ba_crt = ba[0];
     694  1080619802 :         div_crt = div[0];
     695  1080619802 :         a4_crt = a4[0];
     696  1080619802 :         del_crt = del[0];
     697             :     }
     698  1156427106 :     estim = ba_crt + div_crt * sqrtf( del_crt + a4_crt * sphIndex );
     699             : 
     700  1156427106 :     if ( estim > MASA_NO_CIRCLES )
     701             :     {
     702       39286 :         estim = MASA_NO_CIRCLES;
     703             :     }
     704             : 
     705  1156427106 :     assert( estim > 0 );
     706  1156427106 :     id_th = (int16_t) roundf( estim ) - 1;
     707  1156427106 :     if ( id_th < 0 )
     708             :     {
     709           0 :         id_th = 0;
     710             :     }
     711             : 
     712  1156427106 :     if ( id_th == 0 )
     713             :     {
     714    83481883 :         base_low = 0;
     715    83481883 :         base_up = n[0];
     716             :     }
     717             :     else
     718             :     {
     719  1072945223 :         estim = MASA_ANGLE_AT_EQUATOR * (float) ( id_th - 0.5f );
     720  1072945223 :         base_low = n[0];
     721  1072945223 :         if ( id_th >= 2 )
     722             :         {
     723   977789511 :             if ( id_th == 2 )
     724             :             {
     725    51731152 :                 base_low += 2 * (int16_t) ceilf( MASA_NTOT2_FAC * ( sinf( estim ) - MASA_ASIN_OFFSET ) );
     726             :             }
     727             :             else
     728             :             {
     729   926058359 :                 base_low += 2 * (int16_t) roundf( MASA_NTOT2_FAC * ( sinf( estim ) - MASA_ASIN_OFFSET ) );
     730             :             }
     731             :         }
     732  1072945223 :         base_up = base_low + 2 * n[id_th];
     733             :     }
     734             : 
     735  1156427106 :     sign_theta = 1;
     736             : 
     737  1156427106 :     n_crt = n[id_th];
     738  1156427106 :     if ( sphIndex < base_low )
     739             :     {
     740    86137987 :         id_th--;
     741    86137987 :         n_crt = n[id_th];
     742    86137987 :         if ( id_th == 0 )
     743             :         {
     744    55299658 :             base_low = 0;
     745    55299658 :             base_up = n_crt;
     746             :         }
     747             :         else
     748             :         {
     749    30838329 :             base_up = base_low;
     750    30838329 :             base_low -= 2 * n[id_th];
     751             :         }
     752    86137987 :         assert( sphIndex >= base_low );
     753             :     }
     754  1070289119 :     else if ( sphIndex >= base_up )
     755             :     {
     756    40990874 :         id_th++;
     757    40990874 :         n_crt = n[id_th];
     758    40990874 :         base_low = base_up;
     759    40990874 :         base_up += 2 * n_crt;
     760    40990874 :         assert( sphIndex < base_up );
     761             :     }
     762             : 
     763  1156427106 :     id_phi = (int16_t) ( sphIndex - base_low );
     764  1156427106 :     if ( sphIndex - base_low >= n_crt )
     765             :     {
     766   526774315 :         id_phi -= n_crt;
     767   526774315 :         sign_theta = -1;
     768             :     }
     769             : 
     770  1156427106 :     if ( id_th == 0 )
     771             :     {
     772   138781541 :         *theta = 0.f;
     773   138781541 :         *phi = (float) sphIndex * 360 / (float) n_crt - 180;
     774             :     }
     775             :     else
     776             :     {
     777  1017645565 :         if ( id_th == no_th - 1 )
     778             :         {
     779       14761 :             id_phi = 0;
     780       14761 :             *phi = -180;
     781       14761 :             *theta = 90 * (float) sign_theta;
     782             :         }
     783             :         else
     784             :         {
     785  1017630804 :             *theta = id_th * MASA_ANGLE_AT_EQUATOR_DEG * (float) sign_theta;
     786  1017630804 :             if ( id_th % 2 == 0 )
     787             :             {
     788   480396223 :                 *phi = (float) id_phi * 360 / (float) n_crt - 180;
     789             :             }
     790             :             else
     791             :             {
     792   537234581 :                 *phi = ( (float) id_phi + 0.5f ) * 360 / (float) n_crt - 180;
     793             :             }
     794             :         }
     795             :     }
     796             : 
     797  1156427106 :     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    41556775 : 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    41556775 :     sum = 0;
     820    41556775 :     set_s( base, 1, len );
     821             : 
     822             : 
     823   123111163 :     for ( i = 1; i < len; i++ )
     824             :     {
     825    81554388 :         base[i] = base[i - 1] * 10;
     826             :     }
     827    41556775 :     sum = 0;
     828   164667938 :     for ( i = len - 1; i >= 0; i-- )
     829             :     {
     830   123111163 :         elem = index / base[i];
     831   123111163 :         sum += elem;
     832   123111163 :         index -= elem * base[i];
     833             :     }
     834    41556775 :     if ( sum <= K )
     835             :     {
     836    13484082 :         out = 1;
     837             :     }
     838             :     else
     839             :     {
     840    28072693 :         out = 0;
     841             :     }
     842             : 
     843    41556775 :     return out;
     844             : }
     845             : 
     846             : 
     847             : /*---------------------------------------------------------------
     848             :  * reconstruct_ism_ratios()
     849             :  *
     850             :  * Obtains ISM ratio values from the quantized indexes
     851             :  *---------------------------------------------------------------*/
     852             : 
     853     4911533 : 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     4911533 :     sum = 0;
     864    17370378 :     for ( i = 0; i < nchan_ism - 1; i++ )
     865             :     {
     866    12458845 :         q_energy_ratio_ism[i] = ratio_ism_idx[i] * step;
     867    12458845 :         sum += q_energy_ratio_ism[i];
     868             :     }
     869             : 
     870     4911533 :     q_energy_ratio_ism[nchan_ism - 1] = 1.0f - sum;
     871             : 
     872     4911533 :     if ( q_energy_ratio_ism[nchan_ism - 1] < 0 )
     873             :     {
     874      193712 :         q_energy_ratio_ism[nchan_ism - 1] = 0.0f;
     875             :     }
     876             : 
     877     4911533 :     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      317364 : 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     1586820 :     for ( m = 0; m < MAX_PARAM_SPATIAL_SUBFRAMES; m++ )
     895             :     {
     896     1269456 :         if ( hQMetaData->q_direction[0].cfg.nblocks == 1 )
     897             :         {
     898      535860 :             i = 0;
     899             :         }
     900             :         else
     901             :         {
     902      733596 :             i = m;
     903             :         }
     904             : 
     905    10015616 :         for ( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
     906             :         {
     907    19688052 :             for ( d = 0; d < hQMetaData->no_directions; d++ )
     908             :             {
     909    10941892 :                 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      317364 :     return;
     915             : }
     916             : 
     917             : 
     918             : /*---------------------------------------------------------------
     919             :  * distribute_evenly_ism()
     920             :  *
     921             :  * Obtain ISM ratio indexes for even content distribution bbetween objects
     922             :  *---------------------------------------------------------------*/
     923             : 
     924     1752550 : 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     1752550 :     sum = 0;
     934     7758776 :     for ( i = 0; i < nchan_ism; i++ )
     935             :     {
     936     6006226 :         idx[i] = (int16_t) ( K / nchan_ism );
     937     6006226 :         sum += idx[i];
     938             :     }
     939             : 
     940     1752550 :     assert( sum <= K );
     941             : 
     942     1752550 :     i = 0;
     943     5270820 :     while ( sum < K )
     944             :     {
     945     3518270 :         if ( i == nchan_ism )
     946             :         {
     947           0 :             i = 0;
     948             :         }
     949     3518270 :         idx[i]++;
     950     3518270 :         sum++;
     951     3518270 :         i++;
     952             :     }
     953             : 
     954     1752550 :     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     2130407 : 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     2130407 :     k = 0;
     976    23245350 :     while ( k < SIZE_IVAS_BRATE_TBL && ivas_total_brate != ivas_brate_tbl[k] )
     977             :     {
     978    21114943 :         k++;
     979             :     }
     980             : 
     981     2130407 :     if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
     982             :     {
     983      562754 :         cpe_brate = ivas_total_brate - sep_object_brate[k - 2][0]; /* take data from the first column */
     984             :     }
     985     1567653 :     else if ( ism_mode == ISM_MASA_MODE_DISC )
     986             :     {
     987     1526785 :         cpe_brate = ivas_total_brate;
     988             : 
     989     5319195 :         for ( sce_id = 0; sce_id < nchan_ism; sce_id++ )
     990             :         {
     991     3792410 :             cpe_brate -= sep_object_brate[k - 2][nchan_ism - 1];
     992             :         }
     993             :     }
     994             :     else
     995             :     {
     996       40868 :         cpe_brate = ivas_total_brate;
     997             :     }
     998             : 
     999     2130407 :     return cpe_brate;
    1000             : }

Generated by: LCOV version 1.14