LCOV - code coverage report
Current view: top level - lib_com - ivas_qmetadata_com.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 181 190 95.3 %
Date: 2025-05-23 08:37:30 Functions: 14 14 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 <math.h>
      36             : #include "options.h"
      37             : #include "ivas_cnst.h"
      38             : #include "ivas_rom_com.h"
      39             : #include "ivas_prot.h"
      40             : #include "prot.h"
      41             : #include "cnst.h"
      42             : #include "wmc_auto.h"
      43             : 
      44             : /*-----------------------------------------------------------------------*
      45             :  * Local constants
      46             :  *-----------------------------------------------------------------------*/
      47             : 
      48             : #define MASA_DIR_RATIO_COMP_MAX_IDX_STEPS 2
      49             : 
      50             : /*-----------------------------------------------------------------------*
      51             :  * Local function prototypes
      52             :  *-----------------------------------------------------------------------*/
      53             : 
      54             : static void ivas_qmetadata_free_memory( IVAS_QMETADATA_HANDLE hQMetaData );
      55             : 
      56             : 
      57             : /*-----------------------------------------------------------------------*
      58             :  * ivas_qmetadata_open()
      59             :  *
      60             :  * Allocate Q Metadata handle
      61             :  *-----------------------------------------------------------------------*/
      62             : 
      63        2596 : ivas_error ivas_qmetadata_open(
      64             :     IVAS_QMETADATA_HANDLE *hQMetaData /* i/o: q_metadata handle         */
      65             : )
      66             : {
      67             :     /* allocate  MetaData handle */
      68        2596 :     if ( ( *hQMetaData = (IVAS_QMETADATA_HANDLE) malloc( sizeof( IVAS_QMETADATA ) ) ) == NULL )
      69             :     {
      70           0 :         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for Q MetaData" );
      71             :     }
      72             : 
      73        2596 :     ( *hQMetaData )->q_direction = NULL;
      74        2596 :     ( *hQMetaData )->surcoh_band_data = NULL;
      75        2596 :     ( *hQMetaData )->bandMap = NULL;
      76             : 
      77        2596 :     return IVAS_ERR_OK;
      78             : }
      79             : 
      80             : 
      81             : /*-----------------------------------------------------------------------*
      82             :  * ivas_qmetadata_allocate_memory()
      83             :  *
      84             :  * Allocates dynamic memory for qmetadata. Also reallocates automatically
      85             :  * if relevant parameters have changed. To function properly, this function
      86             :  * assumes that qmetadata contains parameter values for nbands, ndirs and
      87             :  * coherence_flag corresponding to the currently reserved memory. This function
      88             :  * then compares them to provided new values given in call and allocates or
      89             :  * reallocates as necessary. The parameter values in qmetadata are updated
      90             :  * accordingly. In addition, parameters inside qdirection config are
      91             :  * set here to their default values out of practicality.
      92             :  *-----------------------------------------------------------------------*/
      93             : 
      94      199242 : ivas_error ivas_qmetadata_allocate_memory(
      95             :     IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle             */
      96             :     const int16_t nbands,             /* i  : new number of frequency bands */
      97             :     const int16_t ndirs,              /* i  : new number of directions      */
      98             :     const int16_t coherence_flag      /* i  : new coherence coding status   */
      99             : )
     100             : {
     101             :     int16_t j, dir;
     102             :     uint8_t do_realloc;
     103             : 
     104             : #ifdef DEBUGGING
     105             :     assert( hQMetaData != NULL );
     106             : #endif
     107             : 
     108             :     /* Check if we need to reallocate memory or do we need to do the first time allocation. */
     109      199242 :     if ( hQMetaData->q_direction != NULL )
     110             :     {
     111      196646 :         do_realloc = nbands != hQMetaData->q_direction->cfg.nbands;
     112      196646 :         do_realloc |= ndirs != hQMetaData->no_directions;
     113      196646 :         do_realloc |= coherence_flag != hQMetaData->coherence_flag;
     114             :     }
     115             :     else
     116             :     {
     117        2596 :         do_realloc = TRUE;
     118             :     }
     119             : 
     120      199242 :     if ( do_realloc )
     121             :     {
     122       16432 :         ivas_qmetadata_free_memory( hQMetaData );
     123             : 
     124       16432 :         hQMetaData->numCodingBands = (uint8_t) nbands;
     125       16432 :         hQMetaData->no_directions = ndirs;
     126       16432 :         hQMetaData->coherence_flag = coherence_flag;
     127             : 
     128       16432 :         if ( ( hQMetaData->q_direction = (IVAS_QDIRECTION *) malloc( sizeof( IVAS_QDIRECTION ) * ndirs ) ) == NULL )
     129             :         {
     130           0 :             return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for Q MetaData" );
     131             :         }
     132             : 
     133       34725 :         for ( dir = 0; dir < hQMetaData->no_directions; dir++ )
     134             :         {
     135       18293 :             hQMetaData->q_direction[dir].cfg.nbands = nbands;
     136       18293 :             if ( nbands == 0 )
     137             :             {
     138           0 :                 hQMetaData->q_direction[dir].band_data = NULL;
     139             :             }
     140             :             else
     141             :             {
     142       18293 :                 if ( ( hQMetaData->q_direction[dir].band_data = (IVAS_QDIRECTION_BAND_DATA *) malloc( sizeof( IVAS_QDIRECTION_BAND_DATA ) * hQMetaData->q_direction[dir].cfg.nbands ) ) == NULL )
     143             :                 {
     144           0 :                     return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for Q MetaData" );
     145             :                 }
     146             : 
     147      141295 :                 for ( j = 0; j < nbands; j++ )
     148             :                 {
     149      123002 :                     set_zero( hQMetaData->q_direction[dir].band_data[j].elevation, MAX_PARAM_SPATIAL_SUBFRAMES );
     150      123002 :                     set_zero( hQMetaData->q_direction[dir].band_data[j].azimuth, MAX_PARAM_SPATIAL_SUBFRAMES );
     151      123002 :                     set_zero( hQMetaData->q_direction[dir].band_data[j].energy_ratio, MAX_PARAM_SPATIAL_SUBFRAMES );
     152             :                 }
     153             :             }
     154             : 
     155       18293 :             if ( coherence_flag )
     156             :             {
     157        7001 :                 hQMetaData->q_direction[dir].coherence_band_data = (IVAS_QDIRECTION_BAND_COHERENCE_DATA *) malloc( sizeof( IVAS_QDIRECTION_BAND_COHERENCE_DATA ) * hQMetaData->q_direction[dir].cfg.nbands );
     158             :             }
     159             :             else
     160             :             {
     161       11292 :                 hQMetaData->q_direction[dir].coherence_band_data = NULL;
     162             :             }
     163             : 
     164             :             /* These default values are set here to get them conveniently in one place */
     165       18293 :             hQMetaData->q_direction[dir].cfg.nblocks = MAX_PARAM_SPATIAL_SUBFRAMES;
     166       18293 :             hQMetaData->q_direction[dir].cfg.search_effort = 3;
     167       18293 :             hQMetaData->q_direction[dir].cfg.start_band = 0;
     168       18293 :             hQMetaData->q_direction[dir].cfg.mc_ls_setup = MC_LS_SETUP_INVALID;
     169             :         }
     170             : 
     171       16432 :         if ( coherence_flag )
     172             :         {
     173        5788 :             if ( ( hQMetaData->surcoh_band_data = (IVAS_SURROUND_COHERENCE_BAND_DATA *) malloc( sizeof( IVAS_SURROUND_COHERENCE_BAND_DATA ) * hQMetaData->q_direction[0].cfg.nbands ) ) == NULL )
     174             :             {
     175           0 :                 return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for Q MetaData" );
     176             :             }
     177             :         }
     178             :         else
     179             :         {
     180       10644 :             hQMetaData->surcoh_band_data = NULL;
     181             :         }
     182             :     }
     183             : 
     184             : 
     185      199242 :     return IVAS_ERR_OK;
     186             : }
     187             : 
     188             : 
     189             : /*-----------------------------------------------------------------------*
     190             :  * ivas_qmetadata_free_memory()
     191             :  *
     192             :  * free dynamic part of Q Metadata memory
     193             :  *-----------------------------------------------------------------------*/
     194             : 
     195       19028 : static void ivas_qmetadata_free_memory(
     196             :     IVAS_QMETADATA_HANDLE hQMetaData /* i/o: q_metadata handle         */
     197             : )
     198             : {
     199             :     int16_t dir;
     200             : 
     201       19028 :     if ( hQMetaData == NULL )
     202             :     {
     203           0 :         return;
     204             :     }
     205             : 
     206       19028 :     if ( hQMetaData->q_direction != NULL )
     207             :     {
     208       34725 :         for ( dir = 0; dir < hQMetaData->no_directions; dir++ )
     209             :         {
     210       18293 :             if ( hQMetaData->q_direction[dir].band_data != NULL )
     211             :             {
     212       18293 :                 free( hQMetaData->q_direction[dir].band_data );
     213       18293 :                 hQMetaData->q_direction[dir].band_data = NULL;
     214             :             }
     215       18293 :             if ( hQMetaData->q_direction[dir].coherence_band_data != NULL )
     216             :             {
     217        7001 :                 free( hQMetaData->q_direction[dir].coherence_band_data );
     218        7001 :                 hQMetaData->q_direction[dir].coherence_band_data = NULL;
     219             :             }
     220             :         }
     221             : 
     222       16432 :         free( hQMetaData->q_direction );
     223       16432 :         hQMetaData->q_direction = NULL;
     224             :     }
     225             : 
     226       19028 :     if ( hQMetaData->surcoh_band_data != NULL )
     227             :     {
     228        5788 :         free( hQMetaData->surcoh_band_data );
     229        5788 :         hQMetaData->surcoh_band_data = NULL;
     230             :     }
     231             : 
     232       19028 :     return;
     233             : }
     234             : 
     235             : 
     236             : /*-----------------------------------------------------------------------*
     237             :  * ivas_qmetadata_close()
     238             :  *
     239             :  * close Q Metadata
     240             :  *-----------------------------------------------------------------------*/
     241             : 
     242        5112 : void ivas_qmetadata_close(
     243             :     IVAS_QMETADATA_HANDLE *hQMetaData /* i/o: q_metadata handle         */
     244             : )
     245             : {
     246        5112 :     if ( hQMetaData == NULL || *hQMetaData == NULL )
     247             :     {
     248        2516 :         return;
     249             :     }
     250             : 
     251        2596 :     ivas_qmetadata_free_memory( *hQMetaData );
     252             : 
     253        2596 :     free( *hQMetaData );
     254        2596 :     *hQMetaData = NULL;
     255             : 
     256        2596 :     return;
     257             : }
     258             : 
     259             : 
     260             : /*-------------------------------------------------------------------------
     261             :  * masa_sq()
     262             :  *
     263             :  * scalar quantization using partition
     264             :  *------------------------------------------------------------------------*/
     265             : 
     266             : /*! r: codeword index */
     267     6747597 : int16_t masa_sq(
     268             :     const float in,         /* i  : input value     */
     269             :     const float *threshold, /* i  : partition       */
     270             :     const int16_t cb_sz     /* i  : codebook size   */
     271             : )
     272             : {
     273             :     int16_t i;
     274             : 
     275    40352363 :     for ( i = 0; i < cb_sz; i++ )
     276             :     {
     277    40352363 :         if ( in < threshold[i + 1] )
     278             :         {
     279     6747597 :             return i;
     280             :         }
     281             :     }
     282             : 
     283           0 :     return -1;
     284             : }
     285             : 
     286             : 
     287             : /*-------------------------------------------------------------------------
     288             :  * only_reduce_bits_direction()
     289             :  *
     290             :  *
     291             :  *------------------------------------------------------------------------*/
     292             : 
     293       35416 : ivas_error only_reduce_bits_direction(
     294             :     int16_t *reduce_bits_out,
     295             :     IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure   */
     296             :     int16_t reduce_bits,
     297             :     const int16_t coding_subbands,
     298             :     const int16_t no_subframes,
     299             :     int16_t *ind_order )
     300             : {
     301             :     int16_t j, k, red_times, rem, n;
     302             :     int16_t max_nb, delta;
     303             :     int16_t *bits_dir0;
     304             : 
     305             :     int16_t bits_sph_idx_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES];
     306             :     float penalty[MASA_MAXIMUM_CODING_SUBBANDS];
     307      199428 :     for ( j = 0; j < coding_subbands; j++ )
     308             :     {
     309      616135 :         for ( k = 0; k < no_subframes; k++ )
     310             :         {
     311      452123 :             bits_sph_idx_orig[j][k] = q_direction->band_data[j].bits_sph_idx[k];
     312             :         }
     313             :     }
     314       35416 :     n = 0;
     315       35416 :     delta = 1;
     316             : 
     317       35416 :     if ( reduce_bits > 0 )
     318             :     {
     319       34022 :         red_times = reduce_bits / ( coding_subbands * no_subframes ); /* number of complete reductions by 1 bit */
     320       34022 :         if ( red_times > 0 )
     321             :         {
     322      155434 :             for ( j = 0; j < coding_subbands; j++ )
     323             :             {
     324      127775 :                 bits_dir0 = (int16_t *) q_direction->band_data[j].bits_sph_idx;
     325      527944 :                 for ( k = 0; k < no_subframes; k++ )
     326             :                 {
     327      400169 :                     bits_dir0[k] -= red_times;
     328      400169 :                     reduce_bits -= red_times;
     329             : 
     330      400169 :                     if ( bits_dir0[k] < MASA_MIN_BITS_TF )
     331             :                     {
     332       59728 :                         reduce_bits += ( MASA_MIN_BITS_TF - bits_dir0[k] );
     333       59728 :                         bits_dir0[k] = MASA_MIN_BITS_TF;
     334             :                     }
     335             :                 }
     336             :             }
     337             :         }
     338             : 
     339       34022 :         rem = reduce_bits; /* -coding_subbands*no_subframes*red_times; */
     340       75745 :         while ( n < rem )
     341             :         {
     342       41723 :             max_nb = 0;
     343             : #ifdef DEBUGGING
     344             :             if ( delta > MASA_MIN_BITS_TF )
     345             :             {
     346             :                 return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Not enough bits for MASA param." );
     347             :             }
     348             : #endif
     349      221875 :             for ( j = 0; j < coding_subbands; j++ )
     350             :             {
     351      180152 :                 bits_dir0 = (int16_t *) q_direction->band_data[j].bits_sph_idx;
     352      733225 :                 for ( k = 0; k < no_subframes; k++ )
     353             :                 {
     354      553073 :                     if ( ( n < rem ) && ( bits_dir0[k] > MASA_MIN_BITS_TF - delta ) )
     355             :                     {
     356      307579 :                         bits_dir0[k] -= 1;
     357      307579 :                         n++;
     358             :                     }
     359             : 
     360      553073 :                     if ( max_nb < bits_dir0[k] )
     361             :                     {
     362       92667 :                         max_nb = bits_dir0[k];
     363             :                     }
     364             :                 }
     365             :             }
     366             : 
     367       41723 :             if ( max_nb <= MASA_MIN_BITS_TF )
     368             :             {
     369        4105 :                 delta += 1;
     370             :             }
     371             :         }
     372             : 
     373       34022 :         reduce_bits = 0;
     374             :     }
     375             : 
     376       35416 :     if ( ind_order[0] == -1 )
     377             :     {
     378       50935 :         for ( j = 0; j < coding_subbands; j++ )
     379             :         {
     380       38042 :             ind_order[j] = j;
     381             :         }
     382             :     }
     383             :     else
     384             :     {
     385      148493 :         for ( j = 0; j < coding_subbands; j++ )
     386             :         {
     387      125970 :             penalty[j] = 0.0f;
     388      429747 :             for ( k = 0; k < no_subframes; k++ )
     389             :             {
     390      303777 :                 if ( bits_sph_idx_orig[j][k] > 0 )
     391             :                 {
     392      303777 :                     penalty[j] += ( bits_sph_idx_orig[j][k] - q_direction->band_data[j].bits_sph_idx[k] ) / (float) bits_sph_idx_orig[j][k];
     393             :                 }
     394             :             }
     395      125970 :             penalty[j] /= no_subframes;
     396             :         }
     397       22523 :         sort_desc_ind( penalty, coding_subbands, ind_order );
     398             :     }
     399             : 
     400       35416 :     *reduce_bits_out = -reduce_bits;
     401             : 
     402       35416 :     return IVAS_ERR_OK;
     403             : }
     404             : 
     405             : 
     406             : /*---------------------------------------------------------------
     407             :  * update_bits_next_block()
     408             :  *
     409             :  * Transfer the saved bits to the next subbands
     410             :  *---------------------------------------------------------------*/
     411             : 
     412      104683 : void update_bits_next_block(
     413             :     IVAS_QDIRECTION *q_direction, /* i/o: qdirection                    */
     414             :     int16_t *p_diff,              /* i/o: bits to be transferred        */
     415             :     const int16_t j,              /* i  : subband to update bit alloc to*/
     416             :     const int16_t max_i,          /* i  : number of subbands            */
     417             :     const int16_t max_k           /* i  : n umber of subframes          */
     418             : )
     419             : {
     420             :     int16_t diff;
     421             :     int16_t k;
     422      104683 :     diff = *p_diff;
     423      104683 :     if ( diff < 0 )
     424             :     {
     425             :         /* increase bits for next subbands */
     426       35533 :         k = 0;
     427      145436 :         while ( ( diff < 0 ) && ( j < max_i ) && ( k < max_k ) )
     428             :         {
     429      109903 :             if ( q_direction->band_data[j].bits_sph_idx[k] < MASA_DIRECTION_MAX_BITS )
     430             :             {
     431      109903 :                 q_direction->band_data[j].bits_sph_idx[k] += 1;
     432      109903 :                 diff++;
     433             :             }
     434      109903 :             k++;
     435             :         }
     436             :     }
     437             :     else
     438             :     {
     439       69150 :         k = 0;
     440      107689 :         while ( ( diff > 0 ) && ( k < max_k ) )
     441             :         {
     442       38539 :             if ( q_direction->band_data[j].bits_sph_idx[k] > 0 )
     443             :             {
     444       38539 :                 q_direction->band_data[j].bits_sph_idx[k] -= 1;
     445       38539 :                 diff--;
     446             :             }
     447             :         }
     448             :     }
     449      104683 :     *p_diff = diff;
     450             : 
     451      104683 :     return;
     452             : }
     453             : 
     454             : 
     455             : /*---------------------------------------------------------------
     456             :  * invdct4_transform()
     457             :  *
     458             :  * Inverse DCT transform for 4D vector
     459             :  *---------------------------------------------------------------*/
     460             : 
     461      587222 : void invdct4_transform(
     462             :     float *v,         /* i  : input vector                */
     463             :     uint8_t *invdct_v /* o  : inverse transformed vector  */
     464             : )
     465             : {
     466             :     float a, b, c, d;
     467             :     int16_t i;
     468             :     float f_invdct_v[4];
     469             : 
     470      587222 :     a = v[0] + v[2];
     471      587222 :     b = v[0] - v[2];
     472      587222 :     c = 1.306562964876376f * v[1] + 0.541196100146198f * v[3];
     473      587222 :     d = 0.541196100146198f * v[1] - 1.306562964876376f * v[3];
     474      587222 :     f_invdct_v[0] = 128 * ( a + c );
     475      587222 :     f_invdct_v[1] = 128 * ( b + d );
     476      587222 :     f_invdct_v[2] = 128 * ( b - d );
     477      587222 :     f_invdct_v[3] = 128 * ( a - c );
     478             : 
     479     2936110 :     for ( i = 0; i < 4; i++ )
     480             :     {
     481     2348888 :         if ( f_invdct_v[i] < 0.0 )
     482             :         {
     483      252591 :             invdct_v[i] = 0;
     484             :         }
     485             :         else
     486             :         {
     487     2096297 :             if ( f_invdct_v[i] > 255.0f )
     488             :             {
     489          25 :                 f_invdct_v[i] = 255.0f;
     490             :             }
     491     2096297 :             invdct_v[i] = (uint8_t) f_invdct_v[i];
     492             :         }
     493             :     }
     494             : 
     495      587222 :     return;
     496             : }
     497             : 
     498             : 
     499             : /*---------------------------------------------------------------
     500             :  * masa_compensate_two_dir_energy_ratio_index()
     501             :  *
     502             :  * Calculated compensated direct-to-total ratios for direction
     503             :  * quantization with two directions. This allows maintaining
     504             :  * direction accuracy while reusing one direction quantizers
     505             :  * separately for both directions.
     506             :  *--------------------------------------------------------------*/
     507             : 
     508      766217 : void masa_compensate_two_dir_energy_ratio_index(
     509             :     const int16_t ratio_index_1, /* i  : Input ratio for direction 1           */
     510             :     const int16_t ratio_index_2, /* i  : Input ratio for direction 2           */
     511             :     int16_t *ratio_index_mod1,   /* o  : Output modified ratio for direction 1 */
     512             :     int16_t *ratio_index_mod2,   /* o  : Output modified ratio for direction 2 */
     513             :     const int16_t hodirac_flag   /* i  : flag to indicate HO-DirAC mode        */
     514             : )
     515             : {
     516             :     float ratio1, ratio2;
     517             :     float ratioSum;
     518             : 
     519      766217 :     ratio1 = 1.0f - diffuseness_reconstructions[ratio_index_1];
     520      766217 :     ratio2 = 1.0f - diffuseness_reconstructions[ratio_index_2];
     521             : 
     522      766217 :     if ( !hodirac_flag )
     523             :     {
     524       52284 :         ratioSum = ratio1 + ratio2;
     525       52284 :         if ( ratio1 >= ratio2 )
     526             :         {
     527       52284 :             ratio2 = ratio2 / ratio1 * ratioSum;
     528       52284 :             ratio1 = ratioSum;
     529             :         }
     530             :         else
     531             :         {
     532           0 :             ratio1 = ratio1 / ratio2 * ratioSum;
     533           0 :             ratio2 = ratioSum;
     534             :         }
     535             :     }
     536             : 
     537      766217 :     *ratio_index_mod1 = masa_sq( 1.0f - ratio1, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS );
     538      766217 :     *ratio_index_mod2 = masa_sq( 1.0f - ratio2, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS );
     539             : 
     540             :     /* Limit maximum accuracy increase to conserve bits */
     541      766217 :     *ratio_index_mod1 = ( ratio_index_1 - *ratio_index_mod1 ) > MASA_DIR_RATIO_COMP_MAX_IDX_STEPS ? ratio_index_1 - MASA_DIR_RATIO_COMP_MAX_IDX_STEPS : *ratio_index_mod1;
     542      766217 :     *ratio_index_mod2 = ( ratio_index_2 - *ratio_index_mod2 ) > MASA_DIR_RATIO_COMP_MAX_IDX_STEPS ? ratio_index_2 - MASA_DIR_RATIO_COMP_MAX_IDX_STEPS : *ratio_index_mod2;
     543             : 
     544      766217 :     return;
     545             : }
     546             : 
     547             : 
     548             : /*---------------------------------------------------------------
     549             :  * set_qmetadata_maxbit_req()
     550             :  *
     551             :  * Sets proper value for qmetadata_max_bit_req limit
     552             :  *--------------------------------------------------------------*/
     553             : 
     554      199242 : void ivas_set_qmetadata_maxbit_req(
     555             :     IVAS_QMETADATA_HANDLE hQMetaData, /* o  : qmetadata structure where the requirement value is set */
     556             :     const IVAS_FORMAT ivas_format     /* i  : IVAS format                                            */
     557             : )
     558             : {
     559      199242 :     if ( ivas_format == SBA_FORMAT )
     560             :     {
     561       11851 :         hQMetaData->qmetadata_max_bit_req = QMETADATA_MAXBIT_REQ_SBA;
     562             :     }
     563             :     else /* MASA_FORMAT */
     564             :     {
     565      187391 :         hQMetaData->qmetadata_max_bit_req = QMETADATA_MAXBIT_REQ_MASA;
     566             :     }
     567             : 
     568      199242 :     return;
     569             : }
     570             : 
     571             : 
     572             : /*-------------------------------------------------------------------------
     573             :  * ivas_qmetadata_azimuth_elevation_to_direction_vector()
     574             :  *
     575             :  *
     576             :  *------------------------------------------------------------------------*/
     577             : 
     578     3269069 : void ivas_qmetadata_azimuth_elevation_to_direction_vector(
     579             :     const float az, /* i  : azimuth          */
     580             :     const float el, /* i  : elevation        */
     581             :     float *dv       /* o  : direction vector */
     582             : )
     583             : {
     584             :     float radius_length;
     585             : 
     586             : #ifdef DEBUGGING
     587             :     assert( fabsf( el ) <= 90.0f );
     588             :     /*assert((0.0f <= az) && (az <= 360.0f)); */
     589             : #endif
     590             : 
     591     3269069 :     dv[2] = sinf( el * PI_OVER_180 );
     592     3269069 :     radius_length = cosf( el * PI_OVER_180 );
     593     3269069 :     dv[0] = radius_length * cosf( az * PI_OVER_180 );
     594     3269069 :     dv[1] = radius_length * sinf( az * PI_OVER_180 );
     595             : 
     596     3269069 :     return;
     597             : }
     598             : 
     599             : /*-------------------------------------------------------------------------
     600             :  * ivas_qmetadata_direction_vector_to_azimuth_elevation()
     601             :  *
     602             :  * azimuth between [-180, 180]
     603             :  * elevation between [-90 and 90]
     604             :  *------------------------------------------------------------------------*/
     605             : 
     606     2729983 : void ivas_qmetadata_direction_vector_to_azimuth_elevation(
     607             :     const float *dv, /* i  : direction vector   */
     608             :     float *az,       /* o  : azimuth            */
     609             :     float *el        /* o  : elevation          */
     610             : )
     611             : {
     612             :     /* note: dv does not need to have unit L_2 norm, because the conversion is scale invariant */
     613             : 
     614     2729983 :     *el = atan2f( dv[2], sqrtf( dv[0] * dv[0] + dv[1] * dv[1] ) ) * _180_OVER_PI;
     615     2729983 :     *az = atan2f( dv[1], dv[0] ) * _180_OVER_PI;
     616             : 
     617     2729983 :     return;
     618             : }
     619             : 
     620             : 
     621             : /*-------------------------------------------------------------------------
     622             :  * ivas_get_df_ratio_bits_hodirac()
     623             :  *
     624             :  *
     625             :  *------------------------------------------------------------------------*/
     626             : 
     627             : /*! r: bits to be used for quantizing ratio of ratios */
     628      713933 : int16_t ivas_get_df_ratio_bits_hodirac(
     629             :     const int16_t index_diff /* i  : index of quantized diffuse-to-total ratio */
     630             : )
     631             : {
     632             :     int16_t dfRatio_bits;
     633             : 
     634      713933 :     if ( index_diff >= DIFF_DFRATIO_1BIT_LIMIT_IDX )
     635             :     {
     636      370497 :         dfRatio_bits = 1;
     637             :     }
     638      343436 :     else if ( index_diff >= DIFF_DFRATIO_2BIT_LIMIT_IDX_HODIRAC )
     639             :     {
     640      199325 :         dfRatio_bits = 2;
     641             :     }
     642             :     else
     643             :     {
     644      144111 :         dfRatio_bits = 3;
     645             :     }
     646             : 
     647      713933 :     return dfRatio_bits;
     648             : }
     649             : 
     650             : /*---------------------------------------------------------------
     651             :  * ivas_get_df_ratio_bits()
     652             :  *
     653             :  * Gives quantization accuracy for distribution factor of
     654             :  * direct-to-total ratios based on the diffuse-to-total ratio
     655             :  * index
     656             :  *--------------------------------------------------------------*/
     657             : 
     658             : /*! r: bits to be used for quantizing ratio of ratios */
     659       52284 : int16_t ivas_get_df_ratio_bits(
     660             :     const int16_t index_diff /* i  : index of quantized diffuse-to-total ratio */
     661             : )
     662             : {
     663             :     int16_t dfRatio_bits;
     664             : 
     665       52284 :     if ( index_diff >= DIFF_DFRATIO_1BIT_LIMIT_IDX )
     666             :     {
     667        1075 :         dfRatio_bits = 1;
     668             :     }
     669       51209 :     else if ( index_diff >= DIFF_DFRATIO_2BIT_LIMIT_IDX )
     670             :     {
     671       43821 :         dfRatio_bits = 2;
     672             :     }
     673             :     else
     674             :     {
     675        7388 :         dfRatio_bits = 3;
     676             :     }
     677             : 
     678       52284 :     return dfRatio_bits;
     679             : }

Generated by: LCOV version 1.14