LCOV - code coverage report
Current view: top level - lib_enc - ivas_qmetadata_enc.c (source / functions) Hit Total Coverage
Test: Coverage on main -- merged total coverage @ efe53129c9ed87a5067dd0a8fb9dca41db9c4add Lines: 2031 2163 93.9 %
Date: 2026-02-12 08:06:51 Functions: 53 53 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2026 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 "ivas_cnst.h"
      38             : #include "prot.h"
      39             : #include "ivas_prot.h"
      40             : #include "ivas_rom_com.h"
      41             : #include "ivas_stat_enc.h"
      42             : #include "wmc_auto.h"
      43             : #include "prot.h"
      44             : #include "basop_settings.h"
      45             : #if defined( DEBUGGING ) && defined( DBG_BITSTREAM_ANALYSIS )
      46             : #include <string.h>
      47             : #endif
      48             : 
      49             : 
      50             : /*-----------------------------------------------------------------------*
      51             :  * Local function prototypes
      52             :  *-----------------------------------------------------------------------*/
      53             : 
      54             : #ifdef DEBUG_MODE_QMETADATA
      55             : static float direction_distance( float elevation[DIRAC_MAX_NBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], float azimuth[DIRAC_MAX_NBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], IVAS_QDIRECTION *q_direction, const int16_t dim1, const int16_t dim2, float mat_dist[DIRAC_MAX_NBANDS][MAX_PARAM_SPATIAL_SUBFRAMES] );
      56             : 
      57             : #endif
      58             : static void ivas_qmetadata_quantize_diffuseness_nrg_ratios( IVAS_QMETADATA_HANDLE hQMetaData, int16_t *needed_bits, int16_t *nbits_diff, int16_t *dfRatioBits, const int16_t hodirac_flag );
      59             : 
      60             : static int16_t ivas_qmetadata_entropy_encode_diffuseness( BSTR_ENC_HANDLE hMetaData, IVAS_QDIRECTION *q_direction, uint16_t *diffuseness_index_max_ec_frame );
      61             : 
      62             : static void ivas_qmetadata_reorder_2dir_bands( IVAS_QMETADATA_HANDLE hQMetaData );
      63             : 
      64             : static int16_t ivas_qmetadata_entropy_encode_df_ratio( BSTR_ENC_HANDLE hMetaData, IVAS_QDIRECTION *q_direction, int16_t *df_ratio_bits );
      65             : 
      66             : static int16_t ivas_qmetadata_entropy_encode_dir( BSTR_ENC_HANDLE hMetaData, IVAS_QDIRECTION *q_direction, const uint16_t diffuseness_index_max_ec_frame, const int16_t nbands, const int16_t start_band, const int16_t direction_bits_raw, int16_t max_bits, const int16_t hrmasa_flag );
      67             : 
      68             : static int16_t ivas_qmetadata_raw_encode_dir( BSTR_ENC_HANDLE hMetaData, IVAS_QDIRECTION *q_direction, const int16_t nbands, const int16_t start_band );
      69             : 
      70             : int16_t ivas_qmetadata_encode_extended_gr_length( const uint16_t value, const uint16_t alphabet_size, const int16_t gr_param );
      71             : 
      72             : static int16_t ivas_qmetadata_get_optimal_gr_param( uint16_t *unsigned_data, const int16_t count, const int16_t gr_param_count, int16_t *opt_gr_size );
      73             : 
      74             : static int16_t ivas_qmetadata_encode_quasi_uniform_length( const uint16_t value, const uint16_t alphabet_size );
      75             : 
      76             : static void ivas_qmetadata_encode_quasi_uniform( BSTR_ENC_HANDLE hMetaData, const uint16_t value, const uint16_t alphabet_size );
      77             : 
      78             : static int16_t ivas_qmetadata_reorder_elevation_index( const int16_t elevation_index, const int16_t avg_elevation_index, const int16_t elevation_alphabet );
      79             : 
      80             : static int16_t ivas_qmetadata_reorder_azimuth_index( const int16_t azimuth_index, const int16_t avg_azimuth_index, const int16_t azimuth_alphabet );
      81             : 
      82             : static ivas_error requantize_direction_EC_3( int16_t *extra_bits, IVAS_QDIRECTION *q_direction, const int16_t coding_subbands, BSTR_ENC_HANDLE hMetaData, float elevation_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], float azimuth_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], int16_t *ind_order );
      83             : 
      84             : static void calculate_two_distances( float *el, int16_t *bits, const int16_t total_bits, const int16_t len, float *p_d1, float *p_d2 );
      85             : 
      86             : static void joint_encoding( IVAS_QDIRECTION *q_direction, const int16_t j, const int16_t next_j, const int16_t coding_subbands, int16_t *bits_dir0, const int16_t allowed_bits, BSTR_ENC_HANDLE hMetaData, int16_t *diff );
      87             : 
      88             : static ivas_error write_ec_direction( int16_t *num_bits_written, BSTR_ENC_HANDLE hMetaData, IVAS_QDIRECTION *q_direction, const int16_t j_idx, const int16_t len, const int16_t GR_ord_elevation, const int16_t GR_ord_azimuth, const int16_t use_context, const int16_t same );
      89             : 
      90             : static int16_t write_fixed_rate_direction( BSTR_ENC_HANDLE hMetaData, IVAS_QDIRECTION *q_direction, const int16_t j_idx, const int16_t len );
      91             : 
      92             : static int16_t ivas_qmetadata_quantize_coherence( IVAS_QMETADATA *hQMetaData, const int16_t idx_d, const int16_t all_coherence_zero, BSTR_ENC_HANDLE hMetaData, const int16_t write_flag, int16_t *indice_coherence, const int16_t hrmasa_flag );
      93             : 
      94             : static void dct4_transform( uint8_t *v, float *dct_v );
      95             : 
      96             : static float quantize_DCT_0_coh( const float x, const int16_t j, const float *coherence_cb, const float delta_var, const int16_t no_cb, IVAS_QDIRECTION *q_direction, uint16_t *idx_x, int16_t *p_no_cb, const int16_t hrmasa_flag );
      97             : 
      98             : static int16_t encode_coherence_indexesDCT0( uint16_t *idx_dct, const int16_t len, int16_t *no_cb_vec, BSTR_ENC_HANDLE hMetaData, const int16_t indice_coherence, const int16_t nbits, const int16_t nbits1 );
      99             : 
     100             : static int16_t encode_coherence_indexesDCT1( uint16_t *idx_dct, const int16_t len, BSTR_ENC_HANDLE hMetaData );
     101             : 
     102             : static uint64_t create_combined_index( uint16_t *idx_dct, const int16_t len, const int16_t *no_cb_vec );
     103             : 
     104             : static int16_t encode_surround_coherence( IVAS_QMETADATA *hQMetaData, BSTR_ENC_HANDLE hMetaData );
     105             : 
     106             : static int16_t write_fixed_rate_direction( BSTR_ENC_HANDLE hMetaData, IVAS_QDIRECTION *q_direction, const int16_t j_idx, const int16_t len );
     107             : 
     108             : static int16_t common_direction( IVAS_QDIRECTION *q_direction, const int16_t band_idx, const int16_t len, const int16_t bits_allowed, BSTR_ENC_HANDLE hMetaData, float *elevation_orig, float *azimuth_orig );
     109             : 
     110             : static int16_t ivas_diffuseness_huff_ec_encode( BSTR_ENC_HANDLE hMetaData, const uint16_t idx );
     111             : 
     112             : static void ivas_diffuseness_huff_ec_prepare( IVAS_QDIRECTION *q_direction, int16_t *best_av, uint16_t *avr_idx, int16_t *diffuseness_bits_huff );
     113             : 
     114             : static int16_t coherence_coding_length( const uint16_t *idx_sur_coh_shift, const uint8_t idx_shift_len, const int16_t coding_subbands, const int16_t *no_cv, uint16_t *mr_idx, int16_t *no_cv_shift, int16_t *p_min_idx, int16_t *GR_ord, int16_t *nbits_fr, int16_t *nbits_fr1 );
     115             : 
     116             : static int16_t write_2dir_info( BSTR_ENC_HANDLE hMetaData, uint8_t *twoDirBands, const int16_t n, const int16_t k );
     117             : 
     118             : static void transform_azimuth_dir2( IVAS_QMETADATA_HANDLE hQMetaData, int16_t *dir2_bands );
     119             : 
     120             : static int16_t calc_var_azi( const IVAS_QDIRECTION *q_direction, const int16_t diffuseness_index_max_ec_frame, const float avg_azimuth, float *avg_azimuth_out );
     121             : 
     122             : static void ivas_qmetadata_quantize_diffuseness_nrg_ratios_hr_512( IVAS_QMETADATA_HANDLE hQMetaData, int16_t *needed_bits, const int16_t bits_dir_hr, BSTR_ENC_HANDLE hMetaData );
     123             : 
     124             : static int16_t encode_surround_coherence_hr( IVAS_QMETADATA *hQMetaData, BSTR_ENC_HANDLE hMetaData );
     125             : 
     126             : static int16_t ivas_qmetadata_quantize_coherence_hr_512( IVAS_QMETADATA *hQMetaData, const int16_t idx_d, const int16_t all_coherence_zero, BSTR_ENC_HANDLE hMetaData, const int16_t bits_coh );
     127             : 
     128             : static int16_t write_stream_dct_coeffs_omasa( int16_t *q_idx, const int16_t len_stream, BSTR_ENC_HANDLE hMetaData, const int16_t first_line, const int16_t low_bitrate_mode );
     129             : 
     130             : static int16_t find_optimal_GR_order( const int16_t *q_idx, const int16_t len, int16_t *GR );
     131             : 
     132             : static int16_t find_optimal_GR_orders( const int16_t *q_idx, const int16_t len, const int16_t len_max_GR1, int16_t *GR1, int16_t *GR2, int16_t *i_min );
     133             : 
     134             : 
     135             : /*-----------------------------------------------------------------------*
     136             :  * ivas_qmetadata_enc_encode()
     137             :  *
     138             :  * Main function for quantizing and coding Spatial Metadata
     139             :  *-----------------------------------------------------------------------*/
     140             : 
     141     3945875 : ivas_error ivas_qmetadata_enc_encode(
     142             :     BSTR_ENC_HANDLE hMetaData,  /* i/o: metadata bitstream handle       */
     143             :     IVAS_QMETADATA *hQMetaData, /* i/o: metadata handle                 */
     144             :     const int16_t hodirac_flag  /* i  : flag to indicate HO-DirAC mode  */
     145             : )
     146             : {
     147             :     int16_t i, bit_pos_start, bit_pos_start_coh;
     148             :     int16_t next_ind_start;
     149             :     uint16_t diffuseness_index_max_ec_frame;
     150             :     uint16_t diffuseness_index_max_ec_frame_pre[QMETADATA_MAX_NO_DIRECTIONS];
     151             :     int16_t bits_dir_raw_pre[QMETADATA_MAX_NO_DIRECTIONS];
     152             :     int16_t bits_diff_sum;
     153             :     int16_t bits_diff[QMETADATA_MAX_NO_DIRECTIONS], bits_coherence[QMETADATA_MAX_NO_DIRECTIONS];
     154             :     int16_t bits_dir[QMETADATA_MAX_NO_DIRECTIONS], bits_dir_raw;
     155             :     int16_t extra_bits;
     156             :     IVAS_QDIRECTION *q_direction;
     157             :     int16_t nbands, nblocks, start_band;
     158             :     int16_t ndirections, d;
     159             :     float azimuth_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], elevation_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES];
     160             :     int16_t all_coherence_zero;
     161             :     int16_t bit_pos_0, total_bits_1dir, bits_no_dirs_coh;
     162             :     int16_t bits_signaling[QMETADATA_MAX_NO_DIRECTIONS];
     163             :     int16_t indice_coherence;
     164             :     int16_t bits_dir_bands[MASA_MAXIMUM_CODING_SUBBANDS], raw_flag[MASA_MAXIMUM_CODING_SUBBANDS];
     165             :     int16_t diff_bits, bits_ec, next_ind_raw_flag;
     166             :     int16_t dfRatio_bits[MASA_MAXIMUM_CODING_SUBBANDS];
     167             :     int16_t bits_surround_coh, no_TF;
     168             :     int16_t dir2_bands[MASA_MAXIMUM_TWO_DIR_BANDS];
     169             :     int16_t ind_order[MASA_MAXIMUM_CODING_SUBBANDS];
     170             :     int16_t reduce_bits;
     171             :     ivas_error error;
     172             : 
     173     3945875 :     error = IVAS_ERR_OK;
     174             : 
     175             : #ifdef DEBUG_MODE_QMETADATA
     176             :     int16_t ec_flag = 0;
     177             :     int16_t tmp;
     178             : 
     179             :     static FILE *pF = NULL;
     180             :     static FILE *pF_azi = NULL;
     181             :     static FILE *pF_ele = NULL;
     182             :     static FILE *pF_ratio = NULL;
     183             :     static FILE *pF_spcoh = NULL;
     184             :     static FILE *pF_spcoh_orig = NULL;
     185             :     static FILE *pF_surcoh = NULL;
     186             : 
     187             :     if ( pF == NULL )
     188             :         pF = fopen( "./res/qmetadata_enc.txt", "w" );
     189             :     if ( pF_azi == NULL )
     190             :         pF_azi = fopen( "./res/qmetadata_azi_enc.txt", "w" );
     191             :     if ( pF_ele == NULL )
     192             :         pF_ele = fopen( "./res/qmetadata_ele_enc.txt", "w" );
     193             :     if ( pF_ratio == NULL )
     194             :         pF_ratio = fopen( "./res/qmetadata_ratio_enc.txt", "w" );
     195             :     if ( pF_spcoh == NULL )
     196             :         pF_spcoh = fopen( "./res/qmetadata_spcoh_enc.txt", "w" );
     197             :     if ( pF_spcoh_orig == NULL )
     198             :         pF_spcoh_orig = fopen( "./res/qmetadata_spcoh_orig.txt", "w" );
     199             :     if ( pF_surcoh == NULL )
     200             :         pF_surcoh = fopen( "./res/qmetadata_surcoh_enc.txt", "w" );
     201             : #endif
     202             : 
     203             : 
     204             :     /* Save initial position in bitstream */
     205     3945875 :     bit_pos_0 = hMetaData->nb_bits_tot;
     206     3945875 :     bit_pos_start = bit_pos_0;
     207             : 
     208     3945875 :     ndirections = hQMetaData->no_directions;
     209     3945875 :     extra_bits = 0;
     210             : 
     211             :     /* Check if coherence should be encoded */
     212     3945875 :     all_coherence_zero = 1;
     213     3945875 :     bits_no_dirs_coh = 0;
     214             : 
     215     3945875 :     if ( hQMetaData->coherence_flag )
     216             :     {
     217      725285 :         all_coherence_zero = hQMetaData->all_coherence_zero;
     218             : 
     219      725285 :         push_next_indice( hMetaData, all_coherence_zero, 1 ); /* signal coherence */
     220      725285 :         bits_no_dirs_coh += 1;
     221             :     }
     222             : 
     223     3945875 :     if ( ndirections > 1 )
     224             :     {
     225             : #ifdef DEBUGGING
     226             :         assert( ndirections == 2 );
     227             : #endif
     228             :         /* Reorder 2dir bands for more efficient encoding. */
     229      373885 :         if ( !hodirac_flag )
     230             :         {
     231      185042 :             ivas_qmetadata_reorder_2dir_bands( hQMetaData );
     232             :         }
     233      373885 :         d = 0;
     234     4341507 :         for ( i = hQMetaData->q_direction[1].cfg.start_band; i < hQMetaData->q_direction[1].cfg.nbands; i++ )
     235             :         {
     236     3967622 :             if ( hQMetaData->twoDirBands[i] == 1 )
     237             :             {
     238     2709152 :                 mvr2r( hQMetaData->q_direction[1].band_data[i].azimuth, hQMetaData->q_direction[1].band_data[d].azimuth, hQMetaData->q_direction[1].cfg.nblocks );
     239     2709152 :                 mvr2r( hQMetaData->q_direction[1].band_data[i].elevation, hQMetaData->q_direction[1].band_data[d].elevation, hQMetaData->q_direction[1].cfg.nblocks );
     240     2709152 :                 mvr2r( hQMetaData->q_direction[1].band_data[i].energy_ratio, hQMetaData->q_direction[1].band_data[d].energy_ratio, hQMetaData->q_direction[1].cfg.nblocks );
     241             : 
     242     2709152 :                 dir2_bands[d] = i;
     243             : 
     244     2709152 :                 if ( hQMetaData->coherence_flag )
     245             :                 {
     246      631879 :                     mvc2c( hQMetaData->q_direction[1].coherence_band_data[i].spread_coherence, hQMetaData->q_direction[1].coherence_band_data[d].spread_coherence, hQMetaData->q_direction[1].cfg.nblocks );
     247             :                 }
     248     2709152 :                 d++;
     249             :             }
     250             :         }
     251             : 
     252      373885 :         bits_no_dirs_coh += write_2dir_info( hMetaData, hQMetaData->twoDirBands, hQMetaData->q_direction[0].cfg.nbands, hQMetaData->numTwoDirBands );
     253             : 
     254     1632355 :         for ( i = d; i < hQMetaData->q_direction[0].cfg.nbands; i++ )
     255             :         {
     256     1258470 :             set_f( hQMetaData->q_direction[1].band_data[i].energy_ratio, 0.0f, hQMetaData->q_direction[1].cfg.nblocks );
     257             :         }
     258             : #ifdef DEBUGGING
     259             :         assert( d == hQMetaData->numTwoDirBands );
     260             : #endif
     261             : 
     262      373885 :         hQMetaData->q_direction[1].cfg.nbands = hQMetaData->numTwoDirBands;
     263             :     }
     264             : 
     265             :     /*Quantization of the Diffuseness */
     266     3945875 :     ivas_qmetadata_quantize_diffuseness_nrg_ratios( hQMetaData, bits_dir_raw_pre, bits_diff, dfRatio_bits, hodirac_flag );
     267             : 
     268     3945875 :     bits_diff_sum = 0;
     269     3945875 :     bits_diff[0] = ivas_qmetadata_entropy_encode_diffuseness( hMetaData, &( hQMetaData->q_direction[0] ), &diffuseness_index_max_ec_frame_pre[0] );
     270     3945875 :     bits_diff_sum += bits_diff[0];
     271             : 
     272     3945875 :     if ( ndirections == 2 )
     273             :     {
     274      373885 :         bits_diff[1] = ivas_qmetadata_entropy_encode_df_ratio( hMetaData, &( hQMetaData->q_direction[1] ), dfRatio_bits );
     275      373885 :         bits_diff_sum += bits_diff[1];
     276             :     }
     277             : 
     278             :     /* 2dir energy ratio encoding reuses index memory. Now that diffRatio and dFRatio have been encoded,
     279             :      * we retrieve index_dirRatio1Inv and index_dirRatio1Inv for further parameter encoding. This is
     280             :      * necessary only for bands that have two concurrent directions. */
     281     3945875 :     if ( hQMetaData->no_directions == 2 )
     282             :     {
     283             :         int16_t j, k, dir2band, index_dirRatio1Inv, index_dirRatio2Inv;
     284             : 
     285      373885 :         dir2band = 0;
     286     4341507 :         for ( j = hQMetaData->q_direction[0].cfg.start_band; j < hQMetaData->q_direction[0].cfg.nbands; ++j )
     287             :         {
     288     3967622 :             if ( hQMetaData->twoDirBands[j] == 1 )
     289             :             {
     290     2709152 :                 index_dirRatio1Inv = masa_sq( 1.0f - hQMetaData->q_direction[0].band_data[j].energy_ratio[0], diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS );
     291     2709152 :                 index_dirRatio2Inv = masa_sq( 1.0f - hQMetaData->q_direction[1].band_data[dir2band].energy_ratio[0], diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS );
     292             : 
     293    12746041 :                 for ( k = 0; k < hQMetaData->q_direction[0].cfg.nblocks; k++ )
     294             :                 {
     295    10036889 :                     hQMetaData->q_direction[0].band_data[j].energy_ratio_index[k] = index_dirRatio1Inv;
     296             :                 }
     297             : 
     298    12746041 :                 for ( k = 0; k < hQMetaData->q_direction[1].cfg.nblocks; k++ )
     299             :                 {
     300    10036889 :                     hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[k] = index_dirRatio2Inv;
     301             :                 }
     302             : 
     303     2709152 :                 dir2band++;
     304             :             }
     305             :         }
     306             :     }
     307             : 
     308             :     /* Encode surround coherence */
     309     3945875 :     if ( ndirections == 2 )
     310             :     {
     311      373885 :         no_TF = hQMetaData->q_direction[0].cfg.nbands * hQMetaData->q_direction[0].cfg.nblocks + hQMetaData->q_direction[1].cfg.nbands * hQMetaData->q_direction[1].cfg.nblocks;
     312      373885 :         if ( ( all_coherence_zero == 0 ) && ( hQMetaData->metadata_max_bits - bits_no_dirs_coh - 4.3f * no_TF - sum_s( bits_diff, ndirections ) >= MASA_MIN_BITS_SURR_COH ) )
     313             :         {
     314      178333 :             bits_surround_coh = encode_surround_coherence( hQMetaData, hMetaData );
     315             :         }
     316             :         else
     317             :         {
     318      195552 :             bits_surround_coh = 0;
     319     2364368 :             for ( i = 0; i < hQMetaData->q_direction[0].cfg.nbands; i++ )
     320             :             {
     321     2168816 :                 if ( hQMetaData->surcoh_band_data != NULL )
     322             :                 {
     323       91543 :                     set_c( (int8_t *) hQMetaData->surcoh_band_data[i].surround_coherence, 0, hQMetaData->q_direction[0].cfg.nblocks );
     324             :                 }
     325             :             }
     326             :         }
     327      373885 :         bits_no_dirs_coh += bits_surround_coh;
     328      373885 :         total_bits_1dir = ( ( hQMetaData->metadata_max_bits - bits_no_dirs_coh ) * hQMetaData->q_direction[0].cfg.nbands * hQMetaData->q_direction[0].cfg.nblocks ) / no_TF;
     329             :     }
     330             :     else
     331             :     {
     332     3571990 :         no_TF = hQMetaData->q_direction[0].cfg.nbands * hQMetaData->q_direction[0].cfg.nblocks;
     333     3571990 :         if ( ( all_coherence_zero == 0 ) && ( hQMetaData->metadata_max_bits - bits_no_dirs_coh - 4.3f * no_TF - bits_diff[0] >= MASA_MIN_BITS_SURR_COH ) )
     334             :         {
     335      472729 :             bits_surround_coh = encode_surround_coherence( hQMetaData, hMetaData );
     336             :         }
     337             :         else
     338             :         {
     339     3099261 :             bits_surround_coh = 0;
     340    13741568 :             for ( i = 0; i < hQMetaData->q_direction[0].cfg.nbands; i++ )
     341             :             {
     342    10642307 :                 if ( hQMetaData->surcoh_band_data != NULL )
     343             :                 {
     344      763698 :                     set_c( (int8_t *) hQMetaData->surcoh_band_data[i].surround_coherence, 0, hQMetaData->q_direction[0].cfg.nblocks );
     345             :                 }
     346             :             }
     347             :         }
     348     3571990 :         total_bits_1dir = hQMetaData->metadata_max_bits - bits_no_dirs_coh - bits_surround_coh;
     349             :     }
     350             : 
     351             :     /* Loop over number of directions*/
     352     8265635 :     for ( d = 0; d < ndirections; d++ )
     353             :     {
     354     4319760 :         q_direction = &( hQMetaData->q_direction[d] );
     355             : 
     356     4319760 :         if ( d == 1 )
     357             :         {
     358      373885 :             transform_azimuth_dir2( hQMetaData, dir2_bands );
     359             :         }
     360             : 
     361     4319760 :         nbands = q_direction->cfg.nbands;
     362     4319760 :         nblocks = q_direction->cfg.nblocks;
     363     4319760 :         start_band = q_direction->cfg.start_band;
     364     4319760 :         diffuseness_index_max_ec_frame = diffuseness_index_max_ec_frame_pre[0];
     365     4319760 :         bits_dir_raw = bits_dir_raw_pre[d];
     366             : 
     367             :         /* This sets bit budget correctly for the second direction */
     368     4319760 :         if ( d == 0 )
     369             :         {
     370     3945875 :             bits_diff[d] = bits_diff_sum;
     371             :         }
     372             :         else
     373             :         {
     374      373885 :             bits_diff[d] = 0;
     375             :         }
     376             : 
     377             : #ifdef DEBUG_MODE_QMETADATA
     378             :         {
     379             :             int16_t j, k;
     380             :             k = 0;
     381             :             fprintf( pF_spcoh_orig, "%d  %d ", frame, k );
     382             : 
     383             :             for ( i = start_band; i < nbands; i++ )
     384             :             {
     385             :                 for ( j = 0; j < nblocks; j++ )
     386             :                 {
     387             :                     if ( q_direction->coherence_band_data != NULL )
     388             :                     {
     389             :                         fprintf( pF_spcoh_orig, " %d ", q_direction->coherence_band_data[i].spread_coherence[j] );
     390             :                     }
     391             :                 }
     392             :             }
     393             :             fprintf( pF_spcoh_orig, "\n" );
     394             :         }
     395             : #endif
     396             : 
     397     4319760 :         bits_signaling[d] = 0;
     398             : 
     399             :         /*Coherence */
     400     4319760 :         bits_coherence[d] = 0;
     401     4319760 :         bit_pos_start_coh = hMetaData->nb_bits_tot;
     402             : 
     403     4319760 :         if ( all_coherence_zero == 0 )
     404             :         {
     405      840979 :             bits_coherence[d] = ivas_qmetadata_quantize_coherence( hQMetaData, d, all_coherence_zero, hMetaData, 0, &indice_coherence, 0 );
     406             :         }
     407             : 
     408     4319760 :         if ( q_direction->cfg.mc_ls_setup == MC_LS_SETUP_5_1 || q_direction->cfg.mc_ls_setup == MC_LS_SETUP_7_1 )
     409             :         {
     410      104326 :             q_direction->not_in_2D = 0;
     411             :             /* Quantize directions*/
     412      104326 :             quantize_direction_frame2D( q_direction, azimuth_orig, elevation_orig );
     413             :         }
     414             :         else
     415             :         {
     416             :             /* Quantize directions*/
     417     4215434 :             quantize_direction_frame( q_direction, azimuth_orig, elevation_orig, 0 );
     418             :         }
     419             : 
     420             :         /* Signalling 2D*/
     421     4319760 :         push_next_indice( hMetaData, ( q_direction->not_in_2D > 0 ), 1 ); /*2D flag*/
     422     4319760 :         bits_signaling[d] = 1;
     423             : 
     424             :         /* Save state of metadata bitstream buffer after writing energy ratios, number of dirs and save space for coherence*/
     425     4319760 :         bit_pos_start = hMetaData->nb_bits_tot;
     426     4319760 :         next_ind_start = hMetaData->nb_ind_tot;
     427             : 
     428             :         /* Encode quantized directions with EC frame-wise*/
     429     4319760 :         if ( total_bits_1dir + bits_surround_coh <= hQMetaData->qmetadata_max_bit_req )
     430             :         {
     431     3286662 :             push_next_indice( hMetaData, 0, 1 ); /*Write 1 bit to signal EC frame-wise (EC1)*/
     432     3286662 :             bits_signaling[d]++;
     433             :         }
     434             : 
     435     4319760 :         next_ind_raw_flag = hMetaData->nb_ind_tot;
     436     4319760 :         push_next_indice( hMetaData, 0, 1 ); /* Raw coding flag*/
     437             : 
     438     4319760 :         bits_dir_bands[0] = ivas_qmetadata_raw_encode_dir( NULL, q_direction, q_direction->cfg.nbands, q_direction->cfg.start_band );
     439             : 
     440     4319760 :         reduce_bits = hQMetaData->is_masa_ivas_format ? ( total_bits_1dir - ( bits_diff[d] + bits_coherence[d] + bits_signaling[d] ) - 1 ) : MASA_MAX_BITS;
     441     4319760 :         bits_ec = ivas_qmetadata_entropy_encode_dir( hMetaData, q_direction, diffuseness_index_max_ec_frame, q_direction->cfg.nbands, q_direction->cfg.start_band, bits_dir_bands[0], reduce_bits, 0 );
     442             : 
     443     4319760 :         if ( bits_ec < 0 )
     444             :         {
     445     1720544 :             hMetaData->ind_list[next_ind_raw_flag].value = 1; /*rewrite flag*/
     446     1720544 :             bits_ec = ivas_qmetadata_raw_encode_dir( hMetaData, q_direction, q_direction->cfg.nbands, q_direction->cfg.start_band );
     447             : #ifdef DEBUGGING
     448             :             assert( bits_dir_bands[0] == bits_ec );
     449             : #endif
     450             :         }
     451     4319760 :         bits_dir[d] = bits_ec + 1;
     452             : #ifdef DEBUG_MODE_QMETADATA
     453             :         tmp = bits_dir[d] - ( total_bits_1dir - ( bits_diff[d] + bits_coherence[d] + bits_signaling[d] ) );
     454             : #endif
     455     4319760 :         extra_bits = hQMetaData->metadata_max_bits - ( hMetaData->nb_bits_tot - bit_pos_0 );
     456             : #ifdef DEBUGGING
     457             :         assert( bit_pos_start + bits_signaling[d] - 1 + bits_dir[d] == hMetaData->nb_bits_tot );
     458             : #endif
     459             : #ifdef DEBUG_MODE_QMETADATA
     460             :         ec_flag = 0;
     461             : #endif
     462             : 
     463             :         /* Encode quantized directions with EC band-wise */
     464     4319760 :         if ( ( total_bits_1dir + bits_surround_coh <= hQMetaData->qmetadata_max_bit_req ) && ( bits_dir[d] + bits_diff[d] + bits_coherence[d] + bits_signaling[d] > total_bits_1dir ) && q_direction->cfg.nblocks > 1 )
     465             :         {
     466      136957 :             restore_metadata_buffer( hMetaData, next_ind_start, bit_pos_start );
     467             : 
     468             :             /* Write signaling */
     469      136957 :             push_next_indice( hMetaData, 1, 1 ); /*Write 1 bit to signal no EC frame-wise (EC1)*/
     470      136957 :             push_next_indice( hMetaData, 0, 1 ); /*Write 1 bit to signal EC band-wise (EC2)*/
     471      136957 :             bits_signaling[d] = 3;
     472             : 
     473             :             /* Write raw flags */
     474      136957 :             next_ind_raw_flag = hMetaData->nb_ind_tot;
     475      814475 :             for ( i = start_band; i < nbands; i++ )
     476             :             {
     477      677518 :                 push_next_indice( hMetaData, 0, 1 ); /* Raw coding flag*/
     478             :             }
     479             : 
     480      136957 :             bits_dir[d] = 0;
     481      136957 :             diff_bits = bits_diff[d] + bits_coherence[d] + bits_signaling[d] - total_bits_1dir;
     482      814475 :             for ( i = start_band; i < nbands; i++ )
     483             :             {
     484      677518 :                 bits_dir_bands[i] = ivas_qmetadata_raw_encode_dir( NULL, q_direction, i + 1, i );
     485             : 
     486             :                 /* Write ec bits */
     487      677518 :                 bits_ec = ivas_qmetadata_entropy_encode_dir( hMetaData, q_direction, diffuseness_index_max_ec_frame, i + 1, i, bits_dir_bands[i], MASA_MAX_BITS, 0 );
     488             : 
     489      677518 :                 if ( bits_ec >= 0 )
     490             :                 {
     491      356537 :                     bits_dir_bands[i] = bits_ec;
     492      356537 :                     raw_flag[i] = 0;
     493             :                 }
     494             :                 else
     495             :                 {
     496      320981 :                     raw_flag[i] = 1;
     497             :                 }
     498      677518 :                 diff_bits += bits_dir_bands[i] + 1;
     499             :             }
     500             : 
     501      136957 :             small_requantize_direction_frame( q_direction, azimuth_orig, elevation_orig, raw_flag, bits_dir_bands, &diff_bits );
     502             : 
     503      814475 :             for ( i = start_band; i < nbands; i++ )
     504             :             {
     505      677518 :                 if ( raw_flag[i] )
     506             :                 {
     507             :                     /* Rewrite raw flag value */
     508      320981 :                     hMetaData->ind_list[next_ind_raw_flag + i - start_band].value = 1;
     509             : 
     510             :                     /* Write ec bits */
     511      320981 :                     bits_ec = ivas_qmetadata_raw_encode_dir( hMetaData, q_direction, i + 1, i );
     512             : #ifdef DEBUGGING
     513             :                     assert( bits_dir_bands[i] == bits_ec );
     514             : #endif
     515             :                 }
     516      677518 :                 bits_dir[d] += bits_dir_bands[i] + 1;
     517             :             }
     518             : 
     519      136957 :             extra_bits = hQMetaData->metadata_max_bits - ( hMetaData->nb_bits_tot - bit_pos_0 );
     520             : 
     521             : #ifdef DEBUGGING
     522             :             if ( ( diff_bits <= 0 ) && ( bits_dir[d] + bits_diff[d] + bits_coherence[d] + bits_signaling[d] > total_bits_1dir ) )
     523             :             {
     524             :                 return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "not possible!!" );
     525             :             }
     526             : #endif
     527             : 
     528             : #ifdef DEBUGGING
     529             :             assert( bit_pos_start + bits_signaling[d] - 1 + bits_dir[d] == hMetaData->nb_bits_tot );
     530             : #endif
     531             : #ifdef DEBUG_MODE_QMETADATA
     532             :             ec_flag = 1;
     533             : #endif
     534             :         }
     535             : 
     536             :         /* Requantized directions */
     537     4319760 :         if ( ( total_bits_1dir + bits_surround_coh <= hQMetaData->qmetadata_max_bit_req ) && ( bits_dir[d] + bits_diff[d] + bits_coherence[d] + bits_signaling[d] > total_bits_1dir ) )
     538             :         {
     539             : 
     540             :             /*Bit budget exceeded, bit reduction strategy?*/
     541      179474 :             extra_bits = 0;
     542             : 
     543      179474 :             restore_metadata_buffer( hMetaData, next_ind_start, bit_pos_start );
     544             : 
     545      179474 :             push_next_indice( hMetaData, 1, 1 ); /*Write 1 bit to signal no EC frame-wise (EC1)*/
     546      179474 :             if ( nblocks > 1 )
     547             :             {
     548       98629 :                 push_next_indice( hMetaData, 1, 1 ); /*Write 1 bit to signal requantization stage (EC3)*/
     549       98629 :                 bits_signaling[d] = 3;
     550             :             }
     551             :             else
     552             :             {
     553       80845 :                 bits_signaling[d] = 2;
     554             :             }
     555             : 
     556      179474 :             if ( hQMetaData->is_masa_ivas_format == 0 )
     557             :             {
     558       41274 :                 reduce_bits = bits_dir_raw - ( total_bits_1dir - bits_diff[d] - bits_coherence[d] - bits_signaling[d] );
     559       41274 :                 ind_order[0] = -1;
     560             :             }
     561             :             else
     562             :             {
     563      138200 :                 ind_order[0] = 0;
     564      138200 :                 reduce_bits = min( nbands * nblocks + MASA_BIT_REDUCT_PARAM, bits_dir_raw - ( total_bits_1dir - bits_diff[d] - bits_coherence[d] - bits_signaling[d] ) );
     565             : 
     566      138200 :                 if ( reduce_bits > bits_dir_raw - nbands * nblocks )
     567             :                 {
     568         326 :                     reduce_bits = bits_dir_raw - nbands * nblocks;
     569             :                 }
     570             :             }
     571             : 
     572      179474 :             only_reduce_bits_direction( &extra_bits, q_direction, reduce_bits, nbands, nblocks, ind_order );
     573      179474 :             bits_dir[d] = hMetaData->nb_bits_tot;
     574      179474 :             requantize_direction_EC_3( &extra_bits, q_direction, nbands, hMetaData, elevation_orig, azimuth_orig, ind_order );
     575      179474 :             bits_dir[d] = hMetaData->nb_bits_tot - bits_dir[d];
     576             : #ifdef DEBUG_MODE_QMETADATA
     577             :             ec_flag = 2;
     578             : #endif
     579             :         }
     580             : 
     581             :         /* finalize writing coherence */
     582     4319760 :         if ( ( bits_coherence[d] > 0 ) && ( all_coherence_zero == 0 ) && ( nblocks > 1 ) )
     583             :         {
     584      577703 :             bit_pos_start = hMetaData->nb_bits_tot;
     585      577703 :             hMetaData->nb_bits_tot = bit_pos_start_coh;
     586      577703 :             ivas_qmetadata_quantize_coherence( hQMetaData, d, all_coherence_zero, hMetaData, 1, &indice_coherence, 0 );
     587      577703 :             hMetaData->nb_bits_tot = bit_pos_start;
     588             :         }
     589             : 
     590     4319760 :         if ( d == 0 )
     591             :         {
     592     3945875 :             total_bits_1dir = hQMetaData->metadata_max_bits - ( hMetaData->nb_bits_tot - bit_pos_0 );
     593             :         }
     594             : #ifdef DEBUG_MODE_QMETADATA
     595             :         {
     596             :             int16_t j;
     597             :             float tmp_f, mat_dist[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES];
     598             : 
     599             :             fprintf( pF, "frame %d: diff %d coh %d surcoh %d ", frame, bits_diff[d], bits_coherence[d], bits_surround_coh );
     600             :             fprintf( pF, "dir %d %d,%d,%d %d %5.3f\n", ec_flag, hMetaData->nb_bits_tot - bit_pos_0, total_bits_1dir, bits_dir_raw, tmp, direction_distance( elevation_orig, azimuth_orig, q_direction, nbands, nblocks, mat_dist ) );
     601             :             fprintf( pF_azi, "frame %d/dir/ec %d/%d: ", frame, d, ec_flag );
     602             :             fprintf( pF_ele, "frame %d/dir/ec %d/%d: ", frame, d, ec_flag );
     603             :             fprintf( pF_ratio, "frame %d/dir %d: ", frame, d );
     604             :             /*fprintf( pF_spcoh, "frame %d/dir %d: ", frame, d ); */
     605             :             fprintf( pF_spcoh, " %d  %d ", frame, d );
     606             :             if ( d == 0 )
     607             :             {
     608             :                 fprintf( pF_surcoh, "frame %d/dir %d: ", frame, d );
     609             :             }
     610             : 
     611             :             /* direction_distance( elevation_orig, azimuth_orig, q_direction,  nbands, nblocks, mat_dist );*/
     612             :             for ( i = start_band; i < nbands; i++ )
     613             :             {
     614             :                 for ( j = 0; j < nblocks; j++ )
     615             :                 {
     616             :                     fprintf( pF_azi, " %+5.2f ", (int16_t) ( 100.f * q_direction->band_data[i].azimuth[j] ) / 100.f );
     617             :                     fprintf( pF_ele, " %+5.2f ", (int16_t) ( 100.f * q_direction->band_data[i].elevation[j] ) / 100.f );
     618             :                     fprintf( pF_ratio, " %1.3f ", q_direction->band_data[i].energy_ratio[j] );
     619             :                     if ( q_direction->coherence_band_data != NULL )
     620             :                     {
     621             :                         fprintf( pF_spcoh, " %d ", q_direction->coherence_band_data[i].spread_coherence[j] );
     622             :                     }
     623             :                     if ( d == 0 && hQMetaData->surcoh_band_data != NULL )
     624             :                     {
     625             :                         fprintf( pF_surcoh, " %d ", hQMetaData->surcoh_band_data[i].surround_coherence[0] );
     626             :                     }
     627             :                 }
     628             :             }
     629             :             fprintf( pF_azi, "\n" );
     630             :             fprintf( pF_ele, "\n" );
     631             :             fprintf( pF_ratio, "\n" );
     632             :             fprintf( pF_spcoh, "\n" );
     633             :             if ( d == 0 )
     634             :             {
     635             :                 fprintf( pF_surcoh, "\n" );
     636             :             }
     637             : 
     638             :             for ( i = 0; i < nblocks; i++ )
     639             :             {
     640             :                 for ( j = 0; j < nbands; j++ )
     641             :                 {
     642             :                     dbgwrite( &( q_direction->band_data[j].azimuth[i] ), sizeof( float ), 1, 1, "./res/IVAS_QMETADATA_azi.bin" );
     643             :                     dbgwrite( &( q_direction->band_data[j].elevation[i] ), sizeof( float ), 1, 1, "./res/IVAS_QMETADATA_ele.bin" );
     644             :                     dbgwrite( &( mat_dist[j][i] ), sizeof( float ), 1, 1, "./res/IVAS_QMETADATA_dist.bin" );
     645             :                     dbgwrite( &( q_direction->band_data[j].energy_ratio_index[i] ), sizeof( uint16_t ), 1, 1, "./res/IVAS_QMETADATA_diffuseness_index.bin" );
     646             :                     tmp_f = 1.f - q_direction->band_data[j].energy_ratio[i];
     647             :                     dbgwrite( &tmp_f, sizeof( float ), 1, 1, "./res/IVAS_QMETADATA_diffuseness.bin" );
     648             :                 }
     649             :             }
     650             : 
     651             :             j = (int16_t) ( hMetaData->nb_bits_tot );
     652             :             dbgwrite( &j, sizeof( int16_t ), 1, 1, "./res/IVAS_QMETADATA_bits.bin" );
     653             :         }
     654             : #endif
     655             : 
     656             :         /* Save quantized DOAs */
     657    25998488 :         for ( i = start_band; i < nbands; i++ )
     658             :         {
     659    21678728 :             mvr2r( q_direction->band_data[i].azimuth, q_direction->band_data[i].q_azimuth, nblocks );
     660    21678728 :             mvr2r( q_direction->band_data[i].elevation, q_direction->band_data[i].q_elevation, nblocks );
     661             :         }
     662             : 
     663             :         /* Copy original DOAs back to q_direction*/
     664    25998488 :         for ( i = start_band; i < nbands; i++ )
     665             :         {
     666    21678728 :             mvr2r( azimuth_orig[i], q_direction->band_data[i].azimuth, nblocks );
     667    21678728 :             mvr2r( elevation_orig[i], q_direction->band_data[i].elevation, nblocks );
     668             :         }
     669             :     }
     670             : 
     671     3945875 :     return error;
     672             : }
     673             : 
     674             : 
     675             : /*-----------------------------------------------------------------------*
     676             :  * ivas_qmetadata_enc_encode_hr_384_512()
     677             :  *
     678             :  * Main function for quantizing and coding Spatial Metadata at HRs
     679             :  *-----------------------------------------------------------------------*/
     680             : 
     681       74940 : ivas_error ivas_qmetadata_enc_encode_hr_384_512(
     682             :     BSTR_ENC_HANDLE hMetaData,  /* i/o: metadata bitstream handle */
     683             :     IVAS_QMETADATA *hQMetaData, /* i/o: metadata handle           */
     684             :     const int16_t bits_sph_idx,
     685             :     const int16_t bits_sp_coh )
     686             : {
     687             :     int16_t i, j;
     688             :     int16_t bits_diff[QMETADATA_MAX_NO_DIRECTIONS];
     689             :     IVAS_QDIRECTION *q_direction;
     690             :     int16_t nbands, nblocks, start_band;
     691             :     int16_t ndirections, d;
     692             :     int16_t all_coherence_zero;
     693             : #ifdef DEBUG_MODE_QMETADATA
     694             :     int16_t bits_no_dirs_coh;
     695             : #endif
     696             :     int16_t bits_ec;
     697             :     float azimuth_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], elevation_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES];
     698             :     ivas_error error;
     699             : 
     700       74940 :     error = IVAS_ERR_OK;
     701             : 
     702             : #ifdef DEBUG_MODE_QMETADATA
     703             : 
     704             :     static FILE *pF = NULL;
     705             :     static FILE *pF_azi = NULL;
     706             :     static FILE *pF_ele = NULL;
     707             :     static FILE *pF_ratio = NULL;
     708             :     static FILE *pF_spcoh = NULL;
     709             :     static FILE *pF_spcoh_orig = NULL;
     710             :     static FILE *pF_surcoh = NULL;
     711             : 
     712             :     if ( pF == NULL )
     713             :         pF = fopen( "./res/qmetadata_enc.txt", "w" );
     714             :     if ( pF_azi == NULL )
     715             :         pF_azi = fopen( "./res/qmetadata_azi_enc.txt", "w" );
     716             :     if ( pF_ele == NULL )
     717             :         pF_ele = fopen( "./res/qmetadata_ele_enc.txt", "w" );
     718             :     if ( pF_ratio == NULL )
     719             :         pF_ratio = fopen( "./res/qmetadata_ratio_enc.txt", "w" );
     720             :     if ( pF_spcoh == NULL )
     721             :         pF_spcoh = fopen( "./res/qmetadata_spcoh_enc.txt", "w" );
     722             :     if ( pF_spcoh_orig == NULL )
     723             :         pF_spcoh_orig = fopen( "./res/qmetadata_spcoh_orig.txt", "w" );
     724             :     if ( pF_surcoh == NULL )
     725             :         pF_surcoh = fopen( "./res/qmetadata_surcoh_enc.txt", "w" );
     726             : #endif
     727             : 
     728       74940 :     ndirections = hQMetaData->no_directions;
     729             : 
     730             :     /* Check if coherence should be encoded */
     731       74940 :     all_coherence_zero = 1;
     732             : #ifdef DEBUG_MODE_QMETADATA
     733             :     bits_no_dirs_coh = 0;
     734             : #endif
     735       74940 :     if ( hQMetaData->q_direction->cfg.inactiveBands > 0 )
     736             :     {
     737       15616 :         push_next_indice( hMetaData, 1, 1 );
     738             :         /* write the number of inactive higher bands */
     739       15616 :         ivas_qmetadata_encode_extended_gr( hMetaData, hQMetaData->q_direction->cfg.inactiveBands - 1, MASA_MAXIMUM_CODING_SUBBANDS, 1 );
     740             :     }
     741             :     else
     742             :     {
     743             :         /* no change */
     744       59324 :         push_next_indice( hMetaData, 0, 1 );
     745             :     }
     746       74940 :     if ( hQMetaData->coherence_flag )
     747             :     {
     748       74940 :         all_coherence_zero = hQMetaData->all_coherence_zero;
     749       74940 :         push_next_indice( hMetaData, all_coherence_zero, 1 ); /* signal coherence */
     750             : #ifdef DEBUG_MODE_QMETADATA
     751             :         bits_no_dirs_coh += 1;
     752             : #endif
     753             :     }
     754             : 
     755             :     /* encode 2 direction subbands position */
     756       74940 :     if ( ndirections == 2 && bits_sph_idx == 11 )
     757             :     {
     758             : #ifdef DEBUG_MODE_QMETADATA
     759             :         bits_no_dirs_coh +=
     760             : #endif
     761       13888 :             write_2dir_info( hMetaData, hQMetaData->twoDirBands, hQMetaData->q_direction[0].cfg.nbands, hQMetaData->numTwoDirBands );
     762       13888 :         d = 0;
     763      314642 :         for ( i = hQMetaData->q_direction[1].cfg.start_band; i < hQMetaData->q_direction[1].cfg.nbands; i++ )
     764             :         {
     765      300754 :             if ( hQMetaData->twoDirBands[i] == 1 )
     766             :             {
     767      132454 :                 mvr2r( hQMetaData->q_direction[1].band_data[i].azimuth, hQMetaData->q_direction[1].band_data[d].azimuth, hQMetaData->q_direction[1].cfg.nblocks );
     768      132454 :                 mvr2r( hQMetaData->q_direction[1].band_data[i].elevation, hQMetaData->q_direction[1].band_data[d].elevation, hQMetaData->q_direction[1].cfg.nblocks );
     769      132454 :                 mvr2r( hQMetaData->q_direction[1].band_data[i].energy_ratio, hQMetaData->q_direction[1].band_data[d].energy_ratio, hQMetaData->q_direction[1].cfg.nblocks );
     770             : 
     771      132454 :                 if ( hQMetaData->coherence_flag )
     772             :                 {
     773      132454 :                     mvc2c( hQMetaData->q_direction[1].coherence_band_data[i].spread_coherence, hQMetaData->q_direction[1].coherence_band_data[d].spread_coherence, hQMetaData->q_direction[1].cfg.nblocks );
     774             :                 }
     775      132454 :                 d++;
     776             :             }
     777             :         }
     778      182188 :         for ( i = hQMetaData->numTwoDirBands; i < hQMetaData->q_direction[0].cfg.nbands; i++ )
     779             :         {
     780      168300 :             set_f( hQMetaData->q_direction[1].band_data[i].energy_ratio, 0.0f, hQMetaData->q_direction[1].cfg.nblocks );
     781             :         }
     782             : 
     783       13888 :         hQMetaData->q_direction[1].cfg.nbands = hQMetaData->numTwoDirBands;
     784             :     }
     785             : 
     786             :     /*Quantization and encoding of the Diffuseness */
     787       74940 :     ivas_qmetadata_quantize_diffuseness_nrg_ratios_hr_512( hQMetaData, bits_diff, bits_sph_idx, hMetaData );
     788             : 
     789             :     /* Encode surround coherence */
     790       74940 :     if ( all_coherence_zero == 0 )
     791             :     {
     792       64390 :         encode_surround_coherence_hr( hQMetaData, hMetaData );
     793             :     }
     794             :     else
     795             :     {
     796      238729 :         for ( i = 0; i < hQMetaData->q_direction[0].cfg.nbands; i++ )
     797             :         {
     798      228179 :             if ( hQMetaData->surcoh_band_data != NULL )
     799             :             {
     800      228179 :                 set_c( (int8_t *) hQMetaData->surcoh_band_data[i].surround_coherence, 0, hQMetaData->q_direction[0].cfg.nblocks );
     801             :             }
     802             :         }
     803             :     }
     804             : 
     805             :     /* Loop over number of directions*/
     806      171712 :     for ( d = 0; d < ndirections; d++ )
     807             :     {
     808       96772 :         q_direction = &( hQMetaData->q_direction[d] );
     809             : 
     810       96772 :         nbands = q_direction->cfg.nbands;
     811       96772 :         nblocks = q_direction->cfg.nblocks;
     812       96772 :         start_band = q_direction->cfg.start_band;
     813             : 
     814             : #ifdef DEBUG_MODE_QMETADATA
     815             :         {
     816             :             int16_t k;
     817             :             k = 0;
     818             :             fprintf( pF_spcoh_orig, "%d  %d ", frame, k );
     819             : 
     820             :             for ( i = start_band; i < nbands; i++ )
     821             :             {
     822             :                 for ( j = 0; j < nblocks; j++ )
     823             :                 {
     824             :                     if ( q_direction->coherence_band_data != NULL )
     825             :                     {
     826             :                         fprintf( pF_spcoh_orig, " %d ", q_direction->coherence_band_data[i].spread_coherence[j] );
     827             :                     }
     828             :                 }
     829             :             }
     830             :             fprintf( pF_spcoh_orig, "\n" );
     831             :         }
     832             : #endif
     833             : 
     834       96772 :         q_direction->not_in_2D = 0;
     835             : 
     836             :         /*Coherence */
     837       96772 :         if ( all_coherence_zero == 0 )
     838             :         {
     839       83969 :             ivas_qmetadata_quantize_coherence_hr_512( hQMetaData, d, all_coherence_zero, hMetaData, bits_sp_coh );
     840             :         }
     841             : 
     842             :         /* write the  spherical indexes */
     843       96772 :         bits_ec = hMetaData->nb_bits_tot;
     844       96772 :         if ( bits_sph_idx == 11 )
     845             :         {
     846             :             /* do the quantization */
     847       59838 :             quantize_direction_frame( q_direction, azimuth_orig, elevation_orig, 1 );
     848             :         }
     849             : 
     850     2095358 :         for ( i = start_band; i < nbands; i++ )
     851             :         {
     852     7972613 :             for ( j = 0; j < nblocks; j++ )
     853             :             {
     854     5974027 :                 push_next_indice( hMetaData, q_direction->band_data[i].spherical_index[j], bits_sph_idx );
     855             :             }
     856             :         }
     857       96772 :         bits_ec = hMetaData->nb_bits_tot - bits_ec;
     858             : 
     859             : #ifdef DEBUG_MODE_QMETADATA
     860             :         {
     861             :             float tmp_f;
     862             :             fprintf( pF, "frame %d: diff %d  ", frame, bits_diff[d] );
     863             :             fprintf( pF_azi, "frame %d/dir/ec %d: ", frame, d );
     864             :             fprintf( pF_ele, "frame %d/dir/ec %d: ", frame, d );
     865             :             fprintf( pF_ratio, "frame %d/dir %d: ", frame, d );
     866             :             /*fprintf( pF_spcoh, "frame %d/dir %d: ", frame, d ); */
     867             :             fprintf( pF_spcoh, " %d  %d ", frame, d );
     868             : 
     869             :             if ( d == 0 )
     870             :             {
     871             :                 fprintf( pF_surcoh, "frame %d/dir %d: ", frame, d );
     872             :             }
     873             : 
     874             :             /* direction_distance( elevation_orig, azimuth_orig, q_direction,  nbands, nblocks, mat_dist );*/
     875             :             for ( i = start_band; i < nbands; i++ )
     876             :             {
     877             :                 for ( j = 0; j < nblocks; j++ )
     878             :                 {
     879             :                     fprintf( pF_azi, " %+5.2f ", (int16_t) ( 100.f * q_direction->band_data[i].azimuth[j] ) / 100.f );
     880             :                     fprintf( pF_ele, " %+5.2f ", (int16_t) ( 100.f * q_direction->band_data[i].elevation[j] ) / 100.f );
     881             :                     fprintf( pF_ratio, " %1.3f ", q_direction->band_data[i].energy_ratio[j] );
     882             :                     if ( q_direction->coherence_band_data != NULL )
     883             :                     {
     884             :                         fprintf( pF_spcoh, " %d ", q_direction->coherence_band_data[i].spread_coherence[j] );
     885             :                     }
     886             :                     if ( d == 0 && hQMetaData->surcoh_band_data != NULL )
     887             :                     {
     888             :                         fprintf( pF_surcoh, " %d ", hQMetaData->surcoh_band_data[i].surround_coherence[j] );
     889             :                     }
     890             :                 }
     891             :             }
     892             :             fprintf( pF, "\n" );
     893             :             fprintf( pF_azi, "\n" );
     894             :             fprintf( pF_ele, "\n" );
     895             :             fprintf( pF_ratio, "\n" );
     896             :             fprintf( pF_spcoh, "\n" );
     897             :             if ( d == 0 )
     898             :             {
     899             :                 fprintf( pF_surcoh, "\n" );
     900             :             }
     901             : 
     902             :             for ( i = 0; i < nblocks; i++ )
     903             :             {
     904             :                 for ( j = 0; j < nbands; j++ )
     905             :                 {
     906             :                     dbgwrite( &( q_direction->band_data[j].azimuth[i] ), sizeof( float ), 1, 1, "./res/IVAS_QMETADATA_azi.bin" );
     907             :                     dbgwrite( &( q_direction->band_data[j].elevation[i] ), sizeof( float ), 1, 1, "./res/IVAS_QMETADATA_ele.bin" );
     908             :                     dbgwrite( &( q_direction->band_data[j].energy_ratio_index[i] ), sizeof( uint16_t ), 1, 1, "./res/IVAS_QMETADATA_diffuseness_index.bin" );
     909             :                     tmp_f = 1.f - q_direction->band_data[j].energy_ratio[i];
     910             :                     dbgwrite( &tmp_f, sizeof( float ), 1, 1, "./res/IVAS_QMETADATA_diffuseness.bin" );
     911             :                 }
     912             :             }
     913             : 
     914             :             j = (int16_t) ( hMetaData->nb_bits_tot );
     915             :             dbgwrite( &j, sizeof( int16_t ), 1, 1, "./res/IVAS_QMETADATA_bits.bin" );
     916             :         }
     917             : #endif
     918             : 
     919             :         /* Save quantized DOAs */
     920       96772 :         if ( bits_sph_idx == 11 )
     921             :         {
     922     1210260 :             for ( i = start_band; i < nbands; i++ )
     923             :             {
     924     1150422 :                 mvr2r( azimuth_orig[i], q_direction->band_data[i].azimuth, nblocks );
     925     1150422 :                 mvr2r( elevation_orig[i], q_direction->band_data[i].elevation, nblocks );
     926             :             }
     927             :         }
     928             :         else
     929             :         {
     930      885098 :             for ( i = start_band; i < nbands; i++ )
     931             :             {
     932      848164 :                 mvr2r( q_direction->band_data[i].azimuth, q_direction->band_data[i].q_azimuth, nblocks );
     933      848164 :                 mvr2r( q_direction->band_data[i].elevation, q_direction->band_data[i].q_elevation, nblocks );
     934             :             }
     935             :         }
     936             :     }
     937             : 
     938       74940 :     if ( hQMetaData->q_direction->cfg.inactiveBands > 0 )
     939             :     {
     940       15616 :         hQMetaData->q_direction[0].cfg.nbands += hQMetaData->q_direction->cfg.inactiveBands;
     941       15616 :         if ( ndirections > 1 )
     942             :         {
     943        5150 :             hQMetaData->q_direction[1].cfg.nbands += hQMetaData->q_direction->cfg.inactiveBands;
     944             :         }
     945             :     }
     946             : 
     947       74940 :     return error;
     948             : }
     949             : 
     950             : 
     951             : /*-----------------------------------------------------------------------*
     952             :  * ivas_qmetadata_enc_sid_encode()
     953             :  *
     954             :  * Main function for coding SID for Spatial Metadata
     955             :  *-----------------------------------------------------------------------*/
     956             : 
     957             : /*! r: number of bits written */
     958       84595 : void ivas_qmetadata_enc_sid_encode(
     959             :     BSTR_ENC_HANDLE hMetaData,         /* i/o: metadata bitstream handle                 */
     960             :     IVAS_QMETADATA *q_metadata,        /* i/o: metadata handle                           */
     961             :     const int16_t masa_sid_descriptor, /* i  : description of MASA SID coding structure  */
     962             :     const int16_t nchan_transport,     /* i  : number of transport channels              */
     963             :     const int16_t ivas_format          /* i  : IVAS format                               */
     964             : )
     965             : {
     966             :     int16_t b, m;
     967             :     int16_t bit_pos_start;
     968             :     IVAS_QDIRECTION *q_direction;
     969             :     int16_t nbands, nblocks, start_band;
     970             :     float avg_direction_vector[3];
     971             :     float direction_vector[3];
     972             :     float avg_azimuth[MASA_MAXIMUM_CODING_SUBBANDS];
     973             :     float avg_elevation[MASA_MAXIMUM_CODING_SUBBANDS];
     974             :     int16_t bits_dir, bits_diff, bits_delta;
     975             :     int16_t metadata_sid_bits; /* bits allocated to SID for metadata */
     976             :     int16_t sba_spar_bitlen;
     977             : 
     978       84595 :     if ( ivas_format == SBA_FORMAT )
     979             :     {
     980       14468 :         sba_spar_bitlen = ivas_sba_spar_sid_bitlen( nchan_transport );
     981       14468 :         metadata_sid_bits = (int16_t) ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - sba_spar_bitlen - SID_FORMAT_NBITS - SBA_ORDER_BITS - SBA_PLANAR_BITS - 1; /* -1 for inactive mode header bit*/
     982             :     }
     983             :     else
     984             :     {
     985       70127 :         metadata_sid_bits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS;
     986             :     }
     987             : 
     988             : #ifdef DEBUG_MODE_QMETADATA
     989             :     static FILE *pF_azi = NULL;
     990             :     static FILE *pF_ele = NULL;
     991             :     static FILE *pF_ratio = NULL;
     992             : 
     993             :     if ( pF_azi == NULL )
     994             :         pF_azi = fopen( "./res/qmetadata_sid_azi_enc.txt", "w" );
     995             :     if ( pF_ele == NULL )
     996             :         pF_ele = fopen( "./res/qmetadata_sid_ele_enc.txt", "w" );
     997             :     if ( pF_ratio == NULL )
     998             :         pF_ratio = fopen( "./res/qmetadata_sid_ratio_enc.txt", "w" );
     999             : 
    1000             : #endif
    1001             : 
    1002             :     /* Save initial position in bitstream */
    1003       84595 :     bit_pos_start = hMetaData->nb_bits_tot;
    1004             : 
    1005             :     /* write for MASA the number of transport channels used at coding and the CPE mode DFT/MDCT */
    1006       84595 :     if ( masa_sid_descriptor > -1 )
    1007             :     {
    1008       45112 :         push_next_indice( hMetaData, masa_sid_descriptor, 1 );
    1009             :     }
    1010             : 
    1011             :     /* Code for one direction: diffuseness and average DOA(s)*/
    1012       84595 :     q_direction = &( q_metadata->q_direction[0] );
    1013       84595 :     nbands = q_direction->cfg.nbands;
    1014       84595 :     nblocks = q_direction->cfg.nblocks;
    1015       84595 :     start_band = 0; /*Start always with band 0 for SID*/
    1016             : 
    1017             :     /* sanity checks*/
    1018       84595 :     assert( q_metadata->no_directions == 1 && "Qmetadata SID: only one direction supported!" );
    1019       84595 :     if ( ivas_format == SBA_FORMAT )
    1020             :     {
    1021       14468 :         assert( ( q_direction->cfg.nbands == DIRAC_DTX_BANDS ) && "Qmetadata SID: only 2 bands supported!" );
    1022             :     }
    1023             :     else
    1024             :     {
    1025       70127 :         assert( ( q_direction->cfg.nbands == 5 ) && "Qmetadata SID: only 5 bands supported!" );
    1026             :     }
    1027             : 
    1028       84595 :     if ( ivas_format != SBA_FORMAT )
    1029             :     {
    1030             :         /* Signalling 2D*/
    1031       70127 :         push_next_indice( hMetaData, ( q_direction->not_in_2D > 0 ), 1 ); /*2D flag*/
    1032             :     }
    1033             :     else
    1034             :     {
    1035       14468 :         q_direction->not_in_2D = 1; /* force for merged modes */
    1036             :     }
    1037             : 
    1038             :     /*Encode the quantized diffuseness in raw coding*/
    1039       84595 :     bits_dir = 0;
    1040       84595 :     bits_diff = 0;
    1041       84595 :     if ( ivas_format != SBA_FORMAT )
    1042             :     {
    1043      420762 :         for ( b = start_band; b < nbands; b++ )
    1044             :         {
    1045      350635 :             q_direction->band_data[b].energy_ratio_index[0] = max( q_direction->band_data[b].energy_ratio_index[0], 4 );
    1046      350635 :             bits_diff += ivas_qmetadata_encode_quasi_uniform_length( q_direction->band_data[b].energy_ratio_index[0] - 4, DIRAC_DIFFUSE_LEVELS - 4 );
    1047      350635 :             q_direction->band_data[b].bits_sph_idx[0] = bits_direction_masa[q_direction->band_data[b].energy_ratio_index[0]];
    1048             : 
    1049      350635 :             if ( q_direction->not_in_2D == 0 )
    1050             :             {
    1051      104460 :                 q_direction->band_data[b].azimuth_m_alphabet[0] = 1 << ( min( 8, q_direction->band_data[b].bits_sph_idx[0] ) );
    1052      104460 :                 bits_dir += ivas_qmetadata_encode_quasi_uniform_length( q_direction->band_data[b].azimuth_m_alphabet[0] - 1, q_direction->band_data[b].azimuth_m_alphabet[0] );
    1053             :             }
    1054             :             else
    1055             :             {
    1056      246175 :                 bits_dir += q_direction->band_data[b].bits_sph_idx[0];
    1057             :             }
    1058             :         }
    1059             : 
    1060             :         /* Reduce bit demand by increasing diffuseness*/
    1061       70127 :         bits_delta = metadata_sid_bits - ( hMetaData->nb_bits_tot - bit_pos_start ) - bits_diff - bits_dir;
    1062       70127 :         if ( bits_delta > 0 )
    1063             :         {
    1064      299409 :             while ( bits_delta > 0 )
    1065             :             {
    1066     1209504 :                 for ( b = start_band; b < nbands && ( bits_delta > 0 ); b++ )
    1067             :                 {
    1068      980222 :                     if ( q_direction->band_data[b].bits_sph_idx[0] < 11 )
    1069             :                     {
    1070      980039 :                         bits_delta -= 1;
    1071      980039 :                         q_direction->band_data[b].bits_sph_idx[0]++;
    1072             :                     }
    1073             :                 }
    1074             :             }
    1075             : 
    1076       70127 :             if ( q_direction->not_in_2D == 0 )
    1077             :             {
    1078      125352 :                 for ( b = start_band; b < nbands; b++ )
    1079             :                 {
    1080      104460 :                     q_direction->band_data[b].azimuth_m_alphabet[0] = 1 << ( min( 8, q_direction->band_data[b].bits_sph_idx[0] ) );
    1081             :                 }
    1082             :             }
    1083             :         }
    1084             :         else
    1085             :         {
    1086           0 :             while ( bits_delta < 0 )
    1087             :             {
    1088           0 :                 for ( b = nbands - 1; b >= start_band && ( bits_delta < 0 ); b-- )
    1089             :                 {
    1090           0 :                     if ( q_direction->band_data[b].bits_sph_idx[0] >= 4 )
    1091             :                     {
    1092           0 :                         bits_delta += 1;
    1093           0 :                         q_direction->band_data[b].bits_sph_idx[0]--;
    1094           0 :                         if ( q_direction->not_in_2D == 0 )
    1095             :                         {
    1096           0 :                             q_direction->band_data[b].azimuth_m_alphabet[0] = 1 << ( min( 8, q_direction->band_data[b].bits_sph_idx[0] ) );
    1097             :                         }
    1098             :                     }
    1099             :                 }
    1100             :             }
    1101             :         }
    1102             :     }
    1103             :     else
    1104             :     {
    1105       43404 :         for ( b = start_band; b < nbands; b++ )
    1106             :         {
    1107       28936 :             q_direction->band_data[b].energy_ratio_index[0] = max( q_direction->band_data[b].energy_ratio_index[0], 4 );
    1108       28936 :             bits_diff += ivas_qmetadata_encode_quasi_uniform_length( q_direction->band_data[b].energy_ratio_index[0] - 4, DIRAC_DIFFUSE_LEVELS - 4 );
    1109       28936 :             q_direction->band_data[b].bits_sph_idx[0] = bits_direction_masa[q_direction->band_data[b].energy_ratio_index[0]];
    1110             : 
    1111       28936 :             if ( q_direction->not_in_2D == 0 )
    1112             :             {
    1113           0 :                 q_direction->band_data[b].azimuth_m_alphabet[0] = 1 << ( min( 5, q_direction->band_data[b].bits_sph_idx[0] ) );
    1114           0 :                 bits_dir += ivas_qmetadata_encode_quasi_uniform_length( q_direction->band_data[b].azimuth_m_alphabet[0] - 1, q_direction->band_data[b].azimuth_m_alphabet[0] );
    1115             :             }
    1116             :             else
    1117             :             {
    1118       28936 :                 bits_dir += q_direction->band_data[b].bits_sph_idx[0];
    1119             :             }
    1120             :         }
    1121             : 
    1122             :         /* Reduce bit demand by increasing diffuseness*/
    1123       14468 :         bits_delta = metadata_sid_bits - ( hMetaData->nb_bits_tot - bit_pos_start ) - bits_diff - bits_dir;
    1124             : 
    1125       14842 :         while ( bits_delta < 0 && ( q_direction->not_in_2D > 0 ) )
    1126             :         {
    1127         981 :             for ( b = nbands - 1; b >= start_band && ( bits_delta < 0 ); b-- )
    1128             :             {
    1129         607 :                 if ( q_direction->band_data[b].energy_ratio_index[0] < ( DIRAC_DIFFUSE_LEVELS - 1 ) )
    1130             :                 {
    1131         595 :                     bits_delta += q_direction->band_data[b].bits_sph_idx[0];
    1132         595 :                     q_direction->band_data[b].energy_ratio_index[0]++;
    1133         595 :                     q_direction->band_data[b].bits_sph_idx[0] = bits_direction_masa[q_direction->band_data[b].energy_ratio_index[0]];
    1134         595 :                     bits_delta -= q_direction->band_data[b].bits_sph_idx[0];
    1135             :                 }
    1136             :             }
    1137             :         }
    1138             :     }
    1139       84595 :     assert( ( bits_delta >= 0 ) && "Bit budget in Qmetadata SID is violated!!!" );
    1140             : 
    1141             :     /*Code diffuseness*/
    1142      464166 :     for ( b = start_band; b < nbands; b++ )
    1143             :     {
    1144      379571 :         ivas_qmetadata_encode_quasi_uniform( hMetaData, q_direction->band_data[b].energy_ratio_index[0] - 4, DIRAC_DIFFUSE_LEVELS - 4 );
    1145             :     }
    1146             : 
    1147             :     /* Compute and Quantize an average direction per band*/
    1148      464166 :     for ( b = start_band; b < nbands; b++ )
    1149             :     {
    1150      379571 :         set_zero( avg_direction_vector, 3 );
    1151     1152910 :         for ( m = 0; m < nblocks; m++ )
    1152             :         {
    1153             :             /*compute the average direction */
    1154      773339 :             ivas_qmetadata_azimuth_elevation_to_direction_vector( q_direction->band_data[b].azimuth[m], q_direction->band_data[b].elevation[m], direction_vector );
    1155      773339 :             v_add( avg_direction_vector, direction_vector, avg_direction_vector, 3 );
    1156             :         }
    1157             : 
    1158      379571 :         ivas_qmetadata_direction_vector_to_azimuth_elevation( avg_direction_vector, &avg_azimuth[b], &avg_elevation[b] );
    1159             : 
    1160             :         /* Quantize the average direction */
    1161      379571 :         if ( q_direction->not_in_2D == 0 )
    1162             :         {
    1163      104460 :             avg_elevation[b] = 0;
    1164      104460 :             q_direction->band_data[b].spherical_index[0] = quantize_direction2D( avg_azimuth[b], q_direction->band_data[b].azimuth_m_alphabet[0], &avg_azimuth[b],
    1165      104460 :                                                                                  &q_direction->band_data[b].azimuth_index[0], q_direction->cfg.mc_ls_setup );
    1166             :         }
    1167             :         else
    1168             :         {
    1169      275111 :             q_direction->band_data[b].spherical_index[0] = quantize_direction( avg_elevation[b], avg_azimuth[b], q_direction->band_data[b].bits_sph_idx[0], &avg_elevation[b], &avg_azimuth[b],
    1170      275111 :                                                                                &q_direction->band_data[b].elevation_index[0], &q_direction->band_data[b].azimuth_index[0], q_direction->cfg.mc_ls_setup );
    1171             :         }
    1172             : 
    1173             :         /* Save quantized DOAs */
    1174      379571 :         q_direction->band_data[b].q_azimuth[0] = avg_azimuth[b];
    1175      379571 :         q_direction->band_data[b].q_elevation[0] = avg_elevation[b];
    1176             : 
    1177      379571 :         if ( q_direction->band_data[b].azimuth_index[0] == MASA_NO_INDEX )
    1178             :         {
    1179         486 :             q_direction->band_data[b].azimuth_index[0] = 0;
    1180             :         }
    1181             :     }
    1182             : 
    1183             :     /* quantize average elevation and azimuth angles */
    1184       84595 :     if ( q_direction->not_in_2D > 0 )
    1185             :     {
    1186      338814 :         for ( b = start_band; b < nbands; b++ )
    1187             :         {
    1188      275111 :             push_next_indice( hMetaData, q_direction->band_data[b].spherical_index[0], q_direction->band_data[b].bits_sph_idx[0] );
    1189             :         }
    1190             :     }
    1191             :     else
    1192             :     {
    1193      125352 :         for ( b = start_band; b < nbands; b++ )
    1194             :         {
    1195      104460 :             ivas_qmetadata_encode_quasi_uniform( hMetaData, q_direction->band_data[b].azimuth_index[0], q_direction->band_data[b].azimuth_m_alphabet[0] );
    1196             :         }
    1197             :     }
    1198             : 
    1199             : #ifdef DEBUG_MODE_QMETADATA
    1200             :     {
    1201             :         fprintf( pF_azi, "frame %d: ", frame );
    1202             :         fprintf( pF_ele, "frame %d: ", frame );
    1203             :         fprintf( pF_ratio, "frame %d: ", frame );
    1204             : 
    1205             : 
    1206             :         /* Data is not used currently. Fix function when needed. */
    1207             :         /*direction_distance( elevation_orig, azimuth_orig, q_direction->elevation, q_direction->azimuth, nbands, nblocks, mat_dist );*/
    1208             :         for ( b = start_band; b < nbands; b++ )
    1209             :         {
    1210             :             fprintf( pF_azi, " %+5.2f ", (int16_t) ( 100.f * avg_azimuth[b] ) / 100.f );
    1211             :             fprintf( pF_ele, " %+5.2f ", (int16_t) ( 100.f * avg_elevation[b] ) / 100.f );
    1212             :             fprintf( pF_ratio, " %1.3f ", q_direction->band_data[b].energy_ratio[0] );
    1213             :         }
    1214             :         fprintf( pF_azi, "\n" );
    1215             :         fprintf( pF_ele, "\n" );
    1216             :         fprintf( pF_ratio, "\n" );
    1217             :     }
    1218             : #endif
    1219             : 
    1220             :     /* fill bits*/
    1221       84595 :     assert( ( hMetaData->nb_bits_tot - bit_pos_start ) <= metadata_sid_bits && "Too many written bits!" );
    1222      170666 :     while ( ( hMetaData->nb_bits_tot - bit_pos_start ) < metadata_sid_bits )
    1223             :     {
    1224       86071 :         push_next_indice( hMetaData, 0, 1 ); /*fill bit*/
    1225             :     }
    1226             : 
    1227       84595 :     return;
    1228             : }
    1229             : 
    1230             : 
    1231             : /*-------------------------------------------------------------------------
    1232             :  * reset_metadata_spatial()
    1233             :  *
    1234             :  * Reset metadata in spatial formats
    1235             :  *------------------------------------------------------------------------*/
    1236             : 
    1237     1655356 : void reset_metadata_spatial(
    1238             :     const IVAS_FORMAT ivas_format, /* i  : IVAS format                  */
    1239             :     BSTR_ENC_HANDLE hMetaData,     /* i/o: metadata bitstream handle    */
    1240             :     const int32_t element_brate,   /* i  : element bitrate              */
    1241             :     int32_t *total_brate,          /* o  : total bitrate                */
    1242             :     const int32_t core_brate,      /* i  : core bitrate                 */
    1243             :     const int16_t nb_bits_metadata /* i  : number of meatdata bits      */
    1244             : )
    1245             : {
    1246             :     int16_t i, next_ind_sid, last_ind_sid;
    1247             :     int16_t j;
    1248             :     int16_t metadata_sid_bits;
    1249             : 
    1250     1655356 :     if ( core_brate == SID_2k40 || core_brate == FRAME_NO_DATA )
    1251             :     {
    1252       16000 :         if ( ( ivas_format == SBA_FORMAT || ivas_format == MASA_FORMAT ) && core_brate != FRAME_NO_DATA )
    1253             :         {
    1254        2549 :             if ( ivas_format == SBA_FORMAT )
    1255             :             {
    1256             : #ifdef DEBUGGING
    1257             :                 assert( hMetaData->ind_list[0].nb_bits == 1 );
    1258             : #endif
    1259        1451 :                 hMetaData->ind_list[0].value = 1;
    1260        1451 :                 metadata_sid_bits = (int16_t) ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS - SBA_PLANAR_BITS - SBA_ORDER_BITS;
    1261             : 
    1262        1451 :                 while ( hMetaData->nb_bits_tot < metadata_sid_bits )
    1263             :                 {
    1264           0 :                     push_next_indice( hMetaData, 0, 1 ); /*fill bit*/
    1265             :                 }
    1266             :             }
    1267             :             else
    1268             :             {
    1269             :                 /* Reset metadata and keep only SID metadata*/
    1270        1098 :                 last_ind_sid = hMetaData->nb_ind_tot;
    1271        1098 :                 next_ind_sid = hMetaData->nb_ind_tot;
    1272       14092 :                 while ( hMetaData->nb_bits_tot > nb_bits_metadata )
    1273             :                 {
    1274       12994 :                     next_ind_sid--;
    1275       12994 :                     hMetaData->nb_bits_tot -= hMetaData->ind_list[next_ind_sid].nb_bits;
    1276             :                 }
    1277             : 
    1278        1098 :                 hMetaData->nb_bits_tot = 0;
    1279             : 
    1280       26152 :                 for ( i = 0; i < next_ind_sid; i++ )
    1281             :                 {
    1282       25054 :                     hMetaData->ind_list[i].nb_bits = -1;
    1283             : #if defined( DEBUGGING ) && defined( DBG_BITSTREAM_ANALYSIS )
    1284             :                     sprintf( hMetaData->ind_list[i].function_name, "RESET in reset_metadata_spatial" );
    1285             : #endif
    1286             :                 }
    1287             : 
    1288       14092 :                 for ( j = 0, i = next_ind_sid; i < last_ind_sid; i++, j++ )
    1289             :                 {
    1290       12994 :                     hMetaData->ind_list[j].value = hMetaData->ind_list[i].value;
    1291       12994 :                     hMetaData->ind_list[j].nb_bits = hMetaData->ind_list[i].nb_bits;
    1292             : #if defined( DEBUGGING ) && defined( DBG_BITSTREAM_ANALYSIS )
    1293             :                     strncpy( hMetaData->ind_list[j].function_name, hMetaData->ind_list[i].function_name, 100 );
    1294             : #endif
    1295       12994 :                     hMetaData->nb_bits_tot += hMetaData->ind_list[j].nb_bits;
    1296       12994 :                     hMetaData->ind_list[i].nb_bits = -1;
    1297             : #ifdef DBG_BISTREAM_ANALYSIS
    1298             :                     sprintf( hMetaData->ind_list[i].function_name, "RESET in reset_metadata_spatial" );
    1299             : #endif
    1300             :                 }
    1301             : 
    1302        1098 :                 hMetaData->nb_ind_tot = j;
    1303             : #ifdef DEBUGGING
    1304             :                 assert( ( hMetaData->nb_bits_tot == ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS ) && "Problem of SID metadata in SCE" );
    1305             : #endif
    1306             :             }
    1307             :         }
    1308             :         else
    1309             :         {
    1310             :             /*Reset metadata*/
    1311       13451 :             reset_indices_enc( hMetaData, hMetaData->nb_ind_tot );
    1312             :         }
    1313             : 
    1314       16000 :         *total_brate = element_brate;
    1315             :     }
    1316     1639356 :     else if ( ivas_format != SBA_FORMAT )
    1317             :     {
    1318             :         /* Reset SID metadata bits*/
    1319     1393056 :         while ( hMetaData->nb_bits_tot > nb_bits_metadata )
    1320             :         {
    1321      770858 :             hMetaData->nb_ind_tot--;
    1322      770858 :             hMetaData->nb_bits_tot -= hMetaData->ind_list[hMetaData->nb_ind_tot].nb_bits;
    1323      770858 :             hMetaData->ind_list[hMetaData->nb_ind_tot].nb_bits = -1;
    1324             : #if defined( DEBUGGING ) && defined( DBG_BITSTREAM_ANALYSIS )
    1325             :             sprintf( hMetaData->ind_list[hMetaData->nb_ind_tot].function_name, "RESET in reset_metadata_spatial" );
    1326             : #endif
    1327             :         }
    1328             : #ifdef DEBUGGING
    1329             :         assert( hMetaData->nb_bits_tot == nb_bits_metadata && "Problem in metadata for SCE" );
    1330             : #endif
    1331             :     }
    1332             : 
    1333     1655356 :     return;
    1334             : }
    1335             : 
    1336             : 
    1337             : /*-------------------------------------------------------------------------
    1338             :  * quantize_direction2D()
    1339             :  *
    1340             :  *
    1341             :  *------------------------------------------------------------------------*/
    1342             : 
    1343             : /*! r: quantized spherical index */
    1344     1063254 : int16_t quantize_direction2D(
    1345             :     float phi,                  /* i  : input azimuth value             */
    1346             :     const int16_t no_cw,        /* i  : number of bits                  */
    1347             :     float *phi_q,               /* o  : quantized azimuth value         */
    1348             :     uint16_t *index_phi,        /* o  : quantized azimuth index         */
    1349             :     const MC_LS_SETUP mc_format /* i  : channel format if in MC-mode    */
    1350             : )
    1351             : {
    1352             :     int16_t idx_sph;
    1353             :     uint16_t id_phi;
    1354     1063254 :     if ( no_cw < 2 )
    1355             :     {
    1356           0 :         *phi_q = 0;
    1357             : 
    1358           0 :         return 0;
    1359             :     }
    1360             : 
    1361     1063254 :     if ( mc_format != MC_LS_SETUP_INVALID )
    1362             :     {
    1363      913955 :         id_phi = quantize_phi_chan_compand( phi + 180, phi_q, no_cw, 0, mc_format );
    1364             :     }
    1365             :     else
    1366             :     {
    1367      149299 :         id_phi = quantize_phi( phi + 180, 0, phi_q, no_cw );
    1368             :     }
    1369     1063254 :     *phi_q -= 180;
    1370     1063254 :     *index_phi = ivas_qmetadata_reorder_generic( id_phi - ( no_cw >> 1 ) );
    1371             : 
    1372     1063254 :     idx_sph = id_phi;
    1373             : 
    1374     1063254 :     return idx_sph;
    1375             : }
    1376             : 
    1377             : 
    1378       74940 : static void ivas_qmetadata_quantize_diffuseness_nrg_ratios_hr_512(
    1379             :     IVAS_QMETADATA_HANDLE hQMetaData,
    1380             :     int16_t *needed_bits,
    1381             :     const int16_t bits_dir_hr,
    1382             :     BSTR_ENC_HANDLE hMetaData )
    1383             : {
    1384             :     int16_t j, k;
    1385             :     int16_t index;
    1386             : 
    1387       74940 :     needed_bits[0] = 0;
    1388       74940 :     needed_bits[1] = 0;
    1389             : 
    1390     1757950 :     for ( j = hQMetaData->q_direction[0].cfg.start_band; j < hQMetaData->q_direction[0].cfg.nbands; ++j )
    1391             :     {
    1392     6768722 :         for ( k = 0; k < hQMetaData->q_direction[0].cfg.nblocks; k++ )
    1393             :         {
    1394     5085712 :             index = masa_sq( 1.0f - hQMetaData->q_direction[0].band_data[j].energy_ratio[k], diffuseness_thresholds_hr, HR_MASA_ER_LEVELS );
    1395     5085712 :             push_next_indice( hMetaData, index, MASA_BITS_ER_HR );
    1396     5085712 :             hQMetaData->q_direction[0].band_data[j].energy_ratio_index[k] = index;
    1397     5085712 :             hQMetaData->q_direction[0].band_data[j].energy_ratio_index_mod[k] = index;
    1398     5085712 :             hQMetaData->q_direction[0].band_data[j].energy_ratio[k] = 1.0f - diffuseness_reconstructions_hr[index];
    1399     5085712 :             needed_bits[0] += MASA_BITS_ER_HR;
    1400     5085712 :             hQMetaData->q_direction[0].band_data[j].bits_sph_idx[k] = bits_dir_hr;
    1401             :         }
    1402             :     }
    1403             : 
    1404       74940 :     if ( hQMetaData->no_directions == 2 )
    1405             :     {
    1406             :         float ratioSum;
    1407       21832 :         if ( bits_dir_hr == 16 )
    1408             :         {
    1409      191066 :             for ( j = hQMetaData->q_direction[1].cfg.start_band; j < hQMetaData->q_direction[1].cfg.nbands; j++ )
    1410             :             {
    1411      708040 :                 for ( k = 0; k < hQMetaData->q_direction[1].cfg.nblocks; k++ )
    1412             :                 {
    1413      524918 :                     index = masa_sq( 1.0f - hQMetaData->q_direction[1].band_data[j].energy_ratio[k], diffuseness_thresholds_hr, HR_MASA_ER_LEVELS );
    1414      524918 :                     push_next_indice( hMetaData, index, MASA_BITS_ER_HR );
    1415      524918 :                     hQMetaData->q_direction[1].band_data[j].energy_ratio_index[k] = index;
    1416      524918 :                     hQMetaData->q_direction[1].band_data[j].energy_ratio[k] = 1.0f - diffuseness_reconstructions_hr[index];
    1417             : 
    1418      524918 :                     ratioSum = hQMetaData->q_direction[0].band_data[j].energy_ratio[k] + hQMetaData->q_direction[1].band_data[j].energy_ratio[k];
    1419      524918 :                     if ( ratioSum > 1.0f )
    1420             :                     {
    1421      110289 :                         hQMetaData->q_direction[0].band_data[j].energy_ratio[k] /= ratioSum;
    1422      110289 :                         hQMetaData->q_direction[1].band_data[j].energy_ratio[k] /= ratioSum;
    1423             :                     }
    1424             : 
    1425      524918 :                     needed_bits[1] += MASA_BITS_ER_HR;
    1426      524918 :                     hQMetaData->q_direction[1].band_data[j].bits_sph_idx[k] = bits_dir_hr;
    1427             :                 }
    1428             :             }
    1429             :         }
    1430             :         else
    1431             :         {
    1432             :             int16_t pos_2dir_band[MASA_MAXIMUM_CODING_SUBBANDS];
    1433       13888 :             k = 0;
    1434      314642 :             for ( j = hQMetaData->q_direction[0].cfg.start_band; j < hQMetaData->q_direction[0].cfg.nbands; j++ )
    1435             :             {
    1436      300754 :                 if ( hQMetaData->twoDirBands[j] == 1 )
    1437             :                 {
    1438      132454 :                     pos_2dir_band[k] = j;
    1439      132454 :                     k++;
    1440             :                 }
    1441             :                 else
    1442             :                 {
    1443      168300 :                     pos_2dir_band[k] = 0;
    1444             :                 }
    1445             :             }
    1446      146342 :             for ( j = hQMetaData->q_direction[1].cfg.start_band; j < hQMetaData->q_direction[1].cfg.nbands; j++ )
    1447             :             {
    1448      495851 :                 for ( k = 0; k < hQMetaData->q_direction[1].cfg.nblocks; k++ )
    1449             :                 {
    1450      363397 :                     index = masa_sq( 1.0f - hQMetaData->q_direction[1].band_data[j].energy_ratio[k], diffuseness_thresholds_hr, HR_MASA_ER_LEVELS );
    1451      363397 :                     push_next_indice( hMetaData, index, MASA_BITS_ER_HR );
    1452      363397 :                     hQMetaData->q_direction[1].band_data[j].energy_ratio_index[k] = index;
    1453      363397 :                     hQMetaData->q_direction[1].band_data[j].energy_ratio[k] = 1.0f - diffuseness_reconstructions_hr[index];
    1454             : 
    1455      363397 :                     ratioSum = hQMetaData->q_direction[0].band_data[pos_2dir_band[j]].energy_ratio[k] + hQMetaData->q_direction[1].band_data[j].energy_ratio[k];
    1456             : 
    1457      363397 :                     if ( ratioSum > 1.0f )
    1458             :                     {
    1459       30222 :                         hQMetaData->q_direction[0].band_data[pos_2dir_band[j]].energy_ratio[k] /= ratioSum;
    1460       30222 :                         hQMetaData->q_direction[1].band_data[j].energy_ratio[k] /= ratioSum;
    1461             :                     }
    1462             : 
    1463      363397 :                     needed_bits[1] += MASA_BITS_ER_HR;
    1464      363397 :                     hQMetaData->q_direction[1].band_data[j].bits_sph_idx[k] = bits_dir_hr;
    1465             :                 }
    1466             :             }
    1467             :         }
    1468             :     }
    1469             : 
    1470       74940 :     return;
    1471             : }
    1472             : 
    1473             : 
    1474             : /*-------------------------------------------------------------------------
    1475             :  * ivas_qmetadata_quantize_diffuseness_nrg_ratios()
    1476             :  *
    1477             :  * Quantize diffuseness
    1478             :  *------------------------------------------------------------------------*/
    1479             : 
    1480     3945875 : static void ivas_qmetadata_quantize_diffuseness_nrg_ratios(
    1481             :     IVAS_QMETADATA_HANDLE hQMetaData,
    1482             :     int16_t *needed_bits,
    1483             :     int16_t *nbits_diff,
    1484             :     int16_t *dfRatioBits,
    1485             :     const int16_t hodirac_flag )
    1486             : {
    1487             :     int16_t j, k, dir2band;
    1488             :     int16_t index_dirRatio1Inv, index_dirRatio2Inv, index_dirRatio1Inv_mod, index_dirRatio2Inv_mod;
    1489             :     int16_t index_diff;
    1490             : 
    1491     3945875 :     nbits_diff[0] = 0;
    1492     3945875 :     nbits_diff[1] = 0;
    1493     3945875 :     needed_bits[0] = 0;
    1494     3945875 :     needed_bits[1] = 0;
    1495     3945875 :     dir2band = 0;
    1496             : 
    1497    22915451 :     for ( j = hQMetaData->q_direction[0].cfg.start_band; j < hQMetaData->q_direction[0].cfg.nbands; ++j )
    1498             :     {
    1499    18969576 :         if ( hQMetaData->no_directions == 2 && hQMetaData->twoDirBands[j] == 1 )
    1500     2709152 :         {
    1501             :             float diffRatio, dfRatio, dfRatioQ, diffRatioQ, dirRatio1Q, dirRatio2Q;
    1502             :             float dirRatio1, dirRatio2, sumRatio;
    1503             :             int16_t dfRatio_index, dfRatio_qsteps, dfRatio_bits;
    1504             : 
    1505             :             /* With 2dir metadata, we quantize and transmit diffuse-to-total ratio (diffRatio) and
    1506             :              * distribution factor of direct-to-total ratios (dFRatio). This is more efficient and
    1507             :              * accurate than simple separate quantization of each direct-to-total ratio or their
    1508             :              * separate inverses. */
    1509     2709152 :             if ( hodirac_flag )
    1510             :             {
    1511             :                 /* already encoded as total and ratios in HO-DirAC */
    1512     2077273 :                 diffRatio = 1.f - hQMetaData->q_direction[0].band_data[j].energy_ratio[0];
    1513     2077273 :                 dfRatio = hQMetaData->q_direction[1].band_data[dir2band].energy_ratio[0];
    1514             :             }
    1515             :             else
    1516             :             {
    1517      631879 :                 dirRatio1 = hQMetaData->q_direction[0].band_data[j].energy_ratio[0];
    1518      631879 :                 dirRatio2 = hQMetaData->q_direction[1].band_data[dir2band].energy_ratio[0];
    1519      631879 :                 sumRatio = dirRatio1 + dirRatio2;
    1520      631879 :                 diffRatio = 1.0f - sumRatio;
    1521      631879 :                 dfRatio = sumRatio < EPSILON ? 0.5f : dirRatio1 / sumRatio;
    1522             :             }
    1523             : 
    1524             : 
    1525     2709152 :             index_diff = masa_sq( diffRatio, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS );
    1526     2709152 :             diffRatioQ = diffuseness_reconstructions[index_diff];
    1527             : 
    1528     2709152 :             if ( hodirac_flag )
    1529             :             {
    1530     2077273 :                 dfRatio_bits = ivas_get_df_ratio_bits_hodirac( index_diff );
    1531             :             }
    1532             :             else
    1533             :             {
    1534      631879 :                 dfRatio_bits = ivas_get_df_ratio_bits( index_diff );
    1535             :             }
    1536             : 
    1537     2709152 :             dfRatioBits[dir2band] = dfRatio_bits;
    1538             : 
    1539     2709152 :             dfRatio_qsteps = ( 1 << dfRatio_bits );
    1540     2709152 :             if ( hodirac_flag )
    1541             :             {
    1542     2077273 :                 dfRatio_index = usquant( dfRatio, &dfRatioQ, 0.0f, 1.f / ( dfRatio_qsteps - 1 ), dfRatio_qsteps );
    1543     2077273 :                 dirRatio1Q = 1.f - diffRatioQ;
    1544     2077273 :                 dirRatio2Q = dfRatioQ;
    1545             :             }
    1546             :             else
    1547             :             {
    1548      631879 :                 dfRatio_index = usquant( dfRatio, &dfRatioQ, 0.5f, 0.5f / ( dfRatio_qsteps - 1 ), dfRatio_qsteps );
    1549             : 
    1550             :                 /* Direction quantization requires also separately quantized direct-to-total ratios. Thus, we calculate them. */
    1551      631879 :                 dirRatio1Q = dfRatioQ * ( 1.0f - diffRatioQ );
    1552      631879 :                 dirRatio2Q = ( 1.0f - diffRatioQ ) - dirRatio1Q;
    1553             :             }
    1554             : 
    1555     2709152 :             index_dirRatio1Inv = masa_sq( 1.0f - dirRatio1Q, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS );
    1556             : 
    1557             :             /* Note: To save memory, we store temporarily index_diff and dfRatio_index into first and second direction
    1558             :              * energy ratio index variables until they have been encoded. index_dirRatio1Inv and index_dirRatio2Inv are
    1559             :              * then later retrieved for further use in encoding. */
    1560    12746041 :             for ( k = 0; k < hQMetaData->q_direction[0].cfg.nblocks; k++ )
    1561             :             {
    1562    10036889 :                 hQMetaData->q_direction[0].band_data[j].energy_ratio_index[k] = index_diff;
    1563    10036889 :                 hQMetaData->q_direction[0].band_data[j].energy_ratio[k] = dirRatio1Q;
    1564             :             }
    1565     2709152 :             nbits_diff[0] += MASA_BITS_ER;
    1566             : 
    1567     2709152 :             if ( hodirac_flag )
    1568             :             {
    1569             :                 float tmp;
    1570     2077273 :                 index_dirRatio2Inv = usquant( dirRatio2Q, &tmp, 0.0f, 1.f / ( DIRAC_DIFFUSE_LEVELS - 1 ), DIRAC_DIFFUSE_LEVELS );
    1571             :             }
    1572             :             else
    1573             :             {
    1574      631879 :                 index_dirRatio2Inv = masa_sq( 1.0f - dirRatio2Q, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS );
    1575             :             }
    1576             : 
    1577    12746041 :             for ( k = 0; k < hQMetaData->q_direction[1].cfg.nblocks; k++ )
    1578             :             {
    1579    10036889 :                 hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[k] = dfRatio_index;
    1580    10036889 :                 hQMetaData->q_direction[1].band_data[dir2band].energy_ratio[k] = dirRatio2Q;
    1581             :             }
    1582     2709152 :             nbits_diff[1] += dfRatio_bits;
    1583             : 
    1584             :             /* Obtain compensated direct-to-total ratios for direction quantization. This compensates for the
    1585             :              * fact that with 2dir data, it is harder to achieve separate high direct-to-total ratio values
    1586             :              * which are assumed by the direction quantization system. In practice, this improves direction
    1587             :              * accuracy when it is perceptual meaningful. */
    1588     2709152 :             masa_compensate_two_dir_energy_ratio_index( index_dirRatio1Inv, index_dirRatio2Inv, &index_dirRatio1Inv_mod, &index_dirRatio2Inv_mod, hodirac_flag );
    1589             : 
    1590    12746041 :             for ( k = 0; k < hQMetaData->q_direction[0].cfg.nblocks; k++ )
    1591             :             {
    1592    10036889 :                 hQMetaData->q_direction[0].band_data[j].energy_ratio_index_mod[k] = index_dirRatio1Inv_mod;
    1593    10036889 :                 hQMetaData->q_direction[0].band_data[j].bits_sph_idx[k] = bits_direction_masa[index_dirRatio1Inv_mod];
    1594             :             }
    1595     2709152 :             needed_bits[0] += hQMetaData->q_direction[0].cfg.nblocks * bits_direction_masa[index_dirRatio1Inv_mod];
    1596             : 
    1597    12746041 :             for ( k = 0; k < hQMetaData->q_direction[1].cfg.nblocks; k++ )
    1598             :             {
    1599    10036889 :                 hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index_mod[k] = index_dirRatio2Inv_mod;
    1600    10036889 :                 hQMetaData->q_direction[1].band_data[dir2band].bits_sph_idx[k] = bits_direction_masa[index_dirRatio2Inv_mod];
    1601             :             }
    1602     2709152 :             needed_bits[1] += hQMetaData->q_direction[1].cfg.nblocks * bits_direction_masa[index_dirRatio2Inv_mod];
    1603             : 
    1604     2709152 :             dir2band++;
    1605             :         }
    1606             :         else
    1607             :         {
    1608    16260424 :             index_dirRatio1Inv = masa_sq( 1.0f - hQMetaData->q_direction[0].band_data[j].energy_ratio[0], diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS );
    1609             : 
    1610    64025099 :             for ( k = 0; k < hQMetaData->q_direction[0].cfg.nblocks; k++ )
    1611             :             {
    1612    47764675 :                 hQMetaData->q_direction[0].band_data[j].energy_ratio_index[k] = index_dirRatio1Inv;
    1613    47764675 :                 hQMetaData->q_direction[0].band_data[j].energy_ratio_index_mod[k] = index_dirRatio1Inv;
    1614    47764675 :                 hQMetaData->q_direction[0].band_data[j].energy_ratio[k] = 1.0f - diffuseness_reconstructions[index_dirRatio1Inv];
    1615    47764675 :                 hQMetaData->q_direction[0].band_data[j].bits_sph_idx[k] = bits_direction_masa[index_dirRatio1Inv];
    1616             :             }
    1617             : 
    1618    16260424 :             nbits_diff[0] += MASA_BITS_ER;
    1619             : 
    1620    16260424 :             needed_bits[0] += hQMetaData->q_direction[0].cfg.nblocks * bits_direction_masa[index_dirRatio1Inv];
    1621             :         }
    1622             :     }
    1623             : 
    1624     3945875 :     return;
    1625             : }
    1626             : 
    1627             : 
    1628             : /*-------------------------------------------------------------------------
    1629             :  * ivas_diffuseness_huff_ec_encode()
    1630             :  *
    1631             :  *
    1632             :  *------------------------------------------------------------------------*/
    1633             : 
    1634     5222144 : static int16_t ivas_diffuseness_huff_ec_encode(
    1635             :     BSTR_ENC_HANDLE hMetaData,
    1636             :     const uint16_t idx )
    1637             : {
    1638             :     int16_t nbits;
    1639     5222144 :     nbits = 0;
    1640     5222144 :     if ( idx <= DIFF_EC_HUFF_GR0_LIMIT )
    1641             :     {
    1642     5216840 :         if ( idx > 0 )
    1643             :         {
    1644     2136866 :             push_next_indice( hMetaData, ( 1 << idx ) - 1, idx );
    1645     2136866 :             nbits += idx;
    1646             :         }
    1647     5216840 :         push_next_indice( hMetaData, 0, 1 );
    1648     5216840 :         nbits += 1;
    1649             :     }
    1650             :     else
    1651             :     {
    1652        5304 :         push_next_indice( hMetaData, 511, DIFF_EC_HUFF_GR0_LIMIT + 1 );
    1653        5304 :         push_next_indice( hMetaData, idx - DIFF_EC_HUFF_GR0_LIMIT - 1, 2 );
    1654        5304 :         nbits += DIFF_EC_HUFF_GR0_LIMIT + 3;
    1655             :     }
    1656     5222144 :     return nbits;
    1657             : }
    1658             : 
    1659             : 
    1660             : /*-------------------------------------------------------------------------
    1661             :  * ivas_diffuseness_huff_ec_prepare()
    1662             :  *
    1663             :  *
    1664             :  *------------------------------------------------------------------------*/
    1665             : 
    1666      574359 : static void ivas_diffuseness_huff_ec_prepare(
    1667             :     IVAS_QDIRECTION *q_direction,
    1668             :     int16_t *best_av,
    1669             :     uint16_t *avr_idx,
    1670             :     int16_t *diffuseness_bits_huff )
    1671             : {
    1672             :     int16_t bits;
    1673             :     int16_t av_crt;
    1674             :     int16_t av;
    1675             :     int16_t sh_idx;
    1676             :     uint16_t ui_sh_idx[MASA_MAXIMUM_CODING_SUBBANDS];
    1677             :     int16_t b, start_band, nbands;
    1678             : 
    1679      574359 :     start_band = q_direction->cfg.start_band;
    1680      574359 :     nbands = q_direction->cfg.nbands;
    1681             : 
    1682      574359 :     *diffuseness_bits_huff = 0;
    1683      574359 :     av = 0;
    1684     8194250 :     for ( b = start_band; b < nbands; b++ )
    1685             :     {
    1686     7619891 :         av += q_direction->band_data[b].energy_ratio_index[0];
    1687             :     }
    1688      574359 :     av = (int16_t) ( 0.5f + av / (float) nbands );
    1689      574359 :     *best_av = av;
    1690             : 
    1691      574359 :     *diffuseness_bits_huff = MAX16B;
    1692     2297436 :     for ( av_crt = av - 1; av_crt <= av + 1; av_crt++ )
    1693             :     {
    1694     1723077 :         bits = 0;
    1695    24582750 :         for ( b = start_band; b < nbands; b++ )
    1696             :         {
    1697    22859673 :             sh_idx = q_direction->band_data[b].energy_ratio_index[0] - av_crt;
    1698    22859673 :             ui_sh_idx[b] = ( sh_idx <= 0 ) ? ( -2 * sh_idx ) : sh_idx * 2 - 1;
    1699    22859673 :             if ( ui_sh_idx[b] >= 2 * DIRAC_DIFFUSE_LEVELS - 3 )
    1700             :             {
    1701        5885 :                 bits = 100; /* to avoid difference larger than 6 in absolute value */
    1702             :             }
    1703             : 
    1704    22859673 :             bits += ( ui_sh_idx[b] <= DIFF_EC_HUFF_GR0_LIMIT ) ? ( ui_sh_idx[b] + 1 ) : 11;
    1705             :         }
    1706             : 
    1707     1723077 :         if ( bits < *diffuseness_bits_huff )
    1708             :         {
    1709     1036747 :             *diffuseness_bits_huff = bits;
    1710     1036747 :             mvs2s( (int16_t *) ui_sh_idx, (int16_t *) avr_idx, nbands );
    1711     1036747 :             *best_av = av_crt;
    1712             :         }
    1713             :     }
    1714             : 
    1715      574359 :     *diffuseness_bits_huff += MASA_BITS_ER; /* for the average */
    1716             : 
    1717      574359 :     return;
    1718             : }
    1719             : 
    1720             : /*-------------------------------------------------------------------------
    1721             :  * ivas_qmetadata_entropy_encode_diffuseness()
    1722             :  *
    1723             :  * encode diffuseness
    1724             :  *------------------------------------------------------------------------*/
    1725             : 
    1726     3945875 : static int16_t ivas_qmetadata_entropy_encode_diffuseness(
    1727             :     BSTR_ENC_HANDLE hMetaData,
    1728             :     IVAS_QDIRECTION *q_direction,
    1729             :     uint16_t *diffuseness_index_max_ec_frame )
    1730             : {
    1731             :     int16_t start_bit_pos;
    1732             :     int16_t diffuseness_bits_raw;
    1733             :     int16_t b;
    1734             :     int16_t min_diffuseness_m_index, max_diffuseness_m_index;
    1735             :     int16_t nbands;
    1736             :     int16_t start_band;
    1737             : 
    1738     3945875 :     nbands = q_direction->cfg.nbands;
    1739     3945875 :     start_band = q_direction->cfg.start_band;
    1740             : 
    1741     3945875 :     start_bit_pos = hMetaData->nb_bits_tot;
    1742             : 
    1743     3945875 :     if ( nbands == 1 )
    1744             :     {
    1745             :         /* If there is only one band, diffuseness should be coded directly as raw with no signaling. */
    1746       63720 :         push_next_indice( hMetaData, q_direction->band_data[0].energy_ratio_index[0], MASA_BITS_ER );
    1747       63720 :         *diffuseness_index_max_ec_frame = 5;
    1748       63720 :         return ( hMetaData->nb_bits_tot - start_bit_pos );
    1749             :     }
    1750             : 
    1751             :     /* compute the number of raw coding bits */
    1752     3882155 :     diffuseness_bits_raw = 0;
    1753    22788011 :     for ( b = start_band; b < nbands; b++ )
    1754             :     {
    1755    18905856 :         diffuseness_bits_raw += ivas_qmetadata_encode_quasi_uniform_length( q_direction->band_data[b].energy_ratio_index[0], DIRAC_DIFFUSE_LEVELS );
    1756             :     }
    1757             : 
    1758     3882155 :     min_diffuseness_m_index = q_direction->band_data[start_band].energy_ratio_index[0];
    1759     3882155 :     max_diffuseness_m_index = q_direction->band_data[start_band].energy_ratio_index[0];
    1760             : 
    1761    22788011 :     for ( b = start_band; b < nbands; b++ )
    1762             :     {
    1763    18905856 :         if ( q_direction->band_data[b].energy_ratio_index[0] < min_diffuseness_m_index )
    1764             :         {
    1765     2160353 :             min_diffuseness_m_index = q_direction->band_data[b].energy_ratio_index[0];
    1766             :         }
    1767             : 
    1768    18905856 :         if ( q_direction->band_data[b].energy_ratio_index[0] > max_diffuseness_m_index )
    1769             :         {
    1770     2444532 :             max_diffuseness_m_index = q_direction->band_data[b].energy_ratio_index[0];
    1771             :         }
    1772             :     }
    1773             : 
    1774     3882155 :     if ( nbands < DIFF_EC_HUFF_BAND_LIMIT )
    1775             :     {
    1776             :         /* Use similarity coding approach or raw coding when there is a low number of bands. */
    1777             :         /* one bit is used to indicate whether diffuseness values are entropy coded or coded raw */
    1778     3307796 :         if ( min_diffuseness_m_index == max_diffuseness_m_index ) /* all values are equal */
    1779             :         {
    1780      907236 :             push_next_indice( hMetaData, 0, 1 );                                                             /* dif_use_raw_coding */
    1781      907236 :             push_next_indice( hMetaData, 1, 1 );                                                             /* dif_have_unique_value */
    1782      907236 :             ivas_qmetadata_encode_quasi_uniform( hMetaData, min_diffuseness_m_index, DIRAC_DIFFUSE_LEVELS ); /* dif_unique_value */
    1783             :         }
    1784     2400560 :         else if ( min_diffuseness_m_index + 1 == max_diffuseness_m_index ) /* only two consecutive values are present */
    1785             :         {
    1786      777637 :             push_next_indice( hMetaData, 0, 1 );                                                                 /* dif_use_raw_coding */
    1787      777637 :             push_next_indice( hMetaData, 0, 1 );                                                                 /* dif_have_unique_value */
    1788      777637 :             ivas_qmetadata_encode_quasi_uniform( hMetaData, min_diffuseness_m_index, DIRAC_DIFFUSE_LEVELS - 1 ); /* dif_min_value */
    1789             : 
    1790     3340401 :             for ( b = start_band; b < nbands; b++ )
    1791             :             {
    1792     2562764 :                 push_next_indice( hMetaData, q_direction->band_data[b].energy_ratio_index[0] - min_diffuseness_m_index, 1 ); /* dif_bit_offset_values */
    1793             :             }
    1794             :         }
    1795             :         else /* raw coding */
    1796             :         {
    1797     1622923 :             push_next_indice( hMetaData, 1, 1 ); /* dif_use_raw_coding */
    1798             : 
    1799     7499529 :             for ( b = start_band; b < nbands; b++ )
    1800             :             {
    1801     5876606 :                 ivas_qmetadata_encode_quasi_uniform( hMetaData, q_direction->band_data[b].energy_ratio_index[0], DIRAC_DIFFUSE_LEVELS ); /* dif_values */
    1802             :             }
    1803             :         }
    1804             :     }
    1805             :     else
    1806             :     {
    1807             :         /* Use Huffman-coding approach or raw coding when there is a high number of bands. */
    1808             :         int16_t diffuseness_bits_huff;
    1809             :         int16_t best_av;
    1810             :         uint16_t avr_idx[MASA_MAXIMUM_CODING_SUBBANDS];
    1811             : 
    1812             :         /* First, obtain average indices and bit usage for Huffman-coding. */
    1813      574359 :         ivas_diffuseness_huff_ec_prepare( q_direction, &best_av, avr_idx, &diffuseness_bits_huff );
    1814             : 
    1815             :         /* If there is benefit, use Huffman-coding. Otherwise, use raw coding. */
    1816      574359 :         if ( diffuseness_bits_huff < diffuseness_bits_raw )
    1817             :         {
    1818             :             /* Signal Huffman EC */
    1819      388649 :             push_next_indice( hMetaData, 0, 1 );
    1820      388649 :             push_next_indice( hMetaData, best_av, MASA_BITS_ER );
    1821     5610793 :             for ( b = start_band; b < nbands; b++ )
    1822             :             {
    1823     5222144 :                 ivas_diffuseness_huff_ec_encode( hMetaData, avr_idx[b] );
    1824             :             }
    1825             : #ifdef DEBUGGING
    1826             :             assert( ( hMetaData->nb_bits_tot - start_bit_pos ) == diffuseness_bits_huff + 1 );
    1827             : #endif
    1828             :         }
    1829             :         else
    1830             :         {
    1831             :             /* Signal raw */
    1832      185710 :             push_next_indice( hMetaData, 1, 1 );
    1833     2583457 :             for ( b = start_band; b < nbands; b++ )
    1834             :             {
    1835     2397747 :                 ivas_qmetadata_encode_quasi_uniform( hMetaData, q_direction->band_data[b].energy_ratio_index[0], DIRAC_DIFFUSE_LEVELS ); /* dif_values */
    1836             :             }
    1837             :         }
    1838             :     }
    1839             : 
    1840     3882155 :     *diffuseness_index_max_ec_frame = 5;
    1841             :     /* adaptively select the diffuseness_index_max_ec threshold */
    1842     3882155 :     if ( min_diffuseness_m_index > 5 )
    1843             :     {
    1844     1310555 :         *diffuseness_index_max_ec_frame = DIRAC_DIFFUSE_LEVELS - 1;
    1845             :     }
    1846             : 
    1847             : #ifdef DEBUGGING
    1848             :     assert( ( hMetaData->nb_bits_tot - start_bit_pos ) <= 1 + diffuseness_bits_raw );
    1849             : #endif
    1850             : 
    1851     3882155 :     return ( hMetaData->nb_bits_tot - start_bit_pos );
    1852             : }
    1853             : 
    1854             : 
    1855             : /*-------------------------------------------------------------------------
    1856             :  * ivas_qmetadata_entropy_encode_df_ratio()
    1857             :  *
    1858             :  * encode dfRatio
    1859             :  *------------------------------------------------------------------------*/
    1860             : 
    1861      373885 : static int16_t ivas_qmetadata_entropy_encode_df_ratio(
    1862             :     BSTR_ENC_HANDLE hMetaData,
    1863             :     IVAS_QDIRECTION *q_direction,
    1864             :     int16_t *df_ratio_bits )
    1865             : {
    1866             :     int16_t start_bit_pos;
    1867             :     int16_t bits_raw;
    1868             :     int16_t b;
    1869             :     int16_t min_index, max_index;
    1870             :     int16_t nbands, start_band;
    1871             :     int16_t max_df_ratio_bits;
    1872      373885 :     int16_t ec_mode = 0;
    1873             :     int16_t max_alphabet_size;
    1874             : 
    1875      373885 :     nbands = q_direction->cfg.nbands;
    1876      373885 :     start_band = q_direction->cfg.start_band;
    1877             : 
    1878      373885 :     start_bit_pos = hMetaData->nb_bits_tot;
    1879             : 
    1880      373885 :     if ( nbands == 1 )
    1881             :     {
    1882             :         /* If there is only one band, ratio should be coded directly as raw with no signaling. */
    1883       55559 :         push_next_indice( hMetaData, q_direction->band_data[0].energy_ratio_index[0], df_ratio_bits[0] );
    1884             : 
    1885       55559 :         return ( hMetaData->nb_bits_tot - start_bit_pos );
    1886             :     }
    1887             : 
    1888             :     /* compute the number of raw coding bits */
    1889      318326 :     bits_raw = 0;
    1890      318326 :     max_df_ratio_bits = 0;
    1891     2971919 :     for ( b = start_band; b < nbands; b++ )
    1892             :     {
    1893     2653593 :         bits_raw += df_ratio_bits[b];
    1894     2653593 :         max_df_ratio_bits = max( df_ratio_bits[b], max_df_ratio_bits );
    1895             :     }
    1896             : 
    1897      318326 :     min_index = q_direction->band_data[start_band].energy_ratio_index[0];
    1898      318326 :     max_index = q_direction->band_data[start_band].energy_ratio_index[0];
    1899     2971919 :     for ( b = start_band; b < nbands; b++ )
    1900             :     {
    1901     2653593 :         if ( q_direction->band_data[b].energy_ratio_index[0] < min_index )
    1902             :         {
    1903      212379 :             min_index = q_direction->band_data[b].energy_ratio_index[0];
    1904             :         }
    1905             : 
    1906     2653593 :         if ( q_direction->band_data[b].energy_ratio_index[0] > max_index )
    1907             :         {
    1908      274109 :             max_index = q_direction->band_data[b].energy_ratio_index[0];
    1909             :         }
    1910             :     }
    1911             : 
    1912             :     /* Decide what modes are possible */
    1913      318326 :     if ( bits_raw >= max_df_ratio_bits + 2 + nbands )
    1914             :     {
    1915      193974 :         ec_mode = 2;
    1916             :     }
    1917      124352 :     else if ( bits_raw >= max_df_ratio_bits + 1 )
    1918             :     {
    1919      124352 :         ec_mode = 1;
    1920             :     }
    1921             :     else
    1922             :     {
    1923           0 :         ec_mode = 0;
    1924             :     }
    1925      318326 :     max_alphabet_size = 1 << max_df_ratio_bits;
    1926             : 
    1927      318326 :     if ( min_index == max_index && ec_mode > 0 ) /* all values are equal */
    1928             :     {
    1929       41611 :         push_next_indice( hMetaData, 0, 1 ); /* Signal between EC and raw */
    1930       41611 :         if ( ec_mode > 1 )
    1931             :         {
    1932             :             /* Only use bit for signaling if necessary */
    1933       12628 :             push_next_indice( hMetaData, 0, 1 ); /* Signal between one value or bandwise diff mode */
    1934             :         }
    1935             : 
    1936       41611 :         ivas_qmetadata_encode_quasi_uniform( hMetaData, min_index, max_alphabet_size );
    1937             :     }
    1938      276715 :     else if ( min_index + 1 == max_index && ec_mode > 1 ) /* only two consecutive values are present */
    1939             :     {
    1940       34423 :         push_next_indice( hMetaData, 0, 1 );
    1941       34423 :         push_next_indice( hMetaData, 1, 1 );
    1942       34423 :         ivas_qmetadata_encode_quasi_uniform( hMetaData, min_index, max_alphabet_size - 1 );
    1943             : 
    1944      275997 :         for ( b = start_band; b < nbands; b++ )
    1945             :         {
    1946      241574 :             push_next_indice( hMetaData, q_direction->band_data[b].energy_ratio_index[0] - min_index, 1 ); /* Band-wise offset values */
    1947             :         }
    1948             :     }
    1949             :     else /* raw coding */
    1950             :     {
    1951      242292 :         if ( ec_mode > 0 )
    1952             :         {
    1953      242292 :             push_next_indice( hMetaData, 1, 1 ); /* Only signal raw mode if not implicitly using it */
    1954             :         }
    1955             : 
    1956     2487925 :         for ( b = start_band; b < nbands; b++ )
    1957             :         {
    1958     2245633 :             ivas_qmetadata_encode_quasi_uniform( hMetaData, q_direction->band_data[b].energy_ratio_index[0], 1 << df_ratio_bits[b] ); /* dif_values */
    1959             :         }
    1960             :     }
    1961             : 
    1962      318326 :     return ( hMetaData->nb_bits_tot - start_bit_pos );
    1963             : }
    1964             : 
    1965             : 
    1966             : /*-------------------------------------------------------------------------
    1967             :  * restore_metadata_buffer()
    1968             :  *
    1969             :  * Restore metadata buffer
    1970             :  *------------------------------------------------------------------------*/
    1971             : 
    1972     4567952 : void restore_metadata_buffer(
    1973             :     BSTR_ENC_HANDLE hMetaData,
    1974             :     const int16_t next_ind_start,
    1975             :     const int16_t bit_pos_start )
    1976             : {
    1977             :     int16_t i;
    1978             : 
    1979   225507830 :     for ( i = next_ind_start; i < hMetaData->nb_ind_tot; i++ )
    1980             :     {
    1981   220939878 :         hMetaData->ind_list[i].nb_bits = -1;
    1982             : #if defined( DEBUGGING ) && defined( DBG_BITSTREAM_ANALYSIS )
    1983             :         sprintf( hMetaData->ind_list[i].function_name, "RESET in restore_metadata_buffer" );
    1984             : #endif
    1985             :     }
    1986     4567952 :     hMetaData->nb_bits_tot = bit_pos_start;
    1987     4567952 :     hMetaData->nb_ind_tot = next_ind_start;
    1988             : 
    1989     4567952 :     return;
    1990             : }
    1991             : 
    1992             : 
    1993             : /*-------------------------------------------------------------------------
    1994             :  * ivas_qmetadata_encode_quasi_uniform()
    1995             :  *
    1996             :  * encode value using a quasi-uniform code of b or b + 1 bits, where b = floor(log2(alphabet_size))
    1997             :  *------------------------------------------------------------------------*/
    1998             : 
    1999    34019597 : static void ivas_qmetadata_encode_quasi_uniform(
    2000             :     BSTR_ENC_HANDLE hMetaData,
    2001             :     const uint16_t value,
    2002             :     const uint16_t alphabet_size )
    2003             : {
    2004             :     int16_t bits;
    2005             :     uint16_t tresh;
    2006             : #ifdef DEBUGGING
    2007             :     assert( ( alphabet_size >= 1 ) );
    2008             :     assert( value < alphabet_size );
    2009             : #endif
    2010             : 
    2011    34019597 :     bits = 30 - norm_l( alphabet_size ); /* bits = floor(log2(alphabet_size)) */
    2012    34019597 :     tresh = ( 1U << ( bits + 1 ) ) - alphabet_size;
    2013             : 
    2014    34019597 :     if ( value < tresh )
    2015             :     {
    2016    28449894 :         push_next_indice( hMetaData, value, bits );
    2017             :     }
    2018             :     else /* value >= tresh */
    2019             :     {
    2020     5569703 :         push_next_indice( hMetaData, value + tresh, bits + 1 );
    2021             :     }
    2022             : 
    2023    34019597 :     return;
    2024             : }
    2025             : 
    2026             : 
    2027             : /*-----------------------------------------------------------------------*
    2028             :  * GR encoder function definitions
    2029             :  *-----------------------------------------------------------------------*/
    2030             : /*-------------------------------------------------------------------------
    2031             :  * GR_bits_new()
    2032             :  *
    2033             :  *
    2034             :  *------------------------------------------------------------------------*/
    2035             : 
    2036             : /*! r: number of bits using Golomb Rice code */
    2037     3103879 : static int16_t GR_bits_new(
    2038             :     uint16_t *data,                 /* i  : data to encode with GR              */
    2039             :     int16_t *no_symb,               /* i  : number of symbols for each component*/
    2040             :     const int16_t no_data,          /* i  : number of input data                */
    2041             :     const int16_t GR_order,         /* i  : GR order to be used                 */
    2042             :     const int16_t check_two_orders, /* i  : check also coding with GR_order-1   */
    2043             :     int16_t *real_GR_ord            /* o  : the GR order that has been used     */
    2044             : )
    2045             : {
    2046     3103879 :     int16_t nbits = 0, i;
    2047     3103879 :     int16_t nbits1 = 0;
    2048             :     int16_t nb;
    2049             : 
    2050    28330081 :     for ( i = 0; i < no_data; i++ )
    2051             :     {
    2052    25226202 :         nb = ivas_qmetadata_encode_extended_gr_length( data[i], no_symb[i], GR_order );
    2053    25226202 :         nbits += nb;
    2054             :     }
    2055             : 
    2056     3103879 :     if ( check_two_orders == 1 )
    2057             :     {
    2058    23795165 :         for ( i = 0; i < no_data; i++ )
    2059             :         {
    2060    21268989 :             nb = ivas_qmetadata_encode_extended_gr_length( data[i], no_symb[i], GR_order - 1 );
    2061    21268989 :             nbits1 += nb;
    2062             :         }
    2063             : 
    2064     2526176 :         if ( nbits1 < nbits )
    2065             :         {
    2066     1494328 :             nbits = nbits1 + 1;
    2067     1494328 :             *real_GR_ord = GR_order - 1;
    2068             :         }
    2069             :         else
    2070             :         {
    2071     1031848 :             nbits += 1;
    2072     1031848 :             *real_GR_ord = GR_order;
    2073             :         }
    2074             :     }
    2075             :     else
    2076             :     {
    2077      577703 :         *real_GR_ord = GR_order;
    2078             :     }
    2079             : 
    2080     3103879 :     return nbits;
    2081             : }
    2082             : 
    2083             : 
    2084             : /*-------------------------------------------------------------------------
    2085             :  * GR_bits_azimuth_context()
    2086             :  *
    2087             :  * Encoding azimuth indexes with GR code using context
    2088             :  *------------------------------------------------------------------------*/
    2089             : 
    2090             : /*! r: numer of bits used for coding */
    2091      389869 : static int16_t GR_bits_azimuth_context(
    2092             :     uint16_t *data_in,        /* i  : data to be encoded                                */
    2093             :     int16_t *no_symb,         /* i  : number of symbols for each component              */
    2094             :     const int16_t no_data_in, /* i  : number of input data                              */
    2095             :     const int16_t GR_order,   /* i  : GR order (GR_order or GR_order-1 are used )       */
    2096             :     const uint16_t *bits_dir, /* i  : bits for encoding the direction for each TF tile  */
    2097             :     int16_t *real_GR_ord,     /* o  : which GR order has been used                      */
    2098             :     int16_t *p_use_context    /* o  : flag telling if context has been used or not      */
    2099             : )
    2100             : {
    2101             :     int16_t i, nbits, nbits1, use_context;
    2102             :     uint16_t cdata[MAX_PARAM_SPATIAL_SUBFRAMES];
    2103             :     uint16_t data[MAX_PARAM_SPATIAL_SUBFRAMES];
    2104             :     int16_t min_val, max_val;
    2105             :     int16_t real_GR_ord1;
    2106             :     int16_t no_symb_local[MAX_PARAM_SPATIAL_SUBFRAMES];
    2107      389869 :     int16_t no_data = 0;
    2108             : #ifdef FIX_FLOAT_1522_LTV_MSAN_QMETADATA_ENC_EC3
    2109             : 
    2110      389869 :     *real_GR_ord = GR_order; /* Init to avoid sanitizer warnings */
    2111             : #endif
    2112             : 
    2113     1548341 :     for ( i = 0; i < no_data_in; i++ )
    2114             :     {
    2115     1158472 :         if ( data_in[i] < MASA_NO_INDEX )
    2116             :         {
    2117     1156436 :             no_symb_local[no_data] = no_symb[i];
    2118     1156436 :             data[no_data++] = data_in[i];
    2119             :         }
    2120             :     }
    2121             : 
    2122      389869 :     if ( no_data == 0 )
    2123             :     {
    2124         300 :         *p_use_context = -3; /* corresponding to nothing to be written */
    2125         300 :         return 0;
    2126             :     }
    2127             : 
    2128      389569 :     nbits = 0;
    2129      389569 :     use_context = 0;
    2130             : 
    2131     1546005 :     for ( i = 0; i < no_data; i++ )
    2132             :     {
    2133     1156436 :         if ( ( bits_dir[i] <= 1 ) )
    2134             :         {
    2135           4 :             nbits += bits_dir[i];
    2136           4 :             use_context = 1;
    2137             :         }
    2138             :         else
    2139             :         {
    2140     1156432 :             *real_GR_ord = GR_order - ( bits_dir[i] == 2 );
    2141     1156432 :             nbits += ivas_qmetadata_encode_extended_gr_length( data[i], no_symb_local[i], *real_GR_ord );
    2142             :         }
    2143             :     }
    2144             : 
    2145      389569 :     real_GR_ord1 = 0;
    2146      389569 :     if ( use_context == 0 )
    2147             :     {
    2148      389565 :         nbits = GR_bits_new( data, no_symb_local, no_data, GR_order, 1, real_GR_ord );
    2149      389565 :         nbits1 = nbits;
    2150             : 
    2151      389565 :         min_val = data[0];
    2152     1156420 :         for ( i = 1; i < no_data; i++ )
    2153             :         {
    2154      766855 :             if ( data[i] < min_val )
    2155             :             {
    2156      111095 :                 min_val = data[i];
    2157             :             }
    2158             :         }
    2159     1545985 :         for ( i = 0; i < no_data; i++ )
    2160             :         {
    2161     1156420 :             cdata[i] = data[i] - min_val;
    2162             :         }
    2163             : 
    2164      389565 :         maximum_s( no_symb_local, no_data, &max_val );
    2165      389565 :         nbits1 = GR_bits_new( cdata, no_symb_local, no_data, GR_order - 1, 1, &real_GR_ord1 ) + ivas_qmetadata_encode_extended_gr_length( min_val, max_val, MASA_GR_ORD_AZ );
    2166             : 
    2167      389565 :         if ( nbits1 < nbits )
    2168             :         {
    2169      123389 :             nbits = nbits1 + 1;
    2170      123389 :             use_context = -2;
    2171      123389 :             *real_GR_ord = real_GR_ord1;
    2172             :         }
    2173             :         else
    2174             :         {
    2175      266176 :             nbits = nbits + 1;
    2176      266176 :             use_context = -1;
    2177             :         }
    2178             :     }
    2179             : 
    2180      389569 :     *p_use_context = use_context;
    2181             : 
    2182      389569 :     return nbits;
    2183             : }
    2184             : 
    2185             : 
    2186             : /*-------------------------------------------------------------------------
    2187             :  * mean_removed_GR_new()
    2188             :  *
    2189             :  * Golomb Rice encoding with mean removing
    2190             :  *------------------------------------------------------------------------*/
    2191             : 
    2192             : /*! r: number of bits used */
    2193      841195 : static int16_t mean_removed_GR_new(
    2194             :     const uint16_t *idx, /* i  : data to encode */
    2195             :     const int16_t max_no_symb,
    2196             :     const int16_t len,      /* i  : number of data                                      */
    2197             :     const int16_t adapt_GR, /* i  : flag for telling to use or nor two GR order values  */
    2198             :     int16_t *GR_ord,        /* i/o: GR order                                            */
    2199             :     uint16_t *p_av,         /* o  : average index                                       */
    2200             :     uint16_t *mr_idx        /* o  : mean removed indexes                                */
    2201             : )
    2202             : {
    2203             :     int16_t av, i, nbits;
    2204             :     int16_t sh_idx[MASA_MAXIMUM_CODING_SUBBANDS];
    2205             :     int16_t max_ns[MASA_MAXIMUM_CODING_SUBBANDS];
    2206             : 
    2207      841195 :     av = (int16_t) ( 0.5f + sum_s( (const int16_t *) idx, len ) / (float) len );
    2208      841195 :     *p_av = av;
    2209    10206268 :     for ( i = 0; i < len; i++ )
    2210             :     {
    2211     9365073 :         max_ns[i] = 2 * ( max_no_symb );
    2212     9365073 :         sh_idx[i] = idx[i] - av;
    2213             :     }
    2214             : 
    2215    10206268 :     for ( i = 0; i < len; i++ )
    2216             :     {
    2217     9365073 :         if ( sh_idx[i] < 0 )
    2218             :         {
    2219     1680887 :             sh_idx[i] = -2 * sh_idx[i];
    2220             :         }
    2221     7684186 :         else if ( sh_idx[i] > 0 )
    2222             :         {
    2223     1521820 :             sh_idx[i] = sh_idx[i] * 2 - 1;
    2224             :         }
    2225             :         else
    2226             :         {
    2227     6162366 :             sh_idx[i] = 0;
    2228             :         }
    2229     9365073 :         mr_idx[i] = (uint16_t) sh_idx[i];
    2230             :     }
    2231             : 
    2232      841195 :     nbits = GR_bits_new( mr_idx, max_ns, len, *GR_ord, adapt_GR, GR_ord );
    2233             : 
    2234      841195 :     return nbits;
    2235             : }
    2236             : 
    2237             : 
    2238             : /*-------------------------------------------------------------------------
    2239             :  * ivas_qmetadata_encode_quasi_uniform_length()
    2240             :  *
    2241             :  *------------------------------------------------------------------------*/
    2242             : 
    2243   166538300 : static int16_t ivas_qmetadata_encode_quasi_uniform_length(
    2244             :     const uint16_t value,
    2245             :     const uint16_t alphabet_size )
    2246             : {
    2247             :     int16_t bits;
    2248             :     uint16_t tresh;
    2249             : #ifdef DEBUGGING
    2250             :     assert( ( alphabet_size >= 1 ) );
    2251             :     assert( value < alphabet_size );
    2252             : #endif
    2253             : 
    2254   166538300 :     bits = 30 - norm_l( alphabet_size ); /* bits = floor(log2(alphabet_size)) */
    2255   166538300 :     tresh = ( 1U << ( bits + 1 ) ) - alphabet_size;
    2256             : 
    2257   166538300 :     if ( value >= tresh )
    2258             :     {
    2259    40211288 :         bits++;
    2260             :     }
    2261             : 
    2262   166538300 :     return bits;
    2263             : }
    2264             : 
    2265             : 
    2266             : /*-------------------------------------------------------------------------
    2267             :  * ivas_qmetadata_entropy_encode_dir()
    2268             :  *
    2269             :  * Main function for entropy coding of the directions
    2270             :  *------------------------------------------------------------------------*/
    2271             : 
    2272     4997278 : static int16_t ivas_qmetadata_entropy_encode_dir(
    2273             :     BSTR_ENC_HANDLE hMetaData,
    2274             :     IVAS_QDIRECTION *q_direction,
    2275             :     const uint16_t diffuseness_index_max_ec_frame,
    2276             :     const int16_t nbands,
    2277             :     const int16_t start_band,
    2278             :     const int16_t direction_bits_raw,
    2279             :     int16_t max_bits,
    2280             :     const int16_t hrmasa_flag )
    2281             : {
    2282             :     uint16_t diff_idx_min;
    2283             :     int16_t i, j;
    2284             :     int16_t nblocks;
    2285             : 
    2286             :     float avg_direction_vector[3], direction_vector[3], avg_azimuth, avg_elevation;
    2287             :     int16_t avg_azimuth_alphabet, avg_elevation_alphabet;
    2288             :     uint16_t avg_azimuth_index, avg_elevation_index;
    2289             :     int16_t avg_elevation_index_projected;
    2290             :     int16_t avg_azimuth_index_projected;
    2291             :     uint16_t avg_elevation_index_initial, avg_elevation_offset;
    2292             :     uint16_t avg_azimuth_index_initial, avg_azimuth_offset;
    2293             :     int16_t elevation_bits_ec_best, azimuth_bits_ec_best;
    2294             : 
    2295     4997278 :     int16_t gr_param_elevation_best = 0, avg_elevation_index_best = 0;
    2296             :     uint16_t dist_elevation_indexes_best[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_MAXIMUM_CODING_SUBBANDS];
    2297             :     int16_t gr_param_azimuth_best, avg_azimuth_index_best;
    2298             :     uint16_t dist_azimuth_indexes_best[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_MAXIMUM_CODING_SUBBANDS];
    2299             : 
    2300             :     uint16_t idx, dist_count;
    2301             :     int16_t direction_bits_ec;
    2302             : 
    2303             :     uint16_t dist_elevation_indexes[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_MAXIMUM_CODING_SUBBANDS];
    2304             :     uint16_t dist_elevation_alphabets[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_MAXIMUM_CODING_SUBBANDS];
    2305             :     uint16_t dist_azimuth_indexes[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_MAXIMUM_CODING_SUBBANDS];
    2306             :     uint16_t dist_azimuth_alphabets[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_MAXIMUM_CODING_SUBBANDS];
    2307     4997278 :     int16_t all_zero_dist_elevation_indexes = 1, all_zero_dist_azimuth_indexes = 1;
    2308             :     int16_t gr_param_elevation, gr_size_elevation, egr_size_elevation, gr_param_azimuth, gr_size_azimuth;
    2309             :     int16_t egr_size_azimuth, elevation_bits_ec, azimuth_bits_ec;
    2310             : 
    2311             :     float abs_theta;
    2312             :     float theta_cb[MAX_NO_THETA];
    2313             :     int16_t sign_th, no_th;
    2314     4997278 :     int16_t avg_azimuth_index_upd = 0, use_adapt_avg;
    2315     4997278 :     int16_t make_gain = 0;
    2316     4997278 :     int16_t bits_gained = 0;
    2317     4997278 :     nblocks = q_direction->cfg.nblocks;
    2318             : 
    2319             :     /* estimate the number of bits for entropy coding of the direction values */
    2320     4997278 :     direction_bits_ec = 0;
    2321     4997278 :     diff_idx_min = DIRAC_DIFFUSE_LEVELS;
    2322     4997278 :     idx = 0;
    2323     4997278 :     dist_count = 0;
    2324     4997278 :     set_zero( avg_direction_vector, 3 );
    2325             : 
    2326    27353524 :     for ( i = start_band; i < nbands; i++ )
    2327             :     {
    2328    22356246 :         if ( hrmasa_flag )
    2329             :         {
    2330           0 :             diff_idx_min = 0; // min( q_direction->band_data[i].energy_ratio_index_mod[0]>>1, diff_idx_min );
    2331             :         }
    2332             :         else
    2333             :         {
    2334    22356246 :             diff_idx_min = min( q_direction->band_data[i].energy_ratio_index_mod[0], diff_idx_min );
    2335             :         }
    2336             : 
    2337    22356246 :         if ( q_direction->band_data[i].energy_ratio_index_mod[0] > diffuseness_index_max_ec_frame )
    2338             :         {
    2339             :             /* estimate the raw part  */
    2340     5845019 :             if ( q_direction->not_in_2D > 0 )
    2341             :             {
    2342    20605286 :                 for ( j = 0; j < nblocks; j++ )
    2343             :                 {
    2344    15606919 :                     direction_bits_ec += q_direction->band_data[i].bits_sph_idx[j];
    2345             :                 }
    2346             :             }
    2347             :             else
    2348             :             {
    2349     3048404 :                 for ( j = 0; j < nblocks; j++ )
    2350             :                 {
    2351     2201752 :                     direction_bits_ec += ivas_qmetadata_encode_quasi_uniform_length( q_direction->band_data[i].azimuth_index[j], q_direction->band_data[i].azimuth_m_alphabet[j] );
    2352             :                 }
    2353             :             }
    2354             :         }
    2355             :         else
    2356             :         {
    2357    16511227 :             dist_count += nblocks;
    2358             : 
    2359    69251081 :             for ( j = 0; j < nblocks; j++ )
    2360             :             {
    2361             :                 /*compute the average direction */
    2362    52739854 :                 ivas_qmetadata_azimuth_elevation_to_direction_vector( q_direction->band_data[i].azimuth[j], q_direction->band_data[i].elevation[j], direction_vector );
    2363    52739854 :                 v_add( avg_direction_vector, direction_vector, avg_direction_vector, 3 );
    2364             :             }
    2365             :         }
    2366             :     }
    2367             : 
    2368             :     /* quantize average elevation and azimuth angles using the best angle spacing and equatorial precision */
    2369     4997278 :     ivas_qmetadata_direction_vector_to_azimuth_elevation( avg_direction_vector, &avg_azimuth, &avg_elevation );
    2370             : 
    2371     4997278 :     if ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID )
    2372             :     {
    2373      357036 :         avg_elevation_alphabet = no_theta_masa[bits_direction_masa[diff_idx_min] - 3];
    2374      357036 :         avg_azimuth_alphabet = no_phi_masa[bits_direction_masa[diff_idx_min] - 1][0]; /* average azimuth is quantized on the equatorial plane */
    2375             :     }
    2376             :     else
    2377             :     {
    2378     4640242 :         avg_elevation_alphabet = no_theta_masa[bits_direction_masa[diff_idx_min] - 3] * 2 - 1;
    2379     4640242 :         avg_azimuth_alphabet = no_phi_masa[bits_direction_masa[diff_idx_min] - 1][0]; /* average azimuth is quantized on the equatorial plane */
    2380             :     }
    2381             : 
    2382     4997278 :     no_th = no_theta_masa[bits_direction_masa[diff_idx_min] - 3];
    2383             : 
    2384    49796878 :     for ( i = 0; i < no_th; i++ )
    2385             :     {
    2386    44799600 :         theta_cb[i] = i * delta_theta_masa[bits_direction_masa[diff_idx_min] - 3];
    2387             :     }
    2388             : 
    2389     4997278 :     if ( theta_cb[i - 1] > 90 )
    2390             :     {
    2391     2646205 :         theta_cb[i - 1] = 90;
    2392             :     }
    2393             : 
    2394     4997278 :     if ( avg_elevation < 0 )
    2395             :     {
    2396     1317947 :         abs_theta = -avg_elevation;
    2397     1317947 :         sign_th = -1;
    2398             :     }
    2399             :     else
    2400             :     {
    2401     3679331 :         abs_theta = avg_elevation;
    2402     3679331 :         sign_th = 1;
    2403             :     }
    2404             : 
    2405     4997278 :     avg_elevation_index = squant( abs_theta, &avg_elevation, theta_cb, no_th );
    2406             : 
    2407     4997278 :     if ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID )
    2408             :     {
    2409      357036 :         assert( avg_elevation >= 0 );
    2410             :     }
    2411             :     else
    2412             :     {
    2413     4640242 :         if ( sign_th < 0 )
    2414             :         {
    2415     1317947 :             avg_elevation_index = ( avg_elevation_alphabet >> 1 ) - avg_elevation_index;
    2416             :         }
    2417             :         else
    2418             :         {
    2419     3322295 :             avg_elevation_index += ( avg_elevation_alphabet >> 1 );
    2420             :         }
    2421     4640242 :         avg_elevation *= sign_th;
    2422             :     }
    2423             : 
    2424     4997278 :     avg_azimuth_index = (uint16_t) ( quantize_phi( avg_azimuth + 180, 0, &avg_azimuth, avg_azimuth_alphabet ) );
    2425             : 
    2426             :     /* Elevation only if not 2D */
    2427     4997278 :     if ( q_direction->not_in_2D > 0 )
    2428             :     {
    2429     4119112 :         avg_elevation_index_initial = avg_elevation_index;
    2430     4119112 :         elevation_bits_ec_best = MAX16B;
    2431     4119112 :         avg_elevation_index_best = -1; /* out of range value */
    2432     4119112 :         gr_param_elevation_best = -1;  /* out of range value */
    2433             : 
    2434    16476448 :         for ( avg_elevation_offset = 0; avg_elevation_offset < q_direction->cfg.search_effort; avg_elevation_offset++ )
    2435             :         {
    2436    12357336 :             if ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID )
    2437             :             {
    2438      721914 :                 avg_elevation_index = avg_elevation_index_initial + avg_elevation_offset;
    2439             :             }
    2440             :             else
    2441             :             {
    2442    11635422 :                 avg_elevation_index = (uint16_t) ( avg_elevation_index_initial + ivas_qmetadata_dereorder_generic( avg_elevation_offset ) );
    2443             :             }
    2444    12357336 :             avg_elevation_index = (uint16_t) ( ( avg_elevation_index + avg_elevation_alphabet ) % avg_elevation_alphabet );
    2445             : 
    2446    12357336 :             all_zero_dist_elevation_indexes = 1;
    2447    12357336 :             if ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID )
    2448             :             {
    2449      721914 :                 elevation_bits_ec = ivas_qmetadata_encode_quasi_uniform_length( avg_elevation_index, avg_elevation_alphabet );
    2450             :             }
    2451             :             else
    2452             :             {
    2453    11635422 :                 elevation_bits_ec = ivas_qmetadata_encode_quasi_uniform_length( ivas_qmetadata_reorder_generic( avg_elevation_index - ( avg_elevation_alphabet >> 1 ) ), avg_elevation_alphabet );
    2454             :             }
    2455    12357336 :             idx = 0;
    2456    65825748 :             for ( i = start_band; i < nbands; i++ )
    2457             :             {
    2458    53468412 :                 if ( q_direction->band_data[i].energy_ratio_index_mod[0] <= diffuseness_index_max_ec_frame )
    2459             :                 {
    2460   167999982 :                     for ( j = 0; j < nblocks; j++ )
    2461             :                     {
    2462             :                         /* project the quantized average elevation to the same grid as the current sample */
    2463   129526671 :                         if ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID )
    2464             :                         {
    2465     4118157 :                             avg_elevation_index_projected = ivas_chan_project_elevation_index( avg_elevation_index, avg_elevation_alphabet, q_direction->band_data[i].elevation_m_alphabet[j] );
    2466             :                         }
    2467             :                         else
    2468             :                         {
    2469   125408514 :                             avg_elevation_index_projected = ivas_dirac_project_elevation_index( avg_elevation_index, avg_elevation_alphabet, q_direction->band_data[i].elevation_m_alphabet[j] );
    2470             :                         }
    2471             : #ifdef DEBUGGING
    2472             :                         assert( ( 0 <= avg_elevation_index_projected ) && ( avg_elevation_index_projected < q_direction->band_data[i].elevation_m_alphabet[j] ) );
    2473             : #endif
    2474             : 
    2475   129526671 :                         if ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID )
    2476             :                         {
    2477     4118157 :                             if ( q_direction->band_data[i].elevation_index[j] - avg_elevation_index_projected > 0 )
    2478             :                             {
    2479      400001 :                                 dist_elevation_indexes[idx] = 2 * ( q_direction->band_data[i].elevation_index[j] - avg_elevation_index_projected ) - 1;
    2480             :                             }
    2481             :                             else
    2482             :                             {
    2483     3718156 :                                 dist_elevation_indexes[idx] = -2 * ( q_direction->band_data[i].elevation_index[j] - avg_elevation_index_projected );
    2484             :                             }
    2485             :                         }
    2486             :                         else
    2487             :                         {
    2488   125408514 :                             dist_elevation_indexes[idx] = ivas_qmetadata_reorder_elevation_index( q_direction->band_data[i].elevation_index[j], avg_elevation_index_projected, q_direction->band_data[i].elevation_m_alphabet[j] );
    2489             :                         }
    2490   129526671 :                         if ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID )
    2491             :                         {
    2492     4118157 :                             dist_elevation_alphabets[idx] = 2 * q_direction->band_data[i].elevation_m_alphabet[j] - 1;
    2493             :                         }
    2494             :                         else
    2495             :                         {
    2496   125408514 :                             dist_elevation_alphabets[idx] = q_direction->band_data[i].elevation_m_alphabet[j];
    2497             :                         }
    2498             : 
    2499   129526671 :                         if ( dist_elevation_indexes[idx] != 0 )
    2500             :                         {
    2501    83060209 :                             all_zero_dist_elevation_indexes = 0;
    2502             :                         }
    2503   129526671 :                         idx++;
    2504             :                     }
    2505             :                 }
    2506             :             }
    2507             : 
    2508    12357336 :             if ( all_zero_dist_elevation_indexes )
    2509             :             {
    2510     1371737 :                 egr_size_elevation = 0;
    2511     1371737 :                 gr_param_elevation = 4;
    2512             :             }
    2513             :             else
    2514             :             {
    2515    10985599 :                 gr_param_elevation = ivas_qmetadata_get_optimal_gr_param( dist_elevation_indexes, idx, 4, &gr_size_elevation );
    2516    10985599 :                 egr_size_elevation = 0;
    2517   137306891 :                 for ( i = 0; i < idx; i++ )
    2518             :                 {
    2519   126321292 :                     egr_size_elevation += ivas_qmetadata_encode_extended_gr_length( dist_elevation_indexes[i], dist_elevation_alphabets[i], gr_param_elevation );
    2520             :                 }
    2521             : #ifdef DEBUGGING
    2522             :                 assert( egr_size_elevation <= gr_size_elevation );
    2523             : #endif
    2524             :             }
    2525    12357336 :             elevation_bits_ec += ivas_qmetadata_encode_quasi_uniform_length( gr_param_elevation, 4 + 1 ) + egr_size_elevation;
    2526             : 
    2527    12357336 :             if ( elevation_bits_ec < elevation_bits_ec_best )
    2528             :             {
    2529     5293485 :                 elevation_bits_ec_best = elevation_bits_ec;
    2530     5293485 :                 avg_elevation_index_best = avg_elevation_index;
    2531     5293485 :                 gr_param_elevation_best = gr_param_elevation;
    2532    65532301 :                 for ( idx = 0; idx < dist_count; idx++ )
    2533             :                 {
    2534    60238816 :                     dist_elevation_indexes_best[idx] = dist_elevation_indexes[idx];
    2535             :                 }
    2536             :             }
    2537             :         }
    2538             : 
    2539     4119112 :         direction_bits_ec += elevation_bits_ec_best;
    2540             :     }
    2541             : 
    2542             :     /*Azimuth*/
    2543     4997278 :     use_adapt_avg = 0;
    2544     4997278 :     if ( ( nbands - start_band >= 5 ) && ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID ) && ( nblocks > 1 ) )
    2545             :     {
    2546       99527 :         use_adapt_avg = calc_var_azi( q_direction, diffuseness_index_max_ec_frame, avg_azimuth - 180, &avg_azimuth );
    2547       99527 :         avg_azimuth_index = (uint16_t) ( quantize_phi( avg_azimuth + 180, 0, &avg_azimuth, avg_azimuth_alphabet ) );
    2548             :     }
    2549     4997278 :     avg_azimuth_index_initial = avg_azimuth_index; /* avg_azimuth_index;*/
    2550     4997278 :     azimuth_bits_ec_best = MAX16B;
    2551     4997278 :     avg_azimuth_index_best = -1; /* out of range value */
    2552     4997278 :     gr_param_azimuth_best = -1;  /* out of range value */
    2553             : 
    2554    19989112 :     for ( avg_azimuth_offset = 0; avg_azimuth_offset < q_direction->cfg.search_effort; avg_azimuth_offset++ )
    2555             :     {
    2556    14991834 :         set_zero( avg_direction_vector, 3 );
    2557    14991834 :         avg_azimuth_index = (uint16_t) ( avg_azimuth_index_initial + ivas_qmetadata_dereorder_generic( avg_azimuth_offset ) );
    2558    14991834 :         avg_azimuth_index = (uint16_t) ( ( avg_azimuth_index + avg_azimuth_alphabet ) % avg_azimuth_alphabet );
    2559    14991834 :         all_zero_dist_azimuth_indexes = 1;
    2560    14991834 :         azimuth_bits_ec = ivas_qmetadata_encode_quasi_uniform_length( ivas_qmetadata_reorder_generic( avg_azimuth_index - ( avg_azimuth_alphabet >> 1 ) ), avg_azimuth_alphabet );
    2561             : 
    2562    14991834 :         idx = 0;
    2563    82060572 :         for ( i = start_band; i < nbands; i++ )
    2564             :         {
    2565    67068738 :             if ( q_direction->band_data[i].energy_ratio_index_mod[0] <= diffuseness_index_max_ec_frame )
    2566             :             {
    2567   207753243 :                 for ( j = 0; j < nblocks; j++ )
    2568             :                 {
    2569             : 
    2570   158219562 :                     if ( ( idx > MASA_LIMIT_IDX_AVG_AZI ) && ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID ) && ( use_adapt_avg == 1 ) )
    2571             :                     {
    2572     1728471 :                         avg_azimuth_index_projected = ivas_dirac_project_azimuth_index( avg_azimuth_index_upd, avg_azimuth_alphabet, q_direction->band_data[i].azimuth_m_alphabet[j] );
    2573             :                     }
    2574             :                     else
    2575             :                     {
    2576   156491091 :                         if ( ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID ) && ( use_adapt_avg == 1 ) )
    2577             :                         {
    2578     1096389 :                             ivas_qmetadata_azimuth_elevation_to_direction_vector( q_direction->band_data[i].azimuth[j], q_direction->band_data[i].elevation[j], direction_vector );
    2579     1096389 :                             if ( idx < 4 )
    2580             :                             {
    2581      913596 :                                 v_add( avg_direction_vector, direction_vector, avg_direction_vector, 3 );
    2582             :                             }
    2583             :                         }
    2584             :                         /* project the quantized average azimuth angle to the same grid as the current sample */
    2585   156491091 :                         avg_azimuth_index_projected = ivas_dirac_project_azimuth_index( avg_azimuth_index, avg_azimuth_alphabet, q_direction->band_data[i].azimuth_m_alphabet[j] );
    2586             :                     }
    2587             : #ifdef DEBUGGING
    2588             :                     assert( ( 0 <= avg_azimuth_index_projected ) && ( avg_azimuth_index_projected < q_direction->band_data[i].azimuth_m_alphabet[j] ) );
    2589             : #endif
    2590   158219562 :                     dist_azimuth_indexes[idx] = ivas_qmetadata_reorder_azimuth_index( ivas_qmetadata_dereorder_generic( q_direction->band_data[i].azimuth_index[j] ) + ( q_direction->band_data[i].azimuth_m_alphabet[j] >> 1 ), avg_azimuth_index_projected, q_direction->band_data[i].azimuth_m_alphabet[j] );
    2591   158219562 :                     dist_azimuth_alphabets[idx] = q_direction->band_data[i].azimuth_m_alphabet[j];
    2592             : 
    2593   158219562 :                     if ( dist_azimuth_indexes[idx] != 0 )
    2594             :                     {
    2595   110494970 :                         all_zero_dist_azimuth_indexes = 0;
    2596             :                     }
    2597             : 
    2598   158219562 :                     if ( ( idx >= MASA_LIMIT_IDX_AVG_AZI ) && ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID ) && ( use_adapt_avg == 1 ) )
    2599             :                     {
    2600     1911264 :                         if ( idx % nblocks == 0 )
    2601             :                         {
    2602      477816 :                             v_multc( avg_direction_vector, 0.5f, avg_direction_vector, 3 );
    2603             :                         }
    2604             : 
    2605             :                         /*compute the average direction per already coded subband */
    2606     1911264 :                         ivas_qmetadata_azimuth_elevation_to_direction_vector( q_direction->band_data[i].azimuth[j], q_direction->band_data[i].elevation[j], direction_vector );
    2607     1911264 :                         v_add( avg_direction_vector, direction_vector, avg_direction_vector, 3 );
    2608     1911264 :                         ivas_qmetadata_direction_vector_to_azimuth_elevation( avg_direction_vector, &avg_azimuth, &avg_elevation );
    2609     1911264 :                         avg_azimuth_index_upd = quantize_phi( avg_azimuth + 180, 0, &avg_azimuth, avg_azimuth_alphabet );
    2610             :                     }
    2611   158219562 :                     idx++;
    2612             :                 }
    2613             :             }
    2614             :         }
    2615             : 
    2616    14991834 :         if ( all_zero_dist_azimuth_indexes )
    2617             :         {
    2618     1715309 :             egr_size_azimuth = 0;
    2619     1715309 :             gr_param_azimuth = 5;
    2620             :         }
    2621             :         else
    2622             :         {
    2623             :             /* estimate the ExtendedGR part for azimuth */
    2624    13276525 :             gr_param_azimuth = ivas_qmetadata_get_optimal_gr_param( dist_azimuth_indexes, idx, 5, &gr_size_azimuth );
    2625    13276525 :             egr_size_azimuth = 0;
    2626   166132104 :             for ( i = 0; i < idx; i++ )
    2627             :             {
    2628   152855579 :                 egr_size_azimuth += ivas_qmetadata_encode_extended_gr_length( dist_azimuth_indexes[i], dist_azimuth_alphabets[i], gr_param_azimuth );
    2629             :             }
    2630             : #ifdef DEBUGGING
    2631             :             assert( egr_size_azimuth <= gr_size_azimuth );
    2632             : #endif
    2633             :         }
    2634             : 
    2635    14991834 :         azimuth_bits_ec += ivas_qmetadata_encode_quasi_uniform_length( gr_param_azimuth, 5 + 1 ) + egr_size_azimuth;
    2636             : 
    2637    14991834 :         if ( azimuth_bits_ec < azimuth_bits_ec_best )
    2638             :         {
    2639     6931276 :             azimuth_bits_ec_best = azimuth_bits_ec;
    2640     6931276 :             avg_azimuth_index_best = avg_azimuth_index;
    2641     6931276 :             gr_param_azimuth_best = gr_param_azimuth;
    2642             : 
    2643    84525639 :             for ( idx = 0; idx < dist_count; idx++ )
    2644             :             {
    2645    77594363 :                 dist_azimuth_indexes_best[idx] = dist_azimuth_indexes[idx];
    2646             :             }
    2647             :         }
    2648             :     }
    2649             : 
    2650     4997278 :     if ( ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID ) && ( dist_count > 4 ) && ( gr_param_azimuth_best != 5 ) && ( nblocks > 1 ) )
    2651             :     {
    2652       79352 :         azimuth_bits_ec_best += 1;
    2653             :     }
    2654             : 
    2655     4997278 :     direction_bits_ec += azimuth_bits_ec_best;
    2656             : 
    2657             :     /*Decision raw or EC*/
    2658             :     /* one bit is used to indicate whether the direction values are entropy coded or coded raw */
    2659     4997278 :     if ( direction_bits_ec < direction_bits_raw ) /* entropy coding is better */
    2660             :     {
    2661             : 
    2662             :         /* encode the raw part first */
    2663    17885509 :         for ( i = start_band; i < nbands; i++ )
    2664             :         {
    2665    14929756 :             if ( q_direction->band_data[i].energy_ratio_index_mod[0] > diffuseness_index_max_ec_frame )
    2666             :             {
    2667     3670186 :                 if ( q_direction->not_in_2D > 0 )
    2668             :                 {
    2669    14250313 :                     for ( j = 0; j < nblocks; j++ )
    2670             :                     {
    2671    11035781 :                         push_next_indice( hMetaData, q_direction->band_data[i].spherical_index[j], q_direction->band_data[i].bits_sph_idx[j] );
    2672             :                     }
    2673             :                 }
    2674             :                 else
    2675             :                 {
    2676     1883941 :                     for ( j = 0; j < nblocks; j++ )
    2677             :                     {
    2678     1428287 :                         ivas_qmetadata_encode_quasi_uniform( hMetaData, q_direction->band_data[i].azimuth_index[j], q_direction->band_data[i].azimuth_m_alphabet[j] );
    2679             :                     }
    2680             :                 }
    2681             :             }
    2682             :         }
    2683             : 
    2684     2955753 :         if ( nbands > 1 && direction_bits_ec - max_bits > 0 && direction_bits_ec - max_bits < nblocks * nbands )
    2685             :         {
    2686       54146 :             make_gain = 1;
    2687             :         }
    2688             : 
    2689     2955753 :         if ( q_direction->not_in_2D > 0 )
    2690             :         {
    2691             :             /* encode the ExtendedGR part for elevation */
    2692     2349322 :             if ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID )
    2693             :             {
    2694      124088 :                 ivas_qmetadata_encode_quasi_uniform( hMetaData, avg_elevation_index_best, avg_elevation_alphabet );
    2695             :             }
    2696             :             else
    2697             :             {
    2698     2225234 :                 ivas_qmetadata_encode_quasi_uniform( hMetaData, ivas_qmetadata_reorder_generic( avg_elevation_index_best - ( avg_elevation_alphabet >> 1 ) ), avg_elevation_alphabet );
    2699             :             }
    2700             : 
    2701     2349322 :             ivas_qmetadata_encode_quasi_uniform( hMetaData, gr_param_elevation_best, 4 + 1 );
    2702             : 
    2703     2349322 :             if ( gr_param_elevation_best != 4 ) /* not all zero */
    2704             :             {
    2705    27313432 :                 for ( idx = 0; idx < dist_count; idx++ )
    2706             :                 {
    2707    25550236 :                     ivas_qmetadata_encode_extended_gr( hMetaData, dist_elevation_indexes_best[idx], dist_elevation_alphabets[idx], gr_param_elevation_best );
    2708             :                 }
    2709             :             }
    2710             :         }
    2711             : 
    2712             :         /* encode the ExtendedGR part for azimuth */
    2713     2955753 :         ivas_qmetadata_encode_quasi_uniform( hMetaData, ivas_qmetadata_reorder_generic( avg_azimuth_index_best - ( avg_azimuth_alphabet >> 1 ) ), avg_azimuth_alphabet );
    2714             : 
    2715     2955753 :         ivas_qmetadata_encode_quasi_uniform( hMetaData, gr_param_azimuth_best, 5 + 1 );
    2716             : 
    2717     2955753 :         if ( gr_param_azimuth_best != 5 ) /* not all zero */
    2718             :         {
    2719    10757492 :             for ( idx = 0; idx < min( nblocks, dist_count ); idx++ )
    2720             :             {
    2721     8479561 :                 if ( make_gain == 1 && bits_gained < direction_bits_ec - max_bits && dist_azimuth_alphabets[idx] > 40 )
    2722             :                 {
    2723       44819 :                     if ( dist_azimuth_indexes_best[idx] > 1 )
    2724             :                     {
    2725       30224 :                         ivas_qmetadata_encode_extended_gr( hMetaData, dist_azimuth_indexes_best[idx] - 2, dist_azimuth_alphabets[idx], gr_param_azimuth_best );
    2726       30224 :                         bits_gained += ivas_qmetadata_encode_extended_gr_length( dist_azimuth_indexes_best[idx], dist_azimuth_alphabets[idx], gr_param_azimuth_best ) -
    2727       30224 :                                        ivas_qmetadata_encode_extended_gr_length( dist_azimuth_indexes_best[idx] - 2, dist_azimuth_alphabets[idx], gr_param_azimuth_best );
    2728             :                     }
    2729       14595 :                     else if ( dist_azimuth_indexes_best[idx] == 1 )
    2730             :                     {
    2731        5822 :                         ivas_qmetadata_encode_extended_gr( hMetaData, dist_azimuth_indexes_best[idx] - 1, dist_azimuth_alphabets[idx], gr_param_azimuth_best );
    2732        5822 :                         bits_gained += ivas_qmetadata_encode_extended_gr_length( dist_azimuth_indexes_best[idx], dist_azimuth_alphabets[idx], gr_param_azimuth_best ) -
    2733        5822 :                                        ivas_qmetadata_encode_extended_gr_length( dist_azimuth_indexes_best[idx] - 1, dist_azimuth_alphabets[idx], gr_param_azimuth_best );
    2734             :                     }
    2735             :                     else
    2736             :                     {
    2737        8773 :                         ivas_qmetadata_encode_extended_gr( hMetaData, dist_azimuth_indexes_best[idx], dist_azimuth_alphabets[idx], gr_param_azimuth_best );
    2738             :                     }
    2739             :                 }
    2740             :                 else
    2741             :                 {
    2742     8434742 :                     ivas_qmetadata_encode_extended_gr( hMetaData, dist_azimuth_indexes_best[idx], dist_azimuth_alphabets[idx], gr_param_azimuth_best );
    2743             :                 }
    2744             :             }
    2745             : 
    2746     2277931 :             if ( dist_count > nblocks )
    2747             :             {
    2748     1772520 :                 if ( ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID ) && ( nblocks > 1 ) )
    2749             :                 {
    2750       62816 :                     push_next_indice( hMetaData, use_adapt_avg, 1 );
    2751             :                 }
    2752    25057805 :                 for ( idx = nblocks; idx < dist_count; idx++ )
    2753             :                 {
    2754    23285285 :                     if ( make_gain == 1 && bits_gained < direction_bits_ec - max_bits && dist_azimuth_alphabets[idx] > 40 )
    2755             :                     {
    2756      201273 :                         if ( dist_azimuth_indexes_best[idx] > 1 )
    2757             :                         {
    2758      138596 :                             ivas_qmetadata_encode_extended_gr( hMetaData, dist_azimuth_indexes_best[idx] - 2, dist_azimuth_alphabets[idx], gr_param_azimuth_best );
    2759      138596 :                             bits_gained += ivas_qmetadata_encode_extended_gr_length( dist_azimuth_indexes_best[idx], dist_azimuth_alphabets[idx], gr_param_azimuth_best ) -
    2760      138596 :                                            ivas_qmetadata_encode_extended_gr_length( dist_azimuth_indexes_best[idx] - 2, dist_azimuth_alphabets[idx], gr_param_azimuth_best );
    2761             :                         }
    2762       62677 :                         else if ( dist_azimuth_indexes_best[idx] == 1 )
    2763             :                         {
    2764       24963 :                             ivas_qmetadata_encode_extended_gr( hMetaData, dist_azimuth_indexes_best[idx] - 1, dist_azimuth_alphabets[idx], gr_param_azimuth_best );
    2765       24963 :                             bits_gained += ivas_qmetadata_encode_extended_gr_length( dist_azimuth_indexes_best[idx], dist_azimuth_alphabets[idx], gr_param_azimuth_best ) -
    2766       24963 :                                            ivas_qmetadata_encode_extended_gr_length( dist_azimuth_indexes_best[idx] - 1, dist_azimuth_alphabets[idx], gr_param_azimuth_best );
    2767             :                         }
    2768             :                         else
    2769             :                         {
    2770       37714 :                             ivas_qmetadata_encode_extended_gr( hMetaData, dist_azimuth_indexes_best[idx], dist_azimuth_alphabets[idx], gr_param_azimuth_best );
    2771             :                         }
    2772             :                     }
    2773             :                     else
    2774             :                     {
    2775    23084012 :                         ivas_qmetadata_encode_extended_gr( hMetaData, dist_azimuth_indexes_best[idx], dist_azimuth_alphabets[idx], gr_param_azimuth_best );
    2776             :                     }
    2777             :                 }
    2778             :             }
    2779             :         }
    2780             : 
    2781     2955753 :         direction_bits_ec -= bits_gained;
    2782             :     }
    2783             :     else
    2784             :     {
    2785     2041525 :         direction_bits_ec = -1;
    2786             :     }
    2787             : 
    2788     4997278 :     return direction_bits_ec;
    2789             : }
    2790             : 
    2791             : 
    2792             : /*-------------------------------------------------------------------------
    2793             :  * ivas_qmetadata_raw_encode_dir()
    2794             :  *
    2795             :  * Main function for raw coding of the directions (writing and bit estimation)
    2796             :  *------------------------------------------------------------------------*/
    2797             : 
    2798     7038803 : static int16_t ivas_qmetadata_raw_encode_dir(
    2799             :     BSTR_ENC_HANDLE hMetaData,
    2800             :     IVAS_QDIRECTION *q_direction,
    2801             :     const int16_t nbands,
    2802             :     const int16_t start_band )
    2803             : {
    2804             :     int16_t i, j;
    2805             :     int16_t direction_bits_raw;
    2806     7038803 :     int16_t start_bits = 0; /*To avoid compiler warning*/
    2807             : 
    2808     7038803 :     direction_bits_raw = 0;
    2809     7038803 :     if ( hMetaData != NULL )
    2810             :     {
    2811     2041525 :         start_bits = hMetaData->nb_bits_tot;
    2812             :     }
    2813             : 
    2814     7038803 :     if ( q_direction->not_in_2D > 0 )
    2815             :     {
    2816    30133827 :         for ( i = start_band; i < nbands; i++ )
    2817             :         {
    2818    24244925 :             if ( hMetaData != NULL )
    2819             :             {
    2820    25645713 :                 for ( j = 0; j < q_direction->cfg.nblocks; j++ )
    2821             :                 {
    2822    19223592 :                     push_next_indice( hMetaData, q_direction->band_data[i].spherical_index[j], q_direction->band_data[i].bits_sph_idx[j] );
    2823             :                 }
    2824             :             }
    2825             :             else
    2826             :             {
    2827    17822804 :                 direction_bits_raw += q_direction->cfg.nblocks * q_direction->band_data[i].bits_sph_idx[0];
    2828             :             }
    2829             :         }
    2830             :     }
    2831             :     else
    2832             :     {
    2833     6687712 :         for ( i = start_band; i < nbands; i++ )
    2834             :         {
    2835    19426836 :             for ( j = 0; j < q_direction->cfg.nblocks; j++ )
    2836             :             {
    2837    13889025 :                 if ( hMetaData != NULL )
    2838             :                 {
    2839     2122976 :                     ivas_qmetadata_encode_quasi_uniform( hMetaData, q_direction->band_data[i].azimuth_index[j], q_direction->band_data[i].azimuth_m_alphabet[j] );
    2840             :                 }
    2841             :                 else
    2842             :                 {
    2843    11766049 :                     direction_bits_raw += ivas_qmetadata_encode_quasi_uniform_length(
    2844    11766049 :                         q_direction->band_data[i].azimuth_index[j], q_direction->band_data[i].azimuth_m_alphabet[j] );
    2845             :                 }
    2846             :             }
    2847             :         }
    2848             :     }
    2849             : 
    2850     7038803 :     if ( hMetaData != NULL )
    2851             :     {
    2852     2041525 :         direction_bits_raw = hMetaData->nb_bits_tot - start_bits;
    2853             :     }
    2854             : 
    2855     7038803 :     return direction_bits_raw;
    2856             : }
    2857             : 
    2858             : 
    2859             : /*-------------------------------------------------------------------------
    2860             :  * ivas_qmetadata_get_optimal_gr_param()
    2861             :  *
    2862             :  *
    2863             :  *------------------------------------------------------------------------*/
    2864             : 
    2865    24262124 : static int16_t ivas_qmetadata_get_optimal_gr_param(
    2866             :     uint16_t *unsigned_data,
    2867             :     const int16_t count,
    2868             :     const int16_t gr_param_count,
    2869             :     int16_t *opt_gr_size )
    2870             : {
    2871             :     int16_t opt_bits, bits, idx;
    2872             :     int16_t opt_gr_param;
    2873             :     int16_t p;
    2874             : 
    2875    24262124 :     opt_bits = MAX16B;
    2876    24262124 :     opt_gr_param = -1;
    2877             : 
    2878   134587145 :     for ( p = 0; p < gr_param_count; p++ )
    2879             :     {
    2880   110325021 :         bits = count * ( 1 + p ); /* terminating zero bit and the lsb bits */
    2881  1379888084 :         for ( idx = 0; idx < count; idx++ )
    2882             :         {
    2883  1269563063 :             bits += unsigned_data[idx] >> p; /* leading one bits */
    2884             :         }
    2885             : 
    2886   110325021 :         if ( bits < opt_bits )
    2887             :         {
    2888    36818917 :             opt_gr_param = p;
    2889    36818917 :             opt_bits = bits;
    2890             :         }
    2891             :     }
    2892             : 
    2893    24262124 :     *opt_gr_size = opt_bits;
    2894             : 
    2895    24262124 :     return opt_gr_param;
    2896             : }
    2897             : 
    2898             : 
    2899             : /*-------------------------------------------------------------------------
    2900             :  * ivas_qmetadata_encode_extended_gr_length()
    2901             :  *
    2902             :  *
    2903             :  *------------------------------------------------------------------------*/
    2904             : 
    2905             : int16_t
    2906   381597635 : ivas_qmetadata_encode_extended_gr_length(
    2907             :     const uint16_t value,
    2908             :     const uint16_t alphabet_size,
    2909             :     const int16_t gr_param )
    2910             : {
    2911             :     uint16_t msb_alphabet_size;
    2912             :     int16_t bits;
    2913             :     uint16_t msb, lsb;
    2914             : 
    2915             : #ifdef DEBUGGING
    2916             :     assert( alphabet_size >= 1 );
    2917             :     assert( value < alphabet_size );
    2918             :     assert( ( gr_param >= 0 ) && ( gr_param <= 15 ) );
    2919             : #endif
    2920             : 
    2921   381597635 :     msb_alphabet_size = ( alphabet_size + ( 1U << gr_param ) - 1 ) >> gr_param;
    2922             : 
    2923   381597635 :     if ( msb_alphabet_size <= 3 )
    2924             :     {
    2925             :         /* EncodeQuasiUniform is always equal or better than Limited GR with up to 3 msb values */
    2926    73725684 :         bits = ivas_qmetadata_encode_quasi_uniform_length( value, alphabet_size );
    2927             :     }
    2928             :     else
    2929             :     {
    2930   307871951 :         msb = value >> gr_param;
    2931             : 
    2932   307871951 :         bits = msb; /* leading one bits */
    2933   307871951 :         if ( msb < msb_alphabet_size - 1 )
    2934             :         {
    2935   303115363 :             bits += 1 + gr_param; /* terminating zero bit, if not the largest msb (Limited GR), and the lsb bits */
    2936             :         }
    2937             :         else
    2938             :         {
    2939     4756588 :             lsb = value & ( ( 1U << gr_param ) - 1 );
    2940     4756588 :             bits += ivas_qmetadata_encode_quasi_uniform_length( lsb, alphabet_size - ( ( msb_alphabet_size - 1 ) << gr_param ) );
    2941             :         }
    2942             :     }
    2943             : 
    2944   381597635 :     return bits;
    2945             : }
    2946             : 
    2947             : 
    2948             : /*-------------------------------------------------------------------------
    2949             :  * ivas_qmetadata_reorder_elevation_index()
    2950             :  *
    2951             :  *
    2952             :  *------------------------------------------------------------------------*/
    2953             : 
    2954   185155944 : static int16_t ivas_qmetadata_reorder_elevation_index(
    2955             :     const int16_t elevation_index,
    2956             :     const int16_t avg_elevation_index,
    2957             :     const int16_t elevation_alphabet )
    2958             : {
    2959             :     int16_t elevation_alphabet_half;
    2960             :     int16_t elevation_index_reordered;
    2961             : #ifdef DEBUGGING
    2962             :     assert( ( elevation_alphabet & 0x01 ) == 1 ); /* elevation_alphabet has the form 2 * n_points + 1 */
    2963             : #endif
    2964             : 
    2965   185155944 :     elevation_alphabet_half = elevation_alphabet >> 1;
    2966   185155944 :     elevation_index_reordered = elevation_index - avg_elevation_index;
    2967             : 
    2968             :     /* reduce the distance for the index elevation to the range [-elevation_alphabet_half, elevation_alphabet_half] */
    2969   185155944 :     if ( elevation_index_reordered < -elevation_alphabet_half )
    2970             :     {
    2971     2133990 :         elevation_index_reordered += elevation_alphabet;
    2972             :     }
    2973   183021954 :     else if ( elevation_index_reordered > elevation_alphabet_half )
    2974             :     {
    2975     3150509 :         elevation_index_reordered -= elevation_alphabet;
    2976             :     }
    2977             : 
    2978             :     /* fold reduced signed distance value for converting to unsigned */
    2979   185155944 :     elevation_index_reordered = ivas_qmetadata_reorder_generic( elevation_index_reordered );
    2980             : #ifdef DEBUGGING
    2981             :     assert( ( 0 <= elevation_index_reordered ) && ( elevation_index_reordered < elevation_alphabet ) );
    2982             : #endif
    2983             : 
    2984   185155944 :     return elevation_index_reordered;
    2985             : }
    2986             : 
    2987             : 
    2988             : /*-------------------------------------------------------------------------
    2989             :  * ivas_qmetadata_reorder_azimuth_index()
    2990             :  *
    2991             :  *
    2992             :  *------------------------------------------------------------------------*/
    2993             : 
    2994   158219562 : static int16_t ivas_qmetadata_reorder_azimuth_index(
    2995             :     const int16_t azimuth_index,
    2996             :     const int16_t avg_azimuth_index,
    2997             :     const int16_t azimuth_alphabet )
    2998             : {
    2999             :     int16_t azimuth_alphabet_half;
    3000             :     int16_t azimuth_index_reordered;
    3001             : 
    3002   158219562 :     azimuth_index_reordered = azimuth_index - avg_azimuth_index;
    3003             : 
    3004   158219562 :     if ( ( azimuth_alphabet != 1 ) && ( ( azimuth_alphabet & 0x01 ) == 1 ) )
    3005             :     {
    3006    59747430 :         return ( ivas_qmetadata_reorder_elevation_index( azimuth_index, avg_azimuth_index, azimuth_alphabet ) );
    3007             :     }
    3008    98472132 :     else if ( azimuth_alphabet != 1 )
    3009             :     {
    3010    98190225 :         azimuth_alphabet_half = azimuth_alphabet >> 1;
    3011             :         /* reduce the distance for the index azimuth to the range [-azimuth_alphabet_half, azimuth_alphabet_half - 1] */
    3012    98190225 :         if ( azimuth_index_reordered < -azimuth_alphabet_half )
    3013             :         {
    3014     1646817 :             azimuth_index_reordered += azimuth_alphabet;
    3015             :         }
    3016    96543408 :         else if ( azimuth_index_reordered > azimuth_alphabet_half - 1 )
    3017             :         {
    3018     6458303 :             azimuth_index_reordered -= azimuth_alphabet;
    3019             :         }
    3020             :         /* fold reduced signed distance value for converting to unsigned */
    3021    98190225 :         azimuth_index_reordered = ivas_qmetadata_reorder_generic( azimuth_index_reordered );
    3022             : #ifdef DEBUGGING
    3023             :         assert( ( 0 <= azimuth_index_reordered ) && ( azimuth_index_reordered < azimuth_alphabet ) );
    3024             : #endif
    3025             :     }
    3026             :     else
    3027             :     {
    3028             :         /* for North and South poles, a single azimuth direction exists */
    3029             : #ifdef DEBUGGING
    3030             :         assert( ( azimuth_index == 0 ) || ( azimuth_index == MASA_NO_INDEX ) );
    3031             : #endif
    3032      281907 :         azimuth_index_reordered = 0;
    3033             : 
    3034             : #ifdef DEBUGGING
    3035             :         assert( avg_azimuth_index == 0 );
    3036             : #endif
    3037             :     }
    3038             : 
    3039    98472132 :     return azimuth_index_reordered;
    3040             : }
    3041             : 
    3042             : 
    3043             : /*-------------------------------------------------------------------------
    3044             :  * ivas_qmetadata_encode_extended_gr()
    3045             :  *
    3046             :  *
    3047             :  *------------------------------------------------------------------------*/
    3048             : 
    3049    83086113 : void ivas_qmetadata_encode_extended_gr(
    3050             :     BSTR_ENC_HANDLE hMetaData,
    3051             :     const uint16_t value,
    3052             :     const uint16_t alphabet_size,
    3053             :     const int16_t gr_param )
    3054             : {
    3055             :     uint16_t msb_alphabet_size;
    3056             :     uint16_t msb, lsb, cnt;
    3057             : 
    3058             : #ifdef DEBUGGING
    3059             :     assert( alphabet_size >= 1 );
    3060             :     assert( value < alphabet_size );
    3061             :     assert( ( gr_param >= 0 ) && ( gr_param <= 31 ) );
    3062             : #endif
    3063             : 
    3064    83086113 :     msb_alphabet_size = ( alphabet_size + ( 1U << gr_param ) - 1 ) >> gr_param;
    3065             : 
    3066    83086113 :     if ( msb_alphabet_size <= 3 )
    3067             :     {
    3068             :         /* EncodeQuasiUniform is always equal or better than Limited GR with up to 3 msb values */
    3069     6575179 :         ivas_qmetadata_encode_quasi_uniform( hMetaData, value, alphabet_size );
    3070             :     }
    3071             :     else
    3072             :     {
    3073    76510934 :         msb = value >> gr_param;
    3074    76510934 :         lsb = value & ( ( 1U << gr_param ) - 1 );
    3075             : 
    3076   132393651 :         for ( cnt = 0; cnt < msb; cnt++ )
    3077             :         {
    3078             :             /* leading one bits */
    3079    55882717 :             push_next_indice( hMetaData, 1, 1 );
    3080             :         }
    3081             : 
    3082    76510934 :         if ( msb < msb_alphabet_size - 1 )
    3083             :         {
    3084    75992853 :             push_next_indice( hMetaData, 0, 1 ); /* terminating zero bit, if not the largest msb (Limited GR) */
    3085    75992853 :             if ( gr_param > 0 )
    3086             :             {
    3087    21445892 :                 push_next_indice( hMetaData, lsb, gr_param );
    3088             :             }
    3089             :         }
    3090             :         else
    3091             :         {
    3092      518081 :             ivas_qmetadata_encode_quasi_uniform( hMetaData, lsb, alphabet_size - ( ( msb_alphabet_size - 1 ) << gr_param ) );
    3093             :         }
    3094             :     }
    3095             : 
    3096    83086113 :     return;
    3097             : }
    3098             : 
    3099             : 
    3100             : /*-----------------------------------------------------------------------*
    3101             :  * Local functions (EC3, requantize directions)
    3102             :  *-----------------------------------------------------------------------*/
    3103             : 
    3104       47400 : static int16_t truncGR0(
    3105             :     float *data,
    3106             :     float *data_hat,
    3107             :     uint16_t *data_idx,
    3108             :     const int16_t len,
    3109             :     const int16_t bits_allowed,
    3110             :     float *st,
    3111             :     float *ct )
    3112             : {
    3113             :     int16_t i;
    3114             :     int16_t bits;
    3115       47400 :     const int16_t remap3b[8] = { 1, 6, 2, 4, 0, 5, 3, 7 };
    3116       47400 :     const int16_t remap2b[4] = { 1, 2, 0, 3 };
    3117             :     float diff[MAX_PARAM_SPATIAL_SUBFRAMES];
    3118             :     int16_t indx[MAX_PARAM_SPATIAL_SUBFRAMES];
    3119             : 
    3120       47400 :     bits = 0;
    3121       47400 :     set_f( data_hat, 0.0f, len );
    3122       47400 :     set_f( diff, 10000.0f, len );
    3123             : 
    3124       47400 :     if ( bits_allowed <= len + 1 )
    3125             :     {
    3126        2241 :         bits = min( bits_allowed, len );
    3127        2241 :         set_f( data_hat, 0.0f, len );
    3128             :         /*set_s(data_idx, 0, len); */
    3129       10332 :         for ( i = 0; i < bits; i++ )
    3130             :         {
    3131        8091 :             if ( fabsf( data[i] ) <= 90 )
    3132             :             {
    3133        7198 :                 data_idx[i] = 0;
    3134        7198 :                 data_hat[i] = 0.0f;
    3135             :             }
    3136             :             else
    3137             :             {
    3138         893 :                 data_idx[i] = 1;
    3139         893 :                 data_hat[i] = -180.0f;
    3140             :             }
    3141             :         }
    3142             : 
    3143        2241 :         return bits;
    3144             :     }
    3145             : 
    3146      223797 :     for ( i = 0; i < len; i++ )
    3147             :     {
    3148             : #ifdef DEBUGGING
    3149             :         assert( data_idx[i] < MASA_NO_INDEX );
    3150             : #endif
    3151      178638 :         data_idx[i] = quantize_phi( data[i] + 180, 0, &data_hat[i], 8 );
    3152      178638 :         data_hat[i] -= 180;
    3153      178638 :         data_idx[i] = remap3b[data_idx[i]];
    3154      178638 :         bits += ivas_qmetadata_encode_extended_gr_length( data_idx[i], 8, 0 );
    3155      178638 :         diff[i] = -st[i] - ct[i] * cosf( PI_OVER_180 * ( data[i] - data_hat[i] ) ); /*(data[i] - data_hat[i])*(data[i] - data_hat[i]);*/
    3156             :     }
    3157             : 
    3158       45159 :     i = 0;
    3159       45159 :     if ( bits > bits_allowed )
    3160             :     {
    3161       37743 :         sort_desc_ind( diff, len, indx );
    3162      154508 :         for ( i = len - 1; i >= 0; i-- )
    3163             :         {
    3164      133588 :             if ( data_idx[indx[i]] > 3 )
    3165             :             {
    3166       74348 :                 bits -= ivas_qmetadata_encode_extended_gr_length( data_idx[indx[i]], 8, 0 );
    3167       74348 :                 data_idx[indx[i]] = quantize_phi( data[indx[i]] + 180, 0, &data_hat[indx[i]], 4 );
    3168       74348 :                 data_hat[indx[i]] -= 180;
    3169       74348 :                 data_idx[indx[i]] = remap2b[data_idx[indx[i]]];
    3170       74348 :                 bits += ivas_qmetadata_encode_extended_gr_length( data_idx[indx[i]], 8, 0 );
    3171       74348 :                 diff[indx[i]] = -st[i] - ct[i] * cosf( PI_OVER_180 * ( data[indx[i]] - data_hat[indx[i]] ) );
    3172             :             }
    3173      133588 :             if ( bits <= bits_allowed )
    3174             :             {
    3175       16823 :                 break;
    3176             :             }
    3177             :         }
    3178             :     }
    3179             : 
    3180       45159 :     if ( bits > bits_allowed )
    3181             :     {
    3182       20920 :         sort_desc_ind( diff, len, indx );
    3183       46122 :         for ( i = len - 1; i >= 0; i-- )
    3184             :         {
    3185             : 
    3186       45826 :             if ( data_idx[indx[i]] > 1 )
    3187             :             {
    3188       39915 :                 bits -= ivas_qmetadata_encode_extended_gr_length( data_idx[indx[i]], 8, 0 );
    3189       39915 :                 if ( fabsf( data[indx[i]] ) <= 90 )
    3190             :                 {
    3191       25668 :                     data_idx[indx[i]] = 0;
    3192       25668 :                     data_hat[indx[i]] = 0;
    3193             :                 }
    3194             :                 else
    3195             :                 {
    3196       14247 :                     data_idx[indx[i]] = 1;
    3197       14247 :                     data_hat[indx[i]] = -180;
    3198             :                 }
    3199             : 
    3200       39915 :                 bits += ivas_qmetadata_encode_extended_gr_length( data_idx[indx[i]], 8, 0 );
    3201       39915 :                 diff[indx[i]] = -st[i] - ct[i] * cosf( PI_OVER_180 * ( data[indx[i]] - data_hat[indx[i]] ) );
    3202             :             }
    3203             : 
    3204       45826 :             if ( bits <= bits_allowed )
    3205             :             {
    3206       20624 :                 break;
    3207             :             }
    3208             :         }
    3209             :     }
    3210             : 
    3211       45159 :     if ( bits > bits_allowed )
    3212             :     {
    3213             : 
    3214             : #ifdef DEBUGGING
    3215             :         assert( bits_allowed > len );
    3216             :         for ( i = 0; i < len; i++ )
    3217             :         {
    3218             :             assert( data_idx[i] <= 1 );
    3219             :         }
    3220             : #endif
    3221             : 
    3222         296 :         sort_desc_ind( diff, len, indx );
    3223         356 :         for ( i = len - 1; i >= 0; i-- )
    3224             :         {
    3225             : 
    3226         356 :             if ( data_idx[indx[i]] > 0 )
    3227             :             {
    3228         316 :                 bits -= data_idx[indx[i]];
    3229         316 :                 data_idx[indx[i]] = 0;
    3230         316 :                 data_hat[indx[i]] = 0;
    3231             :             }
    3232         356 :             if ( bits <= bits_allowed )
    3233             :             {
    3234         296 :                 break;
    3235             :             }
    3236             :         }
    3237             :     }
    3238             : 
    3239       45159 :     return bits;
    3240             : }
    3241             : 
    3242             : 
    3243             : /*-------------------------------------------------------------------*
    3244             :  * truncGR0_chan()
    3245             :  *
    3246             :  *
    3247             :  *-------------------------------------------------------------------*/
    3248             : 
    3249       24550 : static int16_t truncGR0_chan(
    3250             :     const float *data,
    3251             :     float *data_hat,
    3252             :     uint16_t *data_idx,
    3253             :     const int16_t len,
    3254             :     const int16_t bits_allowed,
    3255             :     float *st,
    3256             :     float *ct )
    3257             : {
    3258             :     int16_t i, idx_crt;
    3259             :     int16_t bits;
    3260             :     float diff[MAX_PARAM_SPATIAL_SUBFRAMES], sort_diff[MAX_PARAM_SPATIAL_SUBFRAMES], min_diff, sum_diff;
    3261             :     int16_t indx[MAX_PARAM_SPATIAL_SUBFRAMES];
    3262             : 
    3263       24550 :     bits = 0;
    3264       24550 :     set_f( data_hat, 0.0f, len );
    3265       24550 :     set_f( diff, 10000.0f, len );
    3266             : 
    3267       24550 :     if ( bits_allowed <= len + 1 )
    3268             :     {
    3269          98 :         bits = min( bits_allowed, len );
    3270          98 :         set_f( data_hat, 0.0f, len );
    3271             :         /*set_s(data_idx, 0, len); */
    3272         490 :         for ( i = 0; i < bits; i++ )
    3273             :         {
    3274         392 :             if ( fabsf( data[i] ) <= 90 )
    3275             :             {
    3276         328 :                 data_idx[i] = 0;
    3277         328 :                 data_hat[i] = 0.0f;
    3278             :             }
    3279             :             else
    3280             :             {
    3281          64 :                 data_idx[i] = 1;
    3282          64 :                 data_hat[i] = -180.0f;
    3283             :             }
    3284             :         }
    3285          98 :         return bits;
    3286             :     }
    3287             : 
    3288      122143 :     for ( i = 0; i < len; i++ )
    3289             :     {
    3290             : #ifdef DEBUGGING
    3291             :         assert( data_idx[i] < MASA_NO_INDEX );
    3292             : #endif
    3293       97691 :         data_idx[i] = quantize_phi_chan_lbr( data[i], &data_hat[i], 9 );
    3294             : 
    3295       97691 :         bits += ivas_qmetadata_encode_extended_gr_length( data_idx[i], 9, 0 );
    3296       97691 :         diff[i] = -st[i] - ct[i] * cosf( ( data[i] - data_hat[i] ) * PI_OVER_180 );
    3297             :     }
    3298             : 
    3299       61113 :     while ( bits > bits_allowed )
    3300             :     {
    3301       36661 :         min_diff = 1000.0f;
    3302       36661 :         idx_crt = -1;
    3303       36661 :         mvr2r( diff, sort_diff, len );
    3304      183266 :         for ( i = 0; i < len; i++ )
    3305             :         {
    3306      146605 :             if ( data_idx[i] > 0 )
    3307             :             {
    3308      112235 :                 sort_diff[i] = -st[i] - ct[i] * cosf( ( fabsf( data[i] ) - cb_azi_chan[( ( data_idx[i] + 1 ) >> 1 ) - 1] ) * PI_OVER_180 );
    3309      112235 :                 sum_diff = sum_f( sort_diff, len );
    3310             : 
    3311      112235 :                 if ( sum_diff < min_diff )
    3312             :                 {
    3313       66483 :                     min_diff = sum_diff;
    3314       66483 :                     idx_crt = i;
    3315             :                 }
    3316      112235 :                 sort_diff[i] = diff[i];
    3317             :             }
    3318             :         }
    3319             : 
    3320       36661 :         if ( idx_crt > -1 )
    3321             :         {
    3322       36661 :             bits -= ivas_qmetadata_encode_extended_gr_length( data_idx[idx_crt], 9, 0 );
    3323       36661 :             data_idx[idx_crt] = quantize_phi_chan_lbr( data[idx_crt], &data_hat[idx_crt], data_idx[idx_crt] + 1 );
    3324       36661 :             bits += ivas_qmetadata_encode_extended_gr_length( data_idx[idx_crt], 9, 0 );
    3325       36661 :             diff[idx_crt] = -st[idx_crt] - ct[idx_crt] * cosf( ( data[idx_crt] - data_hat[idx_crt] ) * PI_OVER_180 );
    3326             :         }
    3327             :         else
    3328             :         {
    3329           0 :             break;
    3330             :         }
    3331             :     }
    3332             : 
    3333       24452 :     if ( bits > bits_allowed )
    3334             :     {
    3335           0 :         mvr2r( diff, sort_diff, len );
    3336           0 :         sort_desc_ind( sort_diff, len, indx );
    3337             : 
    3338           0 :         for ( i = len - 1; i >= 0; i-- )
    3339             :         {
    3340           0 :             idx_crt = indx[i];
    3341           0 :             if ( data_idx[idx_crt] > 0 )
    3342             :             {
    3343           0 :                 bits -= ivas_qmetadata_encode_extended_gr_length( data_idx[idx_crt], 9, 0 );
    3344           0 :                 data_idx[idx_crt] = 0;
    3345           0 :                 data_hat[idx_crt] = 0;
    3346           0 :                 bits += 1;
    3347             :             }
    3348             : 
    3349           0 :             if ( bits <= bits_allowed )
    3350             :             {
    3351           0 :                 break;
    3352             :             }
    3353             :         }
    3354             :     }
    3355             : 
    3356       24452 :     return bits;
    3357             : }
    3358             : 
    3359             : 
    3360             : /*-------------------------------------------------------------------*
    3361             :  * common_direction()
    3362             :  *
    3363             :  *
    3364             :  *-------------------------------------------------------------------*/
    3365             : 
    3366       69724 : static int16_t common_direction(
    3367             :     IVAS_QDIRECTION *q_direction,
    3368             :     const int16_t band_idx,
    3369             :     const int16_t len,
    3370             :     const int16_t bits_allowed,
    3371             :     BSTR_ENC_HANDLE hMetaData,
    3372             :     float *elevation_orig,
    3373             :     float *azimuth_orig )
    3374             : {
    3375             :     int16_t nbits;
    3376             :     int16_t no_th, i, id_th, k;
    3377             :     float theta_cb[5];
    3378             :     float dist, best_dist;
    3379             :     float ct[MAX_PARAM_SPATIAL_SUBFRAMES], st[MAX_PARAM_SPATIAL_SUBFRAMES];
    3380             : 
    3381       69724 :     nbits = 0;
    3382             : 
    3383       69724 :     if ( bits_allowed == 0 )
    3384             :     {
    3385           0 :         for ( i = 0; i < len; i++ )
    3386             :         {
    3387           0 :             q_direction->band_data[band_idx].elevation[i] = 0;
    3388           0 :             q_direction->band_data[band_idx].azimuth[i] = 0;
    3389             :         }
    3390             : 
    3391           0 :         return 0;
    3392             :     }
    3393             : 
    3394       69724 :     if ( bits_allowed <= len + 1 )
    3395             :     {
    3396        1114 :         set_f( q_direction->band_data[band_idx].elevation, 0.0f, len );
    3397        1114 :         set_f( st, 0.0f, len );
    3398             : 
    3399        5570 :         for ( i = 0; i < len; i++ )
    3400             :         {
    3401        4456 :             ct[i] = cosf( elevation_orig[i] * PI_OVER_180 );
    3402             :         }
    3403             : 
    3404        1114 :         if ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID )
    3405             :         {
    3406           0 :             nbits = truncGR0_chan( azimuth_orig, q_direction->band_data[band_idx].azimuth, q_direction->band_data[band_idx].azimuth_index, len, bits_allowed, st, ct );
    3407             :         }
    3408             :         else
    3409             :         {
    3410        1114 :             nbits = truncGR0( azimuth_orig, q_direction->band_data[band_idx].azimuth, q_direction->band_data[band_idx].azimuth_index, len, bits_allowed, st, ct );
    3411             :         }
    3412             : 
    3413        5570 :         for ( i = 0; i < nbits; i++ )
    3414             :         {
    3415        4456 :             push_next_indice( hMetaData, q_direction->band_data[band_idx].azimuth_index[i], 1 );
    3416             :         }
    3417             : 
    3418        1114 :         return nbits;
    3419             :     }
    3420             : 
    3421       68610 :     no_th = no_theta_masa[0] + 3; /* only 5 values for theta; the lat 2 are +/-90 */
    3422             : 
    3423       68610 :     theta_cb[0] = 0;
    3424       68610 :     theta_cb[1] = delta_theta_masa[2];
    3425       68610 :     theta_cb[2] = -theta_cb[1];
    3426       68610 :     theta_cb[3] = 90.0f;
    3427       68610 :     theta_cb[4] = -90.0f;
    3428       68610 :     best_dist = 900000.0f;
    3429       68610 :     id_th = 0;
    3430             : 
    3431      411660 :     for ( i = 0; i < no_th; i++ )
    3432             :     {
    3433      343050 :         dist = 0.0f;
    3434     1715250 :         for ( k = 0; k < len; k++ )
    3435             :         {
    3436     1372200 :             dist += ( elevation_orig[k] - theta_cb[i] ) * ( elevation_orig[k] - theta_cb[i] );
    3437             :         }
    3438      343050 :         if ( dist < best_dist )
    3439             :         {
    3440      100535 :             id_th = i;
    3441      100535 :             best_dist = dist;
    3442             :         }
    3443             :     }
    3444             : 
    3445       68610 :     set_f( q_direction->band_data[band_idx].elevation, theta_cb[id_th], len );
    3446             : 
    3447      343050 :     for ( i = 0; i < len; i++ )
    3448             :     {
    3449      274440 :         q_direction->band_data[band_idx].elevation_index[i] = id_th;
    3450             :     }
    3451             : 
    3452       68610 :     if ( id_th == 0 )
    3453             :     {
    3454       38070 :         push_next_indice( hMetaData, 0, 1 ); /* average theta index */
    3455       38070 :         set_f( st, 0.0f, len );
    3456             : 
    3457      190350 :         for ( i = 0; i < len; i++ )
    3458             :         {
    3459      152280 :             ct[i] = cosf( elevation_orig[i] * PI_OVER_180 );
    3460             :         }
    3461             : 
    3462       38070 :         if ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID )
    3463             :         {
    3464        8125 :             nbits = truncGR0_chan( azimuth_orig, q_direction->band_data[band_idx].azimuth, q_direction->band_data[band_idx].azimuth_index, len, bits_allowed - 1, st, ct ) + 1;
    3465             :         }
    3466             :         else
    3467             :         {
    3468       29945 :             nbits = truncGR0( azimuth_orig, q_direction->band_data[band_idx].azimuth, q_direction->band_data[band_idx].azimuth_index, len, bits_allowed - 1, st, ct ) + 1;
    3469             :         }
    3470             :     }
    3471             :     else
    3472             :     {
    3473       30540 :         if ( id_th >= 3 )
    3474             :         {
    3475             :             /* theta is 90 or -90; only theta is sent */
    3476        1385 :             push_next_indice( hMetaData, id_th + 11, 4 ); /* average theta index */
    3477        1385 :             set_f( q_direction->band_data[band_idx].azimuth, 0.0f, len );
    3478        6925 :             for ( i = 0; i < len; i++ )
    3479             :             {
    3480        5540 :                 q_direction->band_data[band_idx].azimuth_index[i] = 0;
    3481             :             }
    3482        1385 :             nbits = 4;
    3483             : 
    3484        1385 :             return nbits;
    3485             :         }
    3486             : 
    3487       29155 :         set_f( st, sinf( theta_cb[id_th] * PI_OVER_180 ), len );
    3488       29155 :         set_f( ct, cosf( theta_cb[id_th] * PI_OVER_180 ), len );
    3489             : 
    3490      145775 :         for ( i = 0; i < len; i++ )
    3491             :         {
    3492      116620 :             st[i] *= sinf( elevation_orig[i] * PI_OVER_180 );
    3493      116620 :             ct[i] *= cosf( elevation_orig[i] * PI_OVER_180 );
    3494      116620 :             q_direction->band_data[band_idx].azimuth_index[i] = 0;
    3495             :         }
    3496             : 
    3497       29155 :         if ( id_th == 1 )
    3498             :         {
    3499       23557 :             push_next_indice( hMetaData, 2, 2 ); /* average theta index */
    3500             :         }
    3501             :         else
    3502             :         {
    3503        5598 :             assert( id_th == 2 );
    3504        5598 :             push_next_indice( hMetaData, 6, 3 ); /* average theta index */
    3505             :         }
    3506             : 
    3507       29155 :         if ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID )
    3508             :         {
    3509       16334 :             nbits = truncGR0_chan( azimuth_orig, q_direction->band_data[band_idx].azimuth, q_direction->band_data[band_idx].azimuth_index, len, bits_allowed - ( id_th + 1 ), st, ct ) + ( id_th + 1 );
    3510             :         }
    3511             :         else
    3512             :         {
    3513       12821 :             nbits = truncGR0( azimuth_orig, q_direction->band_data[band_idx].azimuth, q_direction->band_data[band_idx].azimuth_index, len, bits_allowed - ( id_th + 1 ), st, ct ) + ( id_th + 1 );
    3514             :         }
    3515             :     }
    3516             : 
    3517       67225 :     if ( bits_allowed - ( id_th + 1 ) <= len + 1 )
    3518             :     {
    3519             : 
    3520        2769 :         for ( i = 0; i < min( len, bits_allowed - ( id_th + 1 ) ); i++ )
    3521             :         {
    3522        2208 :             push_next_indice( hMetaData, q_direction->band_data[band_idx].azimuth_index[i], 1 );
    3523             :         }
    3524             :     }
    3525             :     else
    3526             :     {
    3527       66664 :         if ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID )
    3528             :         {
    3529      121805 :             for ( i = 0; i < len; i++ )
    3530             :             {
    3531       97444 :                 ivas_qmetadata_encode_extended_gr( hMetaData, q_direction->band_data[band_idx].azimuth_index[i], 9, 0 );
    3532             :             }
    3533             :         }
    3534             :         else
    3535             :         {
    3536      211515 :             for ( i = 0; i < len; i++ )
    3537             :             {
    3538      169212 :                 ivas_qmetadata_encode_extended_gr( hMetaData, q_direction->band_data[band_idx].azimuth_index[i], 8, 0 );
    3539             :             }
    3540             :         }
    3541             :     }
    3542             : 
    3543       67225 :     return nbits;
    3544             : }
    3545             : 
    3546             : 
    3547             : /*-------------------------------------------------------------------*
    3548             :  * encode_directions_subband()
    3549             :  *
    3550             :  *
    3551             :  *-------------------------------------------------------------------*/
    3552             : 
    3553      880870 : static int16_t encode_directions_subband(
    3554             :     IVAS_QDIRECTION *q_direction,
    3555             :     int16_t coding_subbands,
    3556             :     BSTR_ENC_HANDLE hMetaData,
    3557             :     const int16_t j,
    3558             :     const int16_t next_j,
    3559             :     const int16_t no_subframes,
    3560             :     const int16_t last_subband,
    3561             :     int16_t *p_diff,
    3562             :     float *elevation_orig,
    3563             :     float *azimuth_orig )
    3564             : {
    3565             :     int16_t allowed_bits, use_vq, max_nb_idx, k;
    3566             :     int16_t diff;
    3567             :     float d1, d2;
    3568             :     int16_t nbits;
    3569             :     int16_t *bits_dir0;
    3570             : 
    3571      880870 :     nbits = 0;
    3572      880870 :     diff = *p_diff;
    3573      880870 :     bits_dir0 = (int16_t *) q_direction->band_data[j].bits_sph_idx;
    3574      880870 :     allowed_bits = sum_s( bits_dir0, no_subframes );
    3575             : 
    3576      880870 :     if ( allowed_bits > 0 )
    3577             :     {
    3578      880870 :         use_vq = 0;
    3579      880870 :         max_nb_idx = 0;
    3580             : 
    3581     3157460 :         for ( k = 0; k < no_subframes; k++ )
    3582             :         {
    3583     2276590 :             if ( bits_dir0[k] > use_vq )
    3584             :             {
    3585     1039235 :                 use_vq = bits_dir0[k];
    3586     1039235 :                 max_nb_idx = k;
    3587             :             }
    3588             :         }
    3589             : 
    3590      880870 :         if ( no_subframes > 1 )
    3591             :         {
    3592      465240 :             if ( ( use_vq > 1 ) && ( use_vq <= LIMIT_USE_COMMON ) )
    3593             :             {
    3594       70190 :                 bits_dir0[max_nb_idx] -= 1;
    3595       70190 :                 allowed_bits -= 1;
    3596             :             }
    3597             : #ifdef DEBUGGING
    3598             :             assert( bits_dir0[max_nb_idx] > 0 );
    3599             : #endif
    3600             :         }
    3601      880870 :         if ( no_subframes > 1 )
    3602             :         {
    3603      465240 :             if ( use_vq <= LIMIT_USE_COMMON )
    3604             :             {
    3605             :                 /* calculate the two distances */
    3606       70916 :                 calculate_two_distances( q_direction->band_data[j].elevation, bits_dir0, allowed_bits, no_subframes, &d1, &d2 );
    3607       70916 :                 if ( ( ( use_vq > 1 ) && ( d2 <= d1 ) ) || ( use_vq <= 1 ) )
    3608             :                 {
    3609       69724 :                     if ( use_vq > 1 )
    3610             :                     {
    3611       68998 :                         push_next_indice( hMetaData, 1, 1 ); /* signal VQ */
    3612             :                     }
    3613             : 
    3614       69724 :                     diff += common_direction( q_direction, j, no_subframes, allowed_bits, hMetaData, elevation_orig, azimuth_orig ) - allowed_bits;
    3615             : 
    3616       69724 :                     if ( last_subband == 0 )
    3617             :                     {
    3618       48739 :                         update_bits_next_block( q_direction, &diff, next_j, coding_subbands, no_subframes );
    3619             :                     }
    3620             :                 }
    3621             :                 else
    3622             :                 {
    3623        1192 :                     push_next_indice( hMetaData, 0, 1 );
    3624             : 
    3625        1192 :                     if ( last_subband == 0 )
    3626             :                     {
    3627         695 :                         mvr2r( elevation_orig, q_direction->band_data[j].elevation, no_subframes );
    3628         695 :                         mvr2r( azimuth_orig, q_direction->band_data[j].azimuth, no_subframes );
    3629         695 :                         joint_encoding( q_direction, j, next_j, coding_subbands, bits_dir0, allowed_bits, hMetaData, &diff );
    3630             :                     }
    3631             :                     else
    3632             :                     {
    3633        2485 :                         for ( k = 0; k < no_subframes; k++ )
    3634             :                         {
    3635             :                             /* requantize the direction */
    3636        1988 :                             q_direction->band_data[j].spherical_index[k] = quantize_direction( elevation_orig[k], azimuth_orig[k], q_direction->band_data[j].bits_sph_idx[k], &q_direction->band_data[j].elevation[k], &q_direction->band_data[j].azimuth[k],
    3637        1988 :                                                                                                &q_direction->band_data[j].elevation_index[k], &q_direction->band_data[j].azimuth_index[k], q_direction->cfg.mc_ls_setup );
    3638             :                         }
    3639             : 
    3640         497 :                         if ( allowed_bits > 0 )
    3641             :                         {
    3642         497 :                             nbits = write_fixed_rate_direction( hMetaData, q_direction, j, no_subframes );
    3643             :                         }
    3644             :                     }
    3645             :                 }
    3646             :             }
    3647             :             else
    3648             :             {
    3649             :                 /* there is only joint coding */
    3650      394324 :                 mvr2r( elevation_orig, q_direction->band_data[j].elevation, no_subframes );
    3651      394324 :                 mvr2r( azimuth_orig, q_direction->band_data[j].azimuth, no_subframes );
    3652             : 
    3653      394324 :                 if ( last_subband == 0 )
    3654             :                 {
    3655      255506 :                     joint_encoding( q_direction, j, next_j, coding_subbands, bits_dir0, allowed_bits, hMetaData, &diff );
    3656             :                 }
    3657             :                 else
    3658             :                 {
    3659      694090 :                     for ( k = 0; k < no_subframes; k++ )
    3660             :                     {
    3661             :                         /* requantize the direction */
    3662      555272 :                         q_direction->band_data[j].spherical_index[k] = quantize_direction( elevation_orig[k], azimuth_orig[k], q_direction->band_data[j].bits_sph_idx[k], &q_direction->band_data[j].elevation[k], &q_direction->band_data[j].azimuth[k],
    3663      555272 :                                                                                            &q_direction->band_data[j].elevation_index[k], &q_direction->band_data[j].azimuth_index[k], q_direction->cfg.mc_ls_setup );
    3664             :                     }
    3665             : 
    3666      138818 :                     if ( allowed_bits > 0 )
    3667             :                     {
    3668      138818 :                         nbits = write_fixed_rate_direction( hMetaData, q_direction, j, no_subframes );
    3669             :                     }
    3670             :                 }
    3671             :             }
    3672             :         }
    3673             :         else
    3674             :         {
    3675             :             /* 1 subframe case */
    3676             :             /* there is only joint coding */
    3677      415630 :             mvr2r( elevation_orig, q_direction->band_data[j].elevation, no_subframes );
    3678      415630 :             mvr2r( azimuth_orig, q_direction->band_data[j].azimuth, no_subframes );
    3679             : 
    3680      415630 :             if ( last_subband == 0 )
    3681             :             {
    3682      281583 :                 joint_encoding( q_direction, j, next_j, coding_subbands, bits_dir0, allowed_bits, hMetaData, &diff );
    3683             :             }
    3684             :             else
    3685             :             {
    3686      268094 :                 for ( k = 0; k < no_subframes; k++ )
    3687             :                 {
    3688             :                     /* requantize the direction */
    3689      134047 :                     q_direction->band_data[j].spherical_index[k] = quantize_direction( elevation_orig[k], azimuth_orig[k], q_direction->band_data[j].bits_sph_idx[k], &q_direction->band_data[j].elevation[k], &q_direction->band_data[j].azimuth[k],
    3690      134047 :                                                                                        &q_direction->band_data[j].elevation_index[k], &q_direction->band_data[j].azimuth_index[k], q_direction->cfg.mc_ls_setup );
    3691             :                 }
    3692             : 
    3693      134047 :                 if ( allowed_bits > 0 )
    3694             :                 {
    3695      134047 :                     nbits = write_fixed_rate_direction( hMetaData, q_direction, j, no_subframes );
    3696             :                 }
    3697             :             }
    3698             :         }
    3699             :     }
    3700             :     else
    3701             :     {
    3702           0 :         set_f( q_direction->band_data[j].elevation, 0.0f, no_subframes );
    3703           0 :         set_f( q_direction->band_data[j].azimuth, 0.0f, no_subframes );
    3704             :     }
    3705             : 
    3706      880870 :     *p_diff = diff;
    3707             : 
    3708      880870 :     return nbits;
    3709             : }
    3710             : 
    3711             : 
    3712             : /*-------------------------------------------------------------------*
    3713             :  * calc_var_azi()
    3714             :  *
    3715             :  *
    3716             :  *-------------------------------------------------------------------*/
    3717             : 
    3718       99527 : static int16_t calc_var_azi(
    3719             :     const IVAS_QDIRECTION *q_direction,
    3720             :     const int16_t diffuseness_index_max_ec_frame,
    3721             :     const float avg_azimuth,
    3722             :     float *avg_azimuth_out )
    3723             : {
    3724             :     float var_band, dif;
    3725             :     float avg_direction_vector_band[3], avg_azimuth_band[24], direction_vector[3];
    3726             :     float avg_elevation;
    3727             :     int16_t i, j, idx;
    3728             : 
    3729       99527 :     idx = 0;
    3730       99527 :     set_zero( avg_azimuth_band, 24 );
    3731             : 
    3732      597162 :     for ( i = 0; i < q_direction->cfg.nbands; i++ )
    3733             :     {
    3734      497635 :         set_zero( avg_direction_vector_band, 3 );
    3735      497635 :         if ( q_direction->band_data[i].energy_ratio_index_mod[0] <= diffuseness_index_max_ec_frame )
    3736             :         {
    3737     1637355 :             for ( j = 0; j < q_direction->cfg.nblocks; j++ )
    3738             :             {
    3739             :                 /*compute the average direction */
    3740     1309884 :                 ivas_qmetadata_azimuth_elevation_to_direction_vector( q_direction->band_data[i].azimuth[j], q_direction->band_data[i].elevation[j], direction_vector );
    3741     1309884 :                 v_add( avg_direction_vector_band, direction_vector, avg_direction_vector_band, 3 );
    3742             :             }
    3743      327471 :             ivas_qmetadata_direction_vector_to_azimuth_elevation( avg_direction_vector_band, &avg_azimuth_band[idx], &avg_elevation );
    3744      327471 :             idx++;
    3745             :         }
    3746             :     }
    3747             : 
    3748       99527 :     var_band = 0.0f;
    3749             : 
    3750      426998 :     for ( i = 0; i < idx; i++ )
    3751             :     {
    3752      327471 :         dif = ( avg_azimuth_band[idx] - avg_azimuth );
    3753      327471 :         if ( dif < 0 )
    3754             :         {
    3755       75368 :             dif = -dif;
    3756             :         }
    3757      327471 :         if ( dif > 180 )
    3758             :         {
    3759           0 :             dif = 360 - dif;
    3760             :         }
    3761             : 
    3762      327471 :         var_band += dif * dif;
    3763             :     }
    3764             : 
    3765       99527 :     if ( idx > 0 )
    3766             :     {
    3767       99527 :         var_band = var_band / idx;
    3768             :     }
    3769             : 
    3770       99527 :     if ( var_band <= VAR_AZI_THRESH )
    3771             :     {
    3772       23394 :         *avg_azimuth_out = avg_azimuth;
    3773       23394 :         return 0;
    3774             :     }
    3775             :     else
    3776             :     {
    3777       76133 :         *avg_azimuth_out = avg_azimuth_band[0];
    3778       76133 :         return 1;
    3779             :     }
    3780             : }
    3781             : 
    3782             : 
    3783             : /*-------------------------------------------------------------------*
    3784             :  * requantize_direction_EC_3()
    3785             :  *
    3786             :  *
    3787             :  *-------------------------------------------------------------------*/
    3788             : 
    3789      179474 : static ivas_error requantize_direction_EC_3(
    3790             :     int16_t *extra_bits,
    3791             :     IVAS_QDIRECTION *q_direction,
    3792             :     const int16_t coding_subbands,
    3793             :     BSTR_ENC_HANDLE hMetaData,
    3794             :     float elevation_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES],
    3795             :     float azimuth_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES],
    3796             :     int16_t *ind_order )
    3797             : {
    3798             :     /* gradually increase the bits following the performance of the EC layer*/
    3799             :     int16_t j, k;
    3800             :     int16_t use_vq;
    3801             :     int16_t diff, allowed_bits, last_j;
    3802             :     int16_t no_subframes, start_band;
    3803             :     float st[MAX_PARAM_SPATIAL_SUBFRAMES], ct[MAX_PARAM_SPATIAL_SUBFRAMES];
    3804             :     int16_t *bits_dir0;
    3805             : #ifdef DEBUGGING
    3806             :     int16_t nbits;
    3807             : 
    3808             :     nbits = 0;
    3809             : #endif
    3810      179474 :     no_subframes = q_direction->cfg.nblocks;
    3811      179474 :     start_band = q_direction->cfg.start_band;
    3812             : 
    3813      179474 :     if ( q_direction->not_in_2D > MASA_LIMIT_2D )
    3814             :     {
    3815      171568 :         j = ind_order[coding_subbands - 1];
    3816      171568 :         bits_dir0 = (int16_t *) q_direction->band_data[j].bits_sph_idx;
    3817      171568 :         allowed_bits = sum_s( bits_dir0, no_subframes );
    3818      171568 :         last_j = j - ( allowed_bits == 0 );
    3819      171568 :         diff = 0;
    3820      171568 :         if ( coding_subbands == 1 )
    3821             :         {
    3822        3019 :             last_j = start_band;
    3823             :         }
    3824      758091 :         for ( j = 0; j < last_j; j++ )
    3825             :         {
    3826      586523 :             k = ind_order[j];
    3827      586523 :             encode_directions_subband( q_direction, coding_subbands, hMetaData, k, ind_order[j + 1], no_subframes, 0, &diff, elevation_orig[k], azimuth_orig[k] );
    3828             :         }
    3829             : 
    3830             :         /* last subbands to be written in fixed rate */
    3831      465915 :         for ( j = last_j; j < coding_subbands; j++ )
    3832             :         {
    3833      294347 :             k = ind_order[j];
    3834      294347 :             encode_directions_subband( q_direction, coding_subbands, hMetaData, k, 0, no_subframes, 1, &diff, elevation_orig[k], azimuth_orig[k] );
    3835             :         }
    3836             :     }
    3837             :     else /* 2D */
    3838             :     {
    3839        7906 :         diff = 0;
    3840             : #ifdef DEBUGGING
    3841             :         nbits = 0;
    3842             : #endif
    3843       46002 :         for ( j = start_band; j < coding_subbands; j++ )
    3844             :         {
    3845       38096 :             bits_dir0 = (int16_t *) q_direction->band_data[j].bits_sph_idx;
    3846       38096 :             allowed_bits = sum_s( bits_dir0, no_subframes );
    3847       38096 :             use_vq = 0;
    3848             : 
    3849      132490 :             for ( k = 0; k < no_subframes; k++ )
    3850             :             {
    3851       94394 :                 if ( bits_dir0[k] > use_vq )
    3852             :                 {
    3853       41956 :                     use_vq = bits_dir0[k];
    3854             :                 }
    3855             :             }
    3856             : 
    3857       38096 :             if ( ( use_vq <= 3 ) && ( allowed_bits <= 11 ) )
    3858             :             {
    3859        3611 :                 set_f( st, 0.0f, no_subframes );
    3860             : 
    3861       15103 :                 for ( k = 0; k < no_subframes; k++ )
    3862             :                 {
    3863       11492 :                     ct[k] = cosf( elevation_orig[j][k] * PI_OVER_180 );
    3864             :                 }
    3865             : 
    3866        3611 :                 if ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID )
    3867             :                 {
    3868             : #ifdef DEBUGGING
    3869             :                     nbits += truncGR0_chan( azimuth_orig[j], q_direction->band_data[j].azimuth, q_direction->band_data[j].azimuth_index, no_subframes, allowed_bits, st, ct );
    3870             : #else
    3871          91 :                     truncGR0_chan( azimuth_orig[j], q_direction->band_data[j].azimuth, q_direction->band_data[j].azimuth_index, no_subframes, allowed_bits, st, ct );
    3872             : #endif
    3873             :                 }
    3874             :                 else
    3875             :                 {
    3876             : #ifdef DEBUGGING
    3877             :                     nbits += truncGR0( azimuth_orig[j], q_direction->band_data[j].azimuth, q_direction->band_data[j].azimuth_index, no_subframes, allowed_bits, st, ct );
    3878             : #else
    3879        3520 :                     truncGR0( azimuth_orig[j], q_direction->band_data[j].azimuth, q_direction->band_data[j].azimuth_index, no_subframes, allowed_bits, st, ct );
    3880             : #endif
    3881             :                 }
    3882             : 
    3883        3611 :                 if ( allowed_bits <= no_subframes + 1 )
    3884             :                 {
    3885        2483 :                     for ( k = 0; k < min( no_subframes, allowed_bits ); k++ )
    3886             :                     {
    3887        1819 :                         push_next_indice( hMetaData, q_direction->band_data[j].azimuth_index[k], 1 );
    3888             :                     }
    3889             :                 }
    3890             :                 else
    3891             :                 {
    3892       12620 :                     for ( k = 0; k < no_subframes; k++ )
    3893             :                     {
    3894        9673 :                         ivas_qmetadata_encode_extended_gr( hMetaData, q_direction->band_data[j].azimuth_index[k], q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID ? 9 : 8, 0 );
    3895             :                     }
    3896             :                 }
    3897             :             }
    3898             :             else
    3899             :             {
    3900      117387 :                 for ( k = 0; k < no_subframes; k++ )
    3901             :                 {
    3902             :                     /* requantize the direction */
    3903      165804 :                     q_direction->band_data[j].spherical_index[k] = quantize_direction2D( azimuth_orig[j][k], 1 << q_direction->band_data[j].bits_sph_idx[k], &q_direction->band_data[j].azimuth[k],
    3904       82902 :                                                                                          &q_direction->band_data[j].azimuth_index[k], q_direction->cfg.mc_ls_setup );
    3905       82902 :                     q_direction->band_data[j].elevation_index[k] = 0;
    3906             :                 }
    3907             : #ifdef DEBUGGING
    3908             :                 nbits += write_fixed_rate_direction( hMetaData, q_direction, j, no_subframes );
    3909             : #else
    3910       34485 :                 write_fixed_rate_direction( hMetaData, q_direction, j, no_subframes );
    3911             : #endif
    3912             :             }
    3913             :         }
    3914             :     }
    3915             : #ifdef DEBUGGING
    3916             :     if ( diff > 0 )
    3917             :     {
    3918             :         return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Not enough bits in requantize_direction_EC_3(); %d bits written \n", nbits );
    3919             :     }
    3920             : #endif
    3921             : 
    3922      179474 :     *extra_bits = -diff;
    3923             : 
    3924      179474 :     return IVAS_ERR_OK;
    3925             : }
    3926             : 
    3927             : 
    3928             : /*-------------------------------------------------------------------*
    3929             :  * write_fixed_rate_direction()
    3930             :  *
    3931             :  * writing of the spherical indexes
    3932             :  *-------------------------------------------------------------------*/
    3933             : 
    3934             : /*! r: number of bits written */
    3935      683430 : static int16_t write_fixed_rate_direction(
    3936             :     BSTR_ENC_HANDLE hMetaData,   /* i  : MASA metadata structure                        */
    3937             :     IVAS_QDIRECTION *qdirection, /* i/o: quantized directional parameters               */
    3938             :     const int16_t j_idx,         /* i  : index of subband for which the data is written */
    3939             :     const int16_t len            /* i  : number of data                                 */
    3940             : )
    3941             : {
    3942             :     int16_t nbits, i;
    3943             : 
    3944      683430 :     nbits = 0;
    3945     2130666 :     for ( i = 0; i < len; i++ )
    3946             :     {
    3947     1447236 :         push_next_indice( hMetaData, qdirection->band_data[j_idx].spherical_index[i], qdirection->band_data[j_idx].bits_sph_idx[i] );
    3948     1447236 :         nbits += qdirection->band_data[j_idx].bits_sph_idx[i];
    3949             :     }
    3950             : 
    3951      683430 :     return nbits;
    3952             : }
    3953             : 
    3954             : 
    3955             : /*-------------------------------------------------------------------*
    3956             :  * joint_encoding()
    3957             :  *
    3958             :  * joint encoding of elevation and azimuth
    3959             :  *-------------------------------------------------------------------*/
    3960             : 
    3961      537784 : static void joint_encoding(
    3962             :     IVAS_QDIRECTION *q_direction,  /* i/o: quantized directional parameters                         */
    3963             :     const int16_t j,               /* i  : subband index                                            */
    3964             :     const int16_t next_j,          /* i  : next subband index                                       */
    3965             :     const int16_t coding_subbands, /* i  : total number of subband                                  */
    3966             :     int16_t *bits_dir0,            /* i/o: number of bits for each tile in each subband             */
    3967             :     const int16_t allowed_bits,    /* i  : maximum number of bits available for the current subband */
    3968             :     BSTR_ENC_HANDLE hMetaData,     /* i/o: metadata bitstream handle                                */
    3969             :     int16_t *diff                  /* o  : bits to be given/taken to next subband                   */
    3970             : )
    3971             : {
    3972             :     int16_t k;
    3973             :     int16_t GR_ord_azimuth, use_context, GR_ord_elevation;
    3974             :     uint8_t method;
    3975             :     int16_t nbits;
    3976             :     int16_t same;
    3977             :     uint16_t data[MAX_PARAM_SPATIAL_SUBFRAMES];
    3978      537784 :     int16_t len_data = 0;
    3979             :     int16_t no_symb_ele[MAX_PARAM_SPATIAL_SUBFRAMES];
    3980             : 
    3981     1844171 :     for ( k = 0; k < q_direction->cfg.nblocks; k++ )
    3982             :     {
    3983     1306387 :         q_direction->band_data[j].bits_sph_idx[k] = bits_dir0[k];
    3984             : 
    3985             :         /* requantize the direction */
    3986     2612774 :         q_direction->band_data[j].spherical_index[k] = quantize_direction( q_direction->band_data[j].elevation[k], q_direction->band_data[j].azimuth[k], q_direction->band_data[j].bits_sph_idx[k], &q_direction->band_data[j].elevation[k],
    3987     1306387 :                                                                            &q_direction->band_data[j].azimuth[k], &q_direction->band_data[j].elevation_index[k], &q_direction->band_data[j].azimuth_index[k], q_direction->cfg.mc_ls_setup );
    3988             : 
    3989     1306387 :         if ( bits_dir0[k] >= 3 )
    3990             :         {
    3991     1298096 :             if ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID )
    3992             :             {
    3993      273832 :                 q_direction->band_data[j].elevation_m_alphabet[k] = no_theta_masa[bits_dir0[k] - 3];
    3994      273832 :                 q_direction->band_data[j].azimuth_m_alphabet[k] = no_phi_masa[bits_dir0[k] - 1][q_direction->band_data[j].elevation_index[k]];
    3995             :             }
    3996             :             else
    3997             :             {
    3998     1024264 :                 q_direction->band_data[j].elevation_m_alphabet[k] = no_theta_masa[bits_dir0[k] - 3] * 2 - 1;
    3999     1024264 :                 q_direction->band_data[j].azimuth_m_alphabet[k] = no_phi_masa[bits_dir0[k] - 1][( q_direction->band_data[j].elevation_index[k] + 1 ) >> 1];
    4000             :             }
    4001     1298096 :             assert( q_direction->band_data[j].elevation_index[k] != MASA_NO_INDEX );
    4002             :         }
    4003        8291 :         else if ( bits_dir0[k] > 0 )
    4004             :         {
    4005        8291 :             q_direction->band_data[j].elevation_m_alphabet[k] = 1;
    4006        8291 :             q_direction->band_data[j].azimuth_m_alphabet[k] = no_phi_masa[bits_dir0[k] - 1][0];
    4007             :         }
    4008             :         else
    4009             :         {
    4010           0 :             q_direction->band_data[j].elevation_m_alphabet[k] = 1;
    4011           0 :             q_direction->band_data[j].azimuth_m_alphabet[k] = 1;
    4012             :         }
    4013             :     }
    4014             : 
    4015     1844171 :     for ( k = 0; k < q_direction->cfg.nblocks; k++ )
    4016             :     {
    4017     1306387 :         if ( q_direction->band_data[j].bits_sph_idx[k] <= 2 )
    4018             :         {
    4019        8291 :             q_direction->band_data[j].elevation_index[k] = MASA_NO_INDEX;
    4020             :         }
    4021             :         else
    4022             :         {
    4023     1298096 :             no_symb_ele[len_data] = q_direction->band_data[j].elevation_m_alphabet[k];
    4024     1298096 :             data[len_data++] = q_direction->band_data[j].elevation_index[k];
    4025             :         }
    4026             :     }
    4027             : 
    4028             : 
    4029             :     /* encode indexes for current subband and count the number of bits */
    4030             : 
    4031      537784 :     if ( q_direction->cfg.nblocks == 1 && q_direction->band_data[j].bits_sph_idx[0] <= MASA_MIN_BITS_TF + 1 )
    4032             :     {
    4033             :         /* encode with fixed rate only if only one subframe and very low number of bits */
    4034      147915 :         nbits = write_fixed_rate_direction( hMetaData, q_direction, j, q_direction->cfg.nblocks );
    4035             :     }
    4036             :     else
    4037             :     {
    4038             : 
    4039      389869 :         if ( len_data > 0 )
    4040             :         {
    4041      389865 :             nbits = GR_bits_new( data, no_symb_ele, len_data, MASA_GR_ORD_EL, 1, &GR_ord_elevation );
    4042             :         }
    4043             :         else
    4044             :         {
    4045           4 :             nbits = 0;
    4046           4 :             GR_ord_elevation = MASA_GR_ORD_EL;
    4047             :         }
    4048             : 
    4049      389869 :         same = 1;
    4050     1158472 :         for ( k = 1; k < q_direction->cfg.nblocks; k++ )
    4051             :         {
    4052      768603 :             if ( q_direction->band_data[j].elevation_index[k] != q_direction->band_data[j].elevation_index[0] )
    4053             :             {
    4054      217435 :                 same = 0;
    4055             :             }
    4056             :         }
    4057      389869 :         if ( same == 1 && q_direction->band_data[j].elevation_index[0] < 4 )
    4058             :         {
    4059      249345 :             nbits = 3;
    4060             :         }
    4061             :         else
    4062             :         {
    4063      140524 :             same = 0;
    4064      140524 :             nbits += 1;
    4065             :         }
    4066             : 
    4067      779738 :         nbits += GR_bits_azimuth_context( q_direction->band_data[j].azimuth_index,
    4068      389869 :                                           q_direction->band_data[j].azimuth_m_alphabet, q_direction->cfg.nblocks, MASA_GR_ORD_AZ,
    4069      389869 :                                           q_direction->band_data[j].bits_sph_idx, &GR_ord_azimuth, &use_context );
    4070             : 
    4071      389869 :         if ( allowed_bits == 0 )
    4072             :         {
    4073           0 :             nbits = 0;
    4074             :         }
    4075             :         else
    4076             :         {
    4077      389869 :             if ( nbits >= allowed_bits )
    4078             :             {
    4079      227668 :                 nbits = allowed_bits + 1; /* fixed rate encoding */
    4080      227668 :                 method = 1;
    4081      227668 :                 push_next_indice( hMetaData, method, 1 );
    4082             : 
    4083             :                 /* write current subband data */
    4084      227668 :                 nbits = 1 + write_fixed_rate_direction( hMetaData, q_direction, j, q_direction->cfg.nblocks );
    4085             :             }
    4086             :             else
    4087             :             {
    4088      162201 :                 nbits += 1; /* EC coding */
    4089      162201 :                 method = 0;
    4090      162201 :                 push_next_indice( hMetaData, method, 1 );
    4091             : 
    4092             :                 /* write current subband data */
    4093      162201 :                 write_ec_direction( &nbits, hMetaData, q_direction, j, q_direction->cfg.nblocks, GR_ord_elevation, GR_ord_azimuth, use_context, same );
    4094      162201 :                 nbits++;
    4095             :             }
    4096             :         }
    4097             :     }
    4098      537784 :     *diff += nbits - allowed_bits;
    4099      537784 :     update_bits_next_block( q_direction, diff, next_j, coding_subbands, q_direction->cfg.nblocks );
    4100             : 
    4101      537784 :     return;
    4102             : }
    4103             : 
    4104             : 
    4105             : /*-------------------------------------------------------------------*
    4106             :  * calculate_two_distances()
    4107             :  *
    4108             :  * calculate estimated distortions if encoding with VQ or not
    4109             :  *-------------------------------------------------------------------*/
    4110             : 
    4111       70916 : static void calculate_two_distances(
    4112             :     float *el,                /* i  : elevation values                  */
    4113             :     int16_t *bits,            /* i  : number of bits for each tile      */
    4114             :     const int16_t total_bits, /* i  : total number of bits for subband  */
    4115             :     const int16_t len,        /* i  : number of tiles                   */
    4116             :     float *p_d1,              /* o  : first distortion                  */
    4117             :     float *p_d2               /* o  : second distortion                 */
    4118             : )
    4119             : {
    4120             :     int16_t i;
    4121             :     float d1, d2, el_av;
    4122       70916 :     const float cos_delta_phi_cb[] = { 0.848f, 0.8988f, 0.9272f, 0.9563f, 0.9744f, 0.9816f, 0.9877f, 0.9925f };
    4123             :     float var_el;
    4124             : 
    4125       70916 :     d1 = 0.0f;
    4126       70916 :     d2 = 0.0f;
    4127             : 
    4128       70916 :     el_av = mean( el, len );
    4129       70916 :     if ( total_bits > 9 )
    4130             :     {
    4131      321445 :         for ( i = 0; i < len; i++ )
    4132             :         {
    4133      257156 :             if ( bits[i] > 2 )
    4134             :             {
    4135      181172 :                 if ( fabsf( el[i] ) < fabsf( ( fabsf( el[i] ) - 45 ) ) )
    4136             :                 {
    4137             :                     /* el_hat  = 0*/
    4138      102075 :                     if ( bits[i] == 3 )
    4139             :                     {
    4140      102075 :                         d1 += 1 - 0.7f * cosf( el[i] * PI_OVER_180 );
    4141             :                     }
    4142             :                     else
    4143             :                     {
    4144           0 :                         d1 += 1 - 0.92f * cosf( el[i] * PI_OVER_180 );
    4145             :                     }
    4146             :                 }
    4147             :                 else
    4148             :                 {
    4149       79097 :                     if ( bits[i] == 3 )
    4150             :                     {
    4151       79097 :                         d1 += 1 - sinf( el[i] * PI_OVER_180 ) * 0.7f * sign( el[i] );
    4152             :                     }
    4153             :                     else
    4154             :                     {
    4155           0 :                         d1 += 1 - 0.7f * 0.92f * cosf( el[i] * PI_OVER_180 ) - sinf( fabsf( el[i] * PI_OVER_180 ) ) * 0.7f;
    4156             :                     }
    4157             :                 }
    4158             :             }
    4159             :             else
    4160             :             {
    4161       75984 :                 if ( bits[i] == 2 )
    4162             :                 {
    4163       75984 :                     d1 += 1 - cosf( el[i] * PI_OVER_180 ) * 0.7f;
    4164             :                 }
    4165             :                 else
    4166             :                 {
    4167           0 :                     d1 += 1;
    4168             :                 }
    4169             :             }
    4170      257156 :             d2 += 1 - sinf( el_av * PI_OVER_180 ) * sinf( el[i] * PI_OVER_180 ) - cosf( el[i] * PI_OVER_180 ) * cosf( el_av * PI_OVER_180 ) * cos_delta_phi_cb[total_bits - 9];
    4171             :         }
    4172             :     }
    4173             : 
    4174       70916 :     var_el = var( el, len );
    4175       70916 :     if ( var_el > 1300.0f )
    4176             :     {
    4177        1194 :         d2 = d1 + 0.1f;
    4178             :     }
    4179             : 
    4180       70916 :     *p_d1 = d1;
    4181       70916 :     *p_d2 = d2;
    4182             : 
    4183       70916 :     return;
    4184             : }
    4185             : 
    4186             : 
    4187             : /*-------------------------------------------------------------------*
    4188             :  * write_ec_direction()
    4189             :  *
    4190             :  * write metadata using entropy encoding
    4191             :  *-------------------------------------------------------------------*/
    4192             : 
    4193             : /*! r: number of bits written */
    4194      162201 : static ivas_error write_ec_direction(
    4195             :     int16_t *num_bits_written,      /* o  : Number of bits written                          */
    4196             :     BSTR_ENC_HANDLE hMetaData,      /* i  : MASA metadata structure                         */
    4197             :     IVAS_QDIRECTION *qdirection,    /* i  : quantized directional info                      */
    4198             :     const int16_t j_idx,            /* i  : index of subband to encode and write            */
    4199             :     const int16_t len,              /* i  : number of tiles                                 */
    4200             :     const int16_t GR_ord_elevation, /* i  : GR order for elevation encoding                 */
    4201             :     const int16_t GR_ord_azimuth,   /* i  : GR order for azimuth encoding                   */
    4202             :     const int16_t use_context,      /* i  : flag for context usiage in azimuth encoding     */
    4203             :     const int16_t same              /* i  : flag if elevation indexes are the same or not   */
    4204             : )
    4205             : {
    4206             :     int16_t i, nbits, bits_crt, nr_NO_INDEX;
    4207             :     uint16_t data;
    4208             :     int16_t min_val, max_val;
    4209             : 
    4210      162201 :     nr_NO_INDEX = 0;
    4211             : 
    4212      162201 :     nbits = 0;
    4213             : 
    4214             :     /* write elevation */
    4215      795561 :     for ( i = 0; i < len; i++ )
    4216             :     {
    4217      633360 :         data = qdirection->band_data[j_idx].elevation_index[i];
    4218      633360 :         if ( ( data == MASA_NO_INDEX ) || ( qdirection->band_data[j_idx].bits_sph_idx[i] == 0 ) )
    4219             :         {
    4220          12 :             nr_NO_INDEX += 1;
    4221             :         }
    4222             :     }
    4223             : 
    4224      162201 :     if ( nr_NO_INDEX < len )
    4225             :     {
    4226      162201 :         if ( same == 1 )
    4227             :         {
    4228      123193 :             push_next_indice( hMetaData, 1, 1 );
    4229      123193 :             nbits += 1;
    4230      123193 :             push_next_indice( hMetaData, qdirection->band_data[j_idx].elevation_index[0], 2 );
    4231      123193 :             nbits += 2;
    4232             :         }
    4233             :         else
    4234             :         {
    4235       39008 :             push_next_indice( hMetaData, 0, 1 );
    4236       39008 :             nbits += 1;
    4237             : 
    4238       39008 :             push_next_indice( hMetaData, 1 - ( GR_ord_elevation == MASA_GR_ORD_EL ), 1 );
    4239       39008 :             nbits += 1;
    4240             : 
    4241      195028 :             for ( i = 0; i < len; i++ )
    4242             :             {
    4243      156020 :                 data = qdirection->band_data[j_idx].elevation_index[i];
    4244      156020 :                 if ( data < MASA_NO_INDEX )
    4245             :                 {
    4246      156008 :                     bits_crt = hMetaData->nb_bits_tot;
    4247      156008 :                     ivas_qmetadata_encode_extended_gr( hMetaData, data, qdirection->band_data[j_idx].elevation_m_alphabet[i], GR_ord_elevation );
    4248      156008 :                     nbits += hMetaData->nb_bits_tot - bits_crt;
    4249             :                 }
    4250             :             }
    4251             :         }
    4252             :     }
    4253             : 
    4254             :     /* write azimuth */
    4255      162201 :     if ( use_context < 0 )
    4256             :     {
    4257      162201 :         if ( use_context == -1 )
    4258             :         {
    4259             :             /* regular GR coding */
    4260       62664 :             push_next_indice( hMetaData, 0, 1 );
    4261       62664 :             nbits += 1;
    4262       62664 :             push_next_indice( hMetaData, 1 - ( GR_ord_azimuth == MASA_GR_ORD_AZ ), 1 );
    4263       62664 :             nbits += 1;
    4264             : 
    4265      297882 :             for ( i = 0; i < len; i++ )
    4266             :             {
    4267      235218 :                 data = qdirection->band_data[j_idx].azimuth_index[i];
    4268      235218 :                 if ( data < MASA_NO_INDEX )
    4269             :                 {
    4270      234703 :                     bits_crt = hMetaData->nb_bits_tot;
    4271      234703 :                     ivas_qmetadata_encode_extended_gr( hMetaData, data, qdirection->band_data[j_idx].azimuth_m_alphabet[i], GR_ord_azimuth );
    4272      234703 :                     nbits += hMetaData->nb_bits_tot - bits_crt;
    4273             :                 }
    4274             :             }
    4275             :         }
    4276       99537 :         else if ( use_context == -2 )
    4277             :         {
    4278             :             /* min removed GR coding */
    4279       99454 :             push_next_indice( hMetaData, 1, 1 );
    4280       99454 :             nbits += 1;
    4281       99454 :             push_next_indice( hMetaData, 1 - ( GR_ord_azimuth == MASA_GR_ORD_AZ - 1 ), 1 );
    4282       99454 :             nbits += 1;
    4283             : 
    4284             :             /* find min */
    4285       99454 :             min_val = MASA_NO_INDEX;
    4286      497270 :             for ( i = 0; i < len; i++ )
    4287             :             {
    4288      397816 :                 if ( qdirection->band_data[j_idx].azimuth_index[i] < min_val )
    4289             :                 {
    4290      125820 :                     min_val = qdirection->band_data[j_idx].azimuth_index[i];
    4291             :                 }
    4292             :             }
    4293             : 
    4294             : #ifdef DEBUGGING
    4295             :             if ( min_val == MASA_NO_INDEX )
    4296             :             {
    4297             :                 return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "No azimuth data to be coded in write_ec_direction()" );
    4298             :             }
    4299             : #endif
    4300             : 
    4301             :             /* write min*/
    4302       99454 :             bits_crt = hMetaData->nb_bits_tot;
    4303       99454 :             maximum_s( qdirection->band_data[j_idx].azimuth_m_alphabet, len, &max_val );
    4304       99454 :             ivas_qmetadata_encode_extended_gr( hMetaData, min_val, max_val, MASA_GR_ORD_AZ );
    4305       99454 :             nbits += hMetaData->nb_bits_tot - bits_crt;
    4306             : 
    4307      497270 :             for ( i = 0; i < len; i++ )
    4308             :             {
    4309      397816 :                 data = qdirection->band_data[j_idx].azimuth_index[i] - min_val;
    4310      397816 :                 if ( data < MASA_NO_INDEX - min_val )
    4311             :                 {
    4312      397774 :                     bits_crt = hMetaData->nb_bits_tot;
    4313      397774 :                     ivas_qmetadata_encode_extended_gr( hMetaData, data, qdirection->band_data[j_idx].azimuth_m_alphabet[i], GR_ord_azimuth );
    4314      397774 :                     nbits += hMetaData->nb_bits_tot - bits_crt;
    4315             :                 }
    4316             :             }
    4317             :         }
    4318             : #ifdef DEBUGGING
    4319             :         else
    4320             :         {
    4321             :             if ( use_context != -3 )
    4322             :             {
    4323             :                 return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong use_context value in write_ec_direction()" );
    4324             :             }
    4325             :         }
    4326             : #endif
    4327             :     }
    4328             :     else
    4329             :     {
    4330           0 :         for ( i = 0; i < len; i++ )
    4331             :         {
    4332           0 :             data = qdirection->band_data[j_idx].azimuth_index[i];
    4333           0 :             if ( data < MASA_NO_INDEX )
    4334             :             {
    4335           0 :                 switch ( qdirection->band_data[j_idx].bits_sph_idx[i] )
    4336             :                 {
    4337           0 :                     case 0:
    4338           0 :                         break;
    4339           0 :                     case 1:
    4340           0 :                         nbits += 1;
    4341           0 :                         push_next_indice( hMetaData, data, 1 );
    4342           0 :                         break;
    4343           0 :                     case 2:
    4344           0 :                         bits_crt = hMetaData->nb_bits_tot;
    4345           0 :                         ivas_qmetadata_encode_extended_gr( hMetaData, data, qdirection->band_data[j_idx].azimuth_m_alphabet[i], MASA_GR_ORD_AZ - 1 );
    4346           0 :                         nbits += hMetaData->nb_bits_tot - bits_crt;
    4347           0 :                         break;
    4348           0 :                     default:
    4349           0 :                         bits_crt = hMetaData->nb_bits_tot;
    4350           0 :                         ivas_qmetadata_encode_extended_gr( hMetaData, data, qdirection->band_data[j_idx].azimuth_m_alphabet[i], MASA_GR_ORD_AZ );
    4351           0 :                         nbits += hMetaData->nb_bits_tot - bits_crt;
    4352           0 :                         break;
    4353             :                 }
    4354           0 :             }
    4355             :         }
    4356             :     }
    4357             : 
    4358      162201 :     *num_bits_written = nbits;
    4359      162201 :     return IVAS_ERR_OK;
    4360             : }
    4361             : 
    4362             : 
    4363             : /*-----------------------------------------------------------------------*
    4364             :  * Local functions (coherence Q and coding)
    4365             :  *-----------------------------------------------------------------------*/
    4366             : 
    4367             : /*! r: index */
    4368      957368 : static uint64_t create_combined_index(
    4369             :     uint16_t *idx_dct,       /* i  : indexes to combine */
    4370             :     const int16_t len,       /* i  : number of indexes */
    4371             :     const int16_t *no_cb_vec /* i  : how many codewords for each position */
    4372             : )
    4373             : {
    4374             :     int16_t i;
    4375             :     uint64_t idx, base;
    4376             : 
    4377      957368 :     base = 1;
    4378      957368 :     idx = 0;
    4379     8387942 :     for ( i = 0; i < len; i++ )
    4380             :     {
    4381     7430574 :         idx += base * idx_dct[i];
    4382     7430574 :         base *= no_cb_vec[i];
    4383             :     }
    4384             : 
    4385      957368 :     return idx;
    4386             : }
    4387             : 
    4388             : 
    4389             : /*-----------------------------------------------------------------------*
    4390             :  * encoding DCT0 coeffs with joint index
    4391             :  *-----------------------------------------------------------------------*/
    4392             : 
    4393             : /*! r: number of bits written */
    4394      577703 : static int16_t encode_coherence_indexesDCT0(
    4395             :     uint16_t *idx_dct,  /* i  : indexes to be encoded                 */
    4396             :     const int16_t len,  /* i  : number of indexes                     */
    4397             :     int16_t *no_cb_vec, /* i  : number of codewords for each position */
    4398             :     BSTR_ENC_HANDLE hMetaData,
    4399             :     const int16_t indice_coherence,
    4400             :     const int16_t nbits,
    4401             :     const int16_t nbits1 )
    4402             : {
    4403             :     int16_t i;
    4404             :     uint64_t idx;
    4405             :     int16_t no_idx16;
    4406             :     int16_t k;
    4407             :     int16_t half_len, j;
    4408             :     uint64_t idx1;
    4409             : 
    4410             :     /* calculate bits for dct0 components with joint encoding */
    4411      577703 :     if ( nbits1 > 0 )
    4412             :     {
    4413       11085 :         half_len = len / 2;
    4414       11085 :         idx = create_combined_index( idx_dct, half_len, no_cb_vec );
    4415       11085 :         idx1 = create_combined_index( &idx_dct[half_len], half_len, &no_cb_vec[half_len] );
    4416             :     }
    4417             :     else
    4418             :     {
    4419      566618 :         idx = create_combined_index( idx_dct, len, no_cb_vec );
    4420      566618 :         idx1 = 0;
    4421             :     }
    4422             : 
    4423      577703 :     if ( nbits % 16 == 0 )
    4424             :     {
    4425       12063 :         no_idx16 = nbits / 16;
    4426             :     }
    4427             :     else
    4428             :     {
    4429      565640 :         no_idx16 = (int16_t) round_f( ( nbits / 16.0f + 0.5f ) );
    4430             :     }
    4431             : 
    4432      577703 :     k = nbits;
    4433      577703 :     i = 0;
    4434      718804 :     for ( i = 0; i < no_idx16 - 1; i++ )
    4435             :     {
    4436      141101 :         k -= 16;
    4437      141101 :         hMetaData->ind_list[indice_coherence + i].value = ( ( idx >> k ) & 65535 ); /* 16 bits */
    4438             :     }
    4439      577703 :     hMetaData->ind_list[indice_coherence + i].value = ( idx & ( ( 1 << k ) - 1 ) );
    4440             : 
    4441      577703 :     if ( nbits1 > 0 )
    4442             :     {
    4443       11085 :         if ( nbits1 % 16 == 0 )
    4444             :         {
    4445         268 :             no_idx16 = nbits1 / 16;
    4446             :         }
    4447             :         else
    4448             :         {
    4449       10817 :             no_idx16 = (int16_t) round_f( ( nbits1 / 16.0f + 0.5f ) );
    4450             :         }
    4451             : 
    4452       11085 :         k = nbits1;
    4453             : 
    4454       25018 :         for ( j = i + 1; j < no_idx16 + i; j++ )
    4455             :         {
    4456       13933 :             k -= 16;
    4457       13933 :             hMetaData->ind_list[indice_coherence + j].value = ( ( idx1 >> k ) & 65535 ); /* 16 bits */
    4458             :         }
    4459       11085 :         hMetaData->ind_list[indice_coherence + j].value = ( idx1 & ( ( 1 << k ) - 1 ) );
    4460             :     }
    4461             : 
    4462      577703 :     return nbits + nbits1;
    4463             : }
    4464             : 
    4465             : 
    4466             : /*-------------------------------------------------------------------*
    4467             :  * coherence_coding_length()
    4468             :  *
    4469             :  *
    4470             :  *-------------------------------------------------------------------*/
    4471             : 
    4472     1093689 : static int16_t coherence_coding_length(
    4473             :     const uint16_t *idx_sur_coh_shift,
    4474             :     const uint8_t idx_shift_len,
    4475             :     const int16_t coding_subbands,
    4476             :     const int16_t *no_cv,
    4477             :     uint16_t *mr_idx,
    4478             :     int16_t *no_cv_shift,
    4479             :     int16_t *p_min_idx,
    4480             :     int16_t *GR_ord,
    4481             :     int16_t *nbits_fr,
    4482             :     int16_t *nbits_fr1 )
    4483             : {
    4484             :     int16_t half_coding_subbands;
    4485             :     int16_t j;
    4486             :     int16_t nbits;
    4487             :     uint64_t no_cb;
    4488             :     int16_t min_idx;
    4489             : 
    4490     1093689 :     half_coding_subbands = 0;
    4491             : 
    4492     1093689 :     if ( sum_s( no_cv, coding_subbands ) > MASA_COH_LIMIT_2IDX )
    4493             :     {
    4494             : 
    4495      128734 :         no_cb = 1;
    4496      128734 :         half_coding_subbands = coding_subbands / 2;
    4497     1561652 :         for ( j = 0; j < half_coding_subbands; j++ )
    4498             :         {
    4499     1432918 :             no_cb *= no_cv[j];
    4500             :         }
    4501      128734 :         *nbits_fr = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 );
    4502      128734 :         no_cb = 1;
    4503     1568614 :         for ( j = half_coding_subbands; j < coding_subbands; j++ )
    4504             :         {
    4505     1439880 :             no_cb *= no_cv[j];
    4506             :         }
    4507      128734 :         *nbits_fr1 = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 );
    4508             :     }
    4509             :     else
    4510             :     {
    4511      964955 :         no_cb = 1;
    4512    11434144 :         for ( j = 0; j < coding_subbands; j++ )
    4513             :         {
    4514    10469189 :             no_cb *= no_cv[j];
    4515             :         }
    4516      964955 :         *nbits_fr = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 );
    4517      964955 :         *nbits_fr1 = 0;
    4518             :     }
    4519             : 
    4520             : 
    4521     1093689 :     minimum_s( (const int16_t *) idx_sur_coh_shift, (int16_t) idx_shift_len, &min_idx );
    4522    13486467 :     for ( j = 0; j < idx_shift_len; j++ )
    4523             :     {
    4524    12392778 :         mr_idx[j] = idx_sur_coh_shift[j] - min_idx;
    4525    12392778 :         no_cv_shift[j] -= min_idx;
    4526             :     }
    4527     1093689 :     nbits = min_idx + 1 + GR_bits_new( mr_idx, no_cv_shift, idx_shift_len, *GR_ord, 1, GR_ord );
    4528     1093689 :     *p_min_idx = min_idx;
    4529             : 
    4530     1093689 :     return nbits;
    4531             : }
    4532             : 
    4533             : 
    4534             : /*-------------------------------------------------------------------*
    4535             :  * encode_spread_coherence_1sf()
    4536             :  *
    4537             :  * Encoding spread coherence for 1 subframe bands
    4538             :  *-------------------------------------------------------------------*/
    4539             : 
    4540             : /*! r: number of bits written */
    4541      263276 : static int16_t encode_spread_coherence_1sf(
    4542             :     IVAS_QMETADATA *q_metadata,    /* i  : quantized metadata                        */
    4543             :     const int16_t idx_d,           /* i  : current direction index                   */
    4544             :     BSTR_ENC_HANDLE hMasaMetaData, /* i/o: metadata bitstream handle                 */
    4545             :     const int16_t hrmasa_flag      /* i  : flag indicating high-rate MASA MD coding  */
    4546             : )
    4547             : {
    4548             :     int16_t i, j, k;
    4549             :     int16_t idx_ER;
    4550             :     int16_t nbits, nbits_fr;
    4551             :     uint16_t idx_sp_coh[MASA_MAXIMUM_CODING_SUBBANDS];
    4552             :     uint16_t mr_idx_sp_coh[MASA_MAXIMUM_CODING_SUBBANDS];
    4553             :     int16_t GR_ord, bits_GR;
    4554             :     uint64_t idx, idx1;
    4555             :     int16_t no_idx16;
    4556             :     int16_t no_cv[MASA_MAXIMUM_CODING_SUBBANDS];
    4557             :     IVAS_QDIRECTION *q_direction;
    4558             :     int16_t half_coding_subbands, nbits_fr1, coding_subbands;
    4559             :     uint16_t idx_sp_coh_shift[MASA_MAXIMUM_CODING_SUBBANDS];
    4560             :     uint8_t idx_shift;
    4561      263276 :     int16_t max_val = 0, nbits_max;
    4562             :     int16_t extra_cv;
    4563             :     int16_t no_cv_shift[MASA_MAXIMUM_CODING_SUBBANDS], min_idx;
    4564             : 
    4565      263276 :     coding_subbands = q_metadata->q_direction[idx_d].cfg.nbands;
    4566      263276 :     q_direction = &( q_metadata->q_direction[idx_d] );
    4567      263276 :     nbits = 0;
    4568      263276 :     GR_ord = 1;
    4569      263276 :     idx_shift = 0;
    4570             : 
    4571             :     /* number of codevectors added dependent on number of subbands */
    4572      263276 :     extra_cv = coding_subbands / MASA_FACTOR_CV_COH;
    4573     3125903 :     for ( j = 0; j < coding_subbands; j++ )
    4574             :     {
    4575     2862627 :         if ( hrmasa_flag )
    4576             :         {
    4577           0 :             idx_ER = 7 - ( q_direction->band_data[j].energy_ratio_index_mod[0] >> 1 ) + extra_cv;
    4578             :         }
    4579             :         else
    4580             :         {
    4581     2862627 :             idx_ER = 7 - q_direction->band_data[j].energy_ratio_index_mod[0] + extra_cv;
    4582             :         }
    4583             : 
    4584     2862627 :         if ( idx_ER > 0 )
    4585             :         {
    4586     2708889 :             idx_sp_coh[j] = (uint16_t) roundf( q_direction->coherence_band_data[j].spread_coherence[0] / ( 255.0f / (float) idx_ER ) );
    4587     2708889 :             q_direction->coherence_band_data[j].spread_coherence[0] = (uint8_t) roundf( idx_sp_coh[j] * ( 255.0f / (float) idx_ER ) );
    4588             :         }
    4589             :         else
    4590             :         {
    4591      153738 :             idx_sp_coh[j] = 0;
    4592      153738 :             q_direction->coherence_band_data[j].spread_coherence[0] = 0;
    4593             :         }
    4594     2862627 :         no_cv[j] = idx_ER + 1;
    4595             : 
    4596     2862627 :         no_cv_shift[idx_shift] = no_cv[j];
    4597     2862627 :         idx_sp_coh_shift[idx_shift++] = idx_sp_coh[j];
    4598             :     }
    4599             : 
    4600      263276 :     if ( sum_s( no_cv, coding_subbands ) == coding_subbands )
    4601             :     {
    4602        8811 :         return 0;
    4603             :     }
    4604             : 
    4605      254465 :     nbits_max = 0;
    4606      254465 :     if ( coding_subbands > MASA_LIMIT_NO_BANDS_SUR_COH )
    4607             :     {
    4608      158456 :         j = maximum_s( (int16_t *) idx_sp_coh, coding_subbands, &max_val );
    4609     2569049 :         for ( j = 0; j < coding_subbands; j++ )
    4610             :         {
    4611     2410593 :             if ( no_cv[j] > max_val + 1 )
    4612             :             {
    4613     2125776 :                 no_cv[j] = max_val + 1;
    4614             :             }
    4615             :         }
    4616      158456 :         nbits_max = MASA_MAX_NO_CV_SUR_COH - max_val + extra_cv;
    4617             :     }
    4618             : 
    4619      254465 :     nbits = coherence_coding_length( idx_sp_coh_shift, idx_shift, coding_subbands, no_cv,
    4620             :                                      mr_idx_sp_coh, no_cv_shift, &min_idx, &GR_ord, &nbits_fr, &nbits_fr1 );
    4621      254465 :     half_coding_subbands = 0;
    4622      254465 :     idx1 = 0;
    4623             : 
    4624      254465 :     if ( nbits_fr + nbits_fr1 + nbits_max < nbits )
    4625             :     {
    4626             :         /* write flag*/
    4627      115348 :         push_next_indice( hMasaMetaData, 0, 1 );
    4628             : 
    4629             :         /* create combined index */
    4630      115348 :         nbits = nbits_fr + nbits_fr1 + 1;
    4631             : 
    4632      115348 :         if ( coding_subbands > MASA_LIMIT_NO_BANDS_SUR_COH )
    4633             :         {
    4634             :             /* write max value*/
    4635       43358 :             bits_GR = hMasaMetaData->nb_bits_tot;
    4636       43358 :             ivas_qmetadata_encode_extended_gr( hMasaMetaData, MASA_MAX_NO_CV_SUR_COH - max_val - 1 + extra_cv, MASA_MAX_NO_CV_SUR_COH + extra_cv, 0 );
    4637       43358 :             nbits += hMasaMetaData->nb_bits_tot - bits_GR;
    4638             :         }
    4639             : 
    4640      115348 :         if ( nbits_fr1 > 0 )
    4641             :         {
    4642        1304 :             half_coding_subbands = coding_subbands / 2;
    4643        1304 :             idx = create_combined_index( idx_sp_coh, half_coding_subbands, no_cv );
    4644        1304 :             idx1 = create_combined_index( &idx_sp_coh[half_coding_subbands], half_coding_subbands, &no_cv[half_coding_subbands] );
    4645             :         }
    4646             :         else
    4647             :         {
    4648      114044 :             idx = create_combined_index( idx_sp_coh, coding_subbands, no_cv );
    4649             :         }
    4650             : 
    4651      115348 :         if ( nbits_fr % 16 == 0 )
    4652             :         {
    4653       37441 :             no_idx16 = nbits_fr / 16;
    4654             :         }
    4655             :         else
    4656             :         {
    4657       77907 :             no_idx16 = (int16_t) round_f( ( nbits_fr / 16.0f + 0.5f ) );
    4658             :         }
    4659             : 
    4660             :         /* write combined index */
    4661      115348 :         k = nbits_fr;
    4662      123255 :         for ( i = 0; i < no_idx16 - 1; i++ )
    4663             :         {
    4664        7907 :             k -= 16;
    4665        7907 :             push_next_indice( hMasaMetaData, ( ( idx >> k ) & 65535 ), 16 ); /* 16 bits */
    4666             :         }
    4667             : 
    4668      115348 :         push_next_indice( hMasaMetaData, ( idx & ( ( 1 << k ) - 1 ) ), k );
    4669             : 
    4670      115348 :         if ( nbits_fr1 > 0 )
    4671             :         {
    4672        1304 :             if ( nbits_fr1 % 16 == 0 )
    4673             :             {
    4674          95 :                 no_idx16 = nbits_fr1 / 16;
    4675             :             }
    4676             :             else
    4677             :             {
    4678        1209 :                 no_idx16 = (int16_t) round_f( ( nbits_fr1 / 16.0f + 0.5f ) );
    4679             :             }
    4680             : 
    4681        1304 :             assert( no_idx16 <= 4 );
    4682             : 
    4683        1304 :             k = nbits_fr1;
    4684        2851 :             for ( i = 0; i < no_idx16 - 1; i++ )
    4685             :             {
    4686        1547 :                 k -= 16;
    4687        1547 :                 push_next_indice( hMasaMetaData, ( ( idx1 >> k ) & 65535 ), 16 ); /* 16 bits */
    4688             :             }
    4689        1304 :             push_next_indice( hMasaMetaData, ( idx1 & ( ( 1 << k ) - 1 ) ), k );
    4690             :         }
    4691             :     }
    4692             :     else
    4693             :     {
    4694             :         /* write flag */
    4695      139117 :         nbits = 1;
    4696             : 
    4697             :         /* write flag*/
    4698      139117 :         push_next_indice( hMasaMetaData, 1, 1 );
    4699             : 
    4700             :         /* write GR_ord */
    4701      139117 :         push_next_indice( hMasaMetaData, GR_ord, 1 );
    4702      139117 :         nbits += 1;
    4703             : 
    4704             :         /* write the min */
    4705      139117 :         bits_GR = hMasaMetaData->nb_bits_tot;
    4706      139117 :         ivas_qmetadata_encode_extended_gr( hMasaMetaData, min_idx, MASA_MAX_NO_CV_SUR_COH + extra_cv, 0 );
    4707      139117 :         nbits += hMasaMetaData->nb_bits_tot - bits_GR;
    4708             : 
    4709             :         /* write GR data */
    4710     2027711 :         for ( j = 0; j < idx_shift; j++ )
    4711             :         {
    4712     1888594 :             bits_GR = hMasaMetaData->nb_bits_tot;
    4713     1888594 :             ivas_qmetadata_encode_extended_gr( hMasaMetaData, mr_idx_sp_coh[j], no_cv_shift[j], GR_ord );
    4714     1888594 :             nbits += hMasaMetaData->nb_bits_tot - bits_GR;
    4715             :         }
    4716             :     }
    4717             : 
    4718      254465 :     return nbits;
    4719             : }
    4720             : 
    4721             : 
    4722             : /*-------------------------------------------------------------------*
    4723             :  * encode_surround_coherence()
    4724             :  *
    4725             :  * encoding surround coherence
    4726             :  *-------------------------------------------------------------------*/
    4727             : 
    4728             : /*! r: number of bits written */
    4729      651062 : static int16_t encode_surround_coherence(
    4730             :     IVAS_QMETADATA *hQMetaData, /* i  : quantized metadata            */
    4731             :     BSTR_ENC_HANDLE hMetaData   /* i/o: metadata bitstream handle     */
    4732             : )
    4733             : {
    4734             :     int16_t i, j, k;
    4735             :     int16_t idx_ER, idx16;
    4736             :     int16_t nbits, nbits_fr;
    4737             :     uint16_t idx_sur_coh[MASA_MAXIMUM_CODING_SUBBANDS];
    4738             :     uint16_t mr_idx_sur_coh[MASA_MAXIMUM_CODING_SUBBANDS];
    4739             :     int16_t GR_ord, bits_GR;
    4740             :     uint64_t idx, idx1;
    4741             :     int16_t no_idx16;
    4742             :     int16_t no_cv[MASA_MAXIMUM_CODING_SUBBANDS];
    4743             :     float error_ratio_surr;
    4744             :     IVAS_QDIRECTION *q_direction;
    4745             :     int16_t half_coding_subbands, nbits_fr1, coding_subbands;
    4746             :     int16_t all_coherence_zero;
    4747             :     uint16_t idx_sur_coh_shift[MASA_MAXIMUM_CODING_SUBBANDS];
    4748             :     uint8_t idx_shift;
    4749      651062 :     int16_t max_val = 0, nbits_max;
    4750             :     int16_t no_cv_shift[MASA_MAXIMUM_CODING_SUBBANDS], min_idx;
    4751             : 
    4752      651062 :     coding_subbands = hQMetaData->q_direction[0].cfg.nbands;
    4753      651062 :     all_coherence_zero = hQMetaData->all_coherence_zero;
    4754      651062 :     q_direction = &( hQMetaData->q_direction[0] );
    4755      651062 :     nbits = 0;
    4756             : 
    4757      651062 :     if ( all_coherence_zero == 1 )
    4758             :     {
    4759           0 :         nbits = 0;
    4760             :     }
    4761             :     else
    4762             :     {
    4763      651062 :         GR_ord = 1;
    4764      651062 :         k = 0;
    4765      651062 :         idx_shift = 0;
    4766     6809515 :         for ( j = 0; j < coding_subbands; j++ )
    4767             :         {
    4768     6158453 :             if ( hQMetaData->no_directions == 2 )
    4769             :             {
    4770     1798806 :                 k += hQMetaData->twoDirBands[j];
    4771     1798806 :                 idx16 = max( k - 1, 0 );
    4772     1798806 :                 error_ratio_surr = 1.0f - q_direction[0].band_data[j].energy_ratio[0] - q_direction[1].band_data[idx16].energy_ratio[0] * hQMetaData->twoDirBands[j];
    4773             :             }
    4774             :             else
    4775             :             {
    4776     4359647 :                 error_ratio_surr = 1.0f - q_direction[0].band_data[j].energy_ratio[0];
    4777             :             }
    4778             : 
    4779     6158453 :             if ( error_ratio_surr <= 0 )
    4780             :             {
    4781      383049 :                 error_ratio_surr = 0;
    4782      383049 :                 idx_sur_coh[j] = 0;
    4783      383049 :                 no_cv[j] = 1;
    4784      383049 :                 hQMetaData->surcoh_band_data[j].surround_coherence[0] = 0; /* sur_coherence_cb_masa[idx_cb_sur_coh_masa[DIRAC_DIFFUSE_LEVELS - 1] * MASA_MAX_NO_CV_SUR_COH]; */
    4785             :             }
    4786             :             else
    4787             :             {
    4788     5775404 :                 idx_ER = masa_sq( error_ratio_surr, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS );
    4789             : 
    4790    11550808 :                 idx_sur_coh[j] = squant_int( hQMetaData->surcoh_band_data[j].surround_coherence[0], &hQMetaData->surcoh_band_data[j].surround_coherence[0],
    4791     5775404 :                                              &sur_coherence_cb_masa[idx_cb_sur_coh_masa[idx_ER] * MASA_MAX_NO_CV_SUR_COH], idx_cb_sur_coh_masa[idx_ER] + 2 );
    4792             : 
    4793     5775404 :                 no_cv[j] = idx_cb_sur_coh_masa[idx_ER] + 2;
    4794     5775404 :                 no_cv_shift[idx_shift] = no_cv[j];
    4795     5775404 :                 idx_sur_coh_shift[idx_shift++] = idx_sur_coh[j];
    4796             :             }
    4797             :         }
    4798             : 
    4799      651062 :         if ( sum_s( no_cv, coding_subbands ) == coding_subbands )
    4800             :         {
    4801       11789 :             return 0;
    4802             :         }
    4803             : 
    4804      639273 :         nbits_max = 0;
    4805      639273 :         if ( coding_subbands > MASA_LIMIT_NO_BANDS_SUR_COH )
    4806             :         {
    4807      235429 :             j = maximum_s( (int16_t *) idx_sur_coh, coding_subbands, &max_val );
    4808     4158529 :             for ( j = 0; j < coding_subbands; j++ )
    4809             :             {
    4810     3923100 :                 if ( no_cv[j] > max_val + 1 )
    4811             :                 {
    4812     2814126 :                     no_cv[j] = max_val + 1;
    4813             :                 }
    4814             :             }
    4815      235429 :             nbits_max = MASA_MAX_NO_CV_SUR_COH - max_val; /* encoded with GR0 as max_no_vals - no_vals*/
    4816             :         }
    4817             : 
    4818      639273 :         nbits = coherence_coding_length( idx_sur_coh_shift, idx_shift, coding_subbands, no_cv,
    4819             :                                          mr_idx_sur_coh, no_cv_shift, &min_idx, &GR_ord, &nbits_fr, &nbits_fr1 );
    4820      639273 :         half_coding_subbands = coding_subbands / 2;
    4821      639273 :         idx1 = 0;
    4822             : 
    4823             :         /* should check how to encode the average - check distribution */
    4824      639273 :         if ( nbits_fr + nbits_fr1 + nbits_max < nbits )
    4825             :         {
    4826             :             /* write flag*/
    4827      168839 :             push_next_indice( hMetaData, 0, 1 );
    4828             : 
    4829             :             /* create combined index */
    4830      168839 :             nbits = nbits_fr + nbits_fr1 + 1;
    4831      168839 :             if ( coding_subbands > MASA_LIMIT_NO_BANDS_SUR_COH )
    4832             :             {
    4833             :                 /* write max value*/
    4834       58629 :                 bits_GR = hMetaData->nb_bits_tot;
    4835       58629 :                 ivas_qmetadata_encode_extended_gr( hMetaData, MASA_MAX_NO_CV_SUR_COH - max_val - 1, MASA_MAX_NO_CV_SUR_COH, 0 );
    4836       58629 :                 nbits += hMetaData->nb_bits_tot - bits_GR;
    4837             :             }
    4838             : 
    4839      168839 :             if ( nbits_fr1 > 0 )
    4840             :             {
    4841       17649 :                 idx = create_combined_index( idx_sur_coh, half_coding_subbands, no_cv );
    4842       17649 :                 idx1 = create_combined_index( &idx_sur_coh[half_coding_subbands], half_coding_subbands, &no_cv[half_coding_subbands] );
    4843             :             }
    4844             :             else
    4845             :             {
    4846      151190 :                 idx = create_combined_index( idx_sur_coh, coding_subbands, no_cv );
    4847             :             }
    4848             : 
    4849      168839 :             if ( nbits_fr % 16 == 0 )
    4850             :             {
    4851       21447 :                 no_idx16 = nbits_fr / 16;
    4852             :             }
    4853             :             else
    4854             :             {
    4855      147392 :                 no_idx16 = (int16_t) round_f( ( nbits_fr / 16.0f + 0.5f ) );
    4856             :             }
    4857             : 
    4858             :             /* write combined index */
    4859      168839 :             k = nbits_fr;
    4860      226944 :             for ( i = 0; i < no_idx16 - 1; i++ )
    4861             :             {
    4862       58105 :                 k -= 16;
    4863       58105 :                 push_next_indice( hMetaData, ( ( idx >> k ) & 65535 ), 16 ); /* 16 bits */
    4864             :             }
    4865             : 
    4866      168839 :             push_next_indice( hMetaData, ( idx & ( ( 1 << k ) - 1 ) ), k );
    4867             : 
    4868      168839 :             if ( nbits_fr1 > 0 )
    4869             :             {
    4870       17649 :                 if ( nbits_fr1 % 16 == 0 )
    4871             :                 {
    4872        1421 :                     no_idx16 = nbits_fr1 / 16;
    4873             :                 }
    4874             :                 else
    4875             :                 {
    4876       16228 :                     no_idx16 = (int16_t) round_f( ( nbits_fr1 / 16.0f + 0.5f ) );
    4877             :                 }
    4878             : 
    4879       17649 :                 assert( no_idx16 <= 4 );
    4880             : 
    4881       17649 :                 k = nbits_fr1;
    4882       38238 :                 for ( i = 0; i < no_idx16 - 1; i++ )
    4883             :                 {
    4884       20589 :                     k -= 16;
    4885       20589 :                     push_next_indice( hMetaData, ( ( idx1 >> k ) & 65535 ), 16 ); /* 16 bits */
    4886             :                 }
    4887             : 
    4888       17649 :                 push_next_indice( hMetaData, ( idx1 & ( ( 1 << k ) - 1 ) ), k );
    4889             :             }
    4890             :         }
    4891             :         else
    4892             :         {
    4893             :             /* write flag */
    4894      470434 :             nbits = 1;
    4895             : 
    4896             :             /* write flag*/
    4897      470434 :             push_next_indice( hMetaData, 1, 1 );
    4898             : 
    4899             :             /* write GR_ord */
    4900      470434 :             push_next_indice( hMetaData, GR_ord, 1 );
    4901      470434 :             nbits += 1;
    4902             : 
    4903             :             /* write the min */
    4904      470434 :             bits_GR = hMetaData->nb_bits_tot;
    4905      470434 :             ivas_qmetadata_encode_extended_gr( hMetaData, min_idx, MASA_MAX_NO_CV_SUR_COH, 0 );
    4906      470434 :             nbits += hMetaData->nb_bits_tot - bits_GR;
    4907             : 
    4908             :             /* write GR data */
    4909     4828924 :             for ( j = 0; j < idx_shift; j++ )
    4910             :             {
    4911     4358490 :                 bits_GR = hMetaData->nb_bits_tot;
    4912             : 
    4913     4358490 :                 ivas_qmetadata_encode_extended_gr( hMetaData, mr_idx_sur_coh[j], no_cv_shift[j], GR_ord );
    4914             : 
    4915     4358490 :                 nbits += hMetaData->nb_bits_tot - bits_GR;
    4916             :             }
    4917             :         }
    4918             :     }
    4919             : #ifdef DEBUGGING
    4920             :     for ( i = 0; i < coding_subbands; i++ )
    4921             :     {
    4922             :         for ( j = 1; j < q_direction->cfg.nblocks; j++ )
    4923             :         {
    4924             :             hQMetaData->surcoh_band_data[i].surround_coherence[j] = hQMetaData->surcoh_band_data[i].surround_coherence[0];
    4925             :         }
    4926             :     }
    4927             : #endif
    4928             : 
    4929      639273 :     return nbits;
    4930             : }
    4931             : 
    4932             : 
    4933       64390 : static int16_t encode_surround_coherence_hr(
    4934             :     IVAS_QMETADATA *hQMetaData, /* i  : quantized metadata            */
    4935             :     BSTR_ENC_HANDLE hMetaData   /* i/o: metadata bitstream handle     */
    4936             : )
    4937             : {
    4938             :     int16_t i, j, k, sf;
    4939             :     int16_t nbits, nbits_fr, nbits_sf;
    4940             :     uint16_t idx_sur_coh[MASA_MAXIMUM_CODING_SUBBANDS];
    4941             :     uint16_t mr_idx_sur_coh[MASA_MAXIMUM_CODING_SUBBANDS];
    4942             :     int16_t GR_ord, bits_GR;
    4943             :     uint64_t idx, idx1;
    4944             :     int16_t no_idx16;
    4945             :     int16_t no_cv[MASA_MAXIMUM_CODING_SUBBANDS];
    4946             :     float error_ratio_surr;
    4947             :     IVAS_QDIRECTION *q_direction;
    4948             :     int16_t half_coding_subbands, nbits_fr1, coding_subbands;
    4949             :     int16_t all_coherence_zero;
    4950             :     uint16_t idx_sur_coh_shift[MASA_MAXIMUM_CODING_SUBBANDS];
    4951             :     uint8_t idx_shift;
    4952       64390 :     int16_t max_val = 0, nbits_max;
    4953             :     int16_t no_cv_shift[MASA_MAXIMUM_CODING_SUBBANDS], min_idx;
    4954             :     int16_t idx16;
    4955             :     int32_t int_error_ratio_surr;
    4956             : 
    4957       64390 :     coding_subbands = hQMetaData->q_direction[0].cfg.nbands;
    4958       64390 :     all_coherence_zero = hQMetaData->all_coherence_zero;
    4959       64390 :     q_direction = &( hQMetaData->q_direction[0] );
    4960       64390 :     nbits = 0;
    4961             : 
    4962       64390 :     if ( all_coherence_zero == 1 )
    4963             :     {
    4964           0 :         nbits = 0;
    4965             :     }
    4966             :     else
    4967             :     {
    4968      267485 :         for ( sf = 0; sf < hQMetaData->q_direction[0].cfg.nblocks; sf++ )
    4969             :         {
    4970      203095 :             GR_ord = 1;
    4971      203095 :             k = 0;
    4972      203095 :             idx_shift = 0;
    4973     4785174 :             for ( j = 0; j < coding_subbands; j++ )
    4974             :             {
    4975     4582079 :                 if ( hQMetaData->no_directions == 2 )
    4976             :                 {
    4977     1316214 :                     k += hQMetaData->twoDirBands[j];
    4978     1316214 :                     idx16 = max( k - 1, 0 );
    4979     1316214 :                     error_ratio_surr = 1.0f - q_direction[0].band_data[j].energy_ratio[sf] - q_direction[1].band_data[idx16].energy_ratio[sf] * hQMetaData->twoDirBands[j];
    4980             :                 }
    4981             :                 else
    4982             :                 {
    4983     3265865 :                     error_ratio_surr = 1.0f - q_direction[0].band_data[j].energy_ratio[sf];
    4984             :                 }
    4985             : 
    4986     4582079 :                 int_error_ratio_surr = (int32_t) ( MASA_SUR_COH_PRECISION * error_ratio_surr );
    4987     4582079 :                 error_ratio_surr = (float) ( int_error_ratio_surr * MASA_SUR_COH_THRESHOLD );
    4988             : 
    4989     4582079 :                 if ( error_ratio_surr <= 0 )
    4990             :                 {
    4991      792196 :                     error_ratio_surr = 0;
    4992      792196 :                     idx_sur_coh[j] = 0;
    4993      792196 :                     no_cv[j] = 1;
    4994      792196 :                     hQMetaData->surcoh_band_data[j].surround_coherence[sf] = 0; /* sur_coherence_cb_masa[idx_cb_sur_coh_masa[DIRAC_DIFFUSE_LEVELS - 1] * MASA_MAX_NO_CV_SUR_COH]; */
    4995             :                 }
    4996             :                 else
    4997             :                 {
    4998     7579766 :                     idx_sur_coh[j] = squant_int( hQMetaData->surcoh_band_data[j].surround_coherence[sf], &hQMetaData->surcoh_band_data[j].surround_coherence[sf],
    4999     3789883 :                                                  &sur_coherence_cb_masa[idx_cb_sur_coh_masa[7] * MASA_MAX_NO_CV_SUR_COH], idx_cb_sur_coh_masa[7] + 2 );
    5000     3789883 :                     no_cv[j] = idx_cb_sur_coh_masa[7] + 2;
    5001     3789883 :                     no_cv_shift[idx_shift] = no_cv[j];
    5002     3789883 :                     idx_sur_coh_shift[idx_shift++] = idx_sur_coh[j];
    5003             :                 }
    5004             :             }
    5005             : 
    5006      203095 :             if ( sum_s( no_cv, coding_subbands ) != coding_subbands )
    5007             :             {
    5008      199951 :                 nbits_max = 0;
    5009      199951 :                 if ( coding_subbands > MASA_LIMIT_NO_BANDS_SUR_COH )
    5010             :                 {
    5011      189971 :                     j = maximum_s( (int16_t *) idx_sur_coh, coding_subbands, &max_val );
    5012     4647525 :                     for ( j = 0; j < coding_subbands; j++ )
    5013             :                     {
    5014     4457554 :                         if ( no_cv[j] > max_val + 1 )
    5015             :                         {
    5016     3211825 :                             no_cv[j] = max_val + 1;
    5017             :                         }
    5018             :                     }
    5019      189971 :                     nbits_max = MASA_MAX_NO_CV_SUR_COH - max_val; /* encoded with GR0 as max_no_vals - no_vals*/
    5020             :                 }
    5021      199951 :                 if ( max_val == 0 )
    5022             :                 {
    5023      856008 :                     for ( j = 0; j < coding_subbands; j++ )
    5024             :                     {
    5025      813992 :                         hQMetaData->surcoh_band_data[j].surround_coherence[sf] = 0;
    5026             :                     }
    5027             :                 }
    5028      199951 :                 nbits_sf = coherence_coding_length( idx_sur_coh_shift, idx_shift, coding_subbands, no_cv,
    5029             :                                                     mr_idx_sur_coh, no_cv_shift, &min_idx, &GR_ord, &nbits_fr, &nbits_fr1 );
    5030      199951 :                 half_coding_subbands = coding_subbands / 2;
    5031      199951 :                 idx1 = 0;
    5032             : 
    5033             :                 /* should check how to encode the average - check distribution */
    5034      199951 :                 if ( nbits_fr + nbits_fr1 + nbits_max < nbits_sf )
    5035             :                 {
    5036             :                     /* write flag*/
    5037       45180 :                     push_next_indice( hMetaData, 0, 1 );
    5038             : 
    5039             :                     /* create combined index */
    5040       45180 :                     nbits += nbits_fr + nbits_fr1 + 1;
    5041       45180 :                     if ( coding_subbands > MASA_LIMIT_NO_BANDS_SUR_COH )
    5042             :                     {
    5043             :                         /* write max value*/
    5044       45093 :                         bits_GR = hMetaData->nb_bits_tot;
    5045       45093 :                         ivas_qmetadata_encode_extended_gr( hMetaData, MASA_MAX_NO_CV_SUR_COH - max_val - 1, MASA_MAX_NO_CV_SUR_COH, 0 );
    5046       45093 :                         nbits += hMetaData->nb_bits_tot - bits_GR;
    5047             :                     }
    5048             : 
    5049       45180 :                     if ( nbits_fr1 > 0 )
    5050             :                     {
    5051       20260 :                         idx = create_combined_index( idx_sur_coh, half_coding_subbands, no_cv );
    5052       20260 :                         idx1 = create_combined_index( &idx_sur_coh[half_coding_subbands], half_coding_subbands, &no_cv[half_coding_subbands] );
    5053             :                     }
    5054             :                     else
    5055             :                     {
    5056       24920 :                         idx = create_combined_index( idx_sur_coh, coding_subbands, no_cv );
    5057             :                     }
    5058             : 
    5059       45180 :                     if ( nbits_fr % 16 == 0 )
    5060             :                     {
    5061       22044 :                         no_idx16 = nbits_fr / 16;
    5062             :                     }
    5063             :                     else
    5064             :                     {
    5065       23136 :                         no_idx16 = (int16_t) round_f( ( nbits_fr / 16.0f + 0.5f ) );
    5066             :                     }
    5067             : 
    5068             :                     /* write combined index */
    5069       45180 :                     k = nbits_fr;
    5070       91255 :                     for ( i = 0; i < no_idx16 - 1; i++ )
    5071             :                     {
    5072       46075 :                         k -= 16;
    5073       46075 :                         push_next_indice( hMetaData, ( ( idx >> k ) & 65535 ), 16 ); /* 16 bits */
    5074             :                     }
    5075             : 
    5076       45180 :                     push_next_indice( hMetaData, ( idx & ( ( 1 << k ) - 1 ) ), k );
    5077             : 
    5078       45180 :                     if ( nbits_fr1 > 0 )
    5079             :                     {
    5080       20260 :                         if ( nbits_fr1 % 16 == 0 )
    5081             :                         {
    5082        2862 :                             no_idx16 = nbits_fr1 / 16;
    5083             :                         }
    5084             :                         else
    5085             :                         {
    5086       17398 :                             no_idx16 = (int16_t) round_f( ( nbits_fr1 / 16.0f + 0.5f ) );
    5087             :                         }
    5088             : 
    5089       20260 :                         assert( no_idx16 <= 4 );
    5090             : 
    5091       20260 :                         k = nbits_fr1;
    5092       53831 :                         for ( i = 0; i < no_idx16 - 1; i++ )
    5093             :                         {
    5094       33571 :                             k -= 16;
    5095       33571 :                             push_next_indice( hMetaData, ( ( idx1 >> k ) & 65535 ), 16 ); /* 16 bits */
    5096             :                         }
    5097             : 
    5098       20260 :                         push_next_indice( hMetaData, ( idx1 & ( ( 1 << k ) - 1 ) ), k );
    5099             :                     }
    5100             :                 }
    5101             :                 else
    5102             :                 {
    5103             :                     /* write flag */
    5104      154771 :                     nbits += 1;
    5105             : 
    5106             :                     /* write flag*/
    5107      154771 :                     push_next_indice( hMetaData, 1, 1 );
    5108             : 
    5109             :                     /* write GR_ord */
    5110      154771 :                     push_next_indice( hMetaData, GR_ord, 1 );
    5111      154771 :                     nbits += 1;
    5112             : 
    5113             :                     /* write the min */
    5114      154771 :                     bits_GR = hMetaData->nb_bits_tot;
    5115      154771 :                     ivas_qmetadata_encode_extended_gr( hMetaData, min_idx, MASA_MAX_NO_CV_SUR_COH, 0 );
    5116      154771 :                     nbits += hMetaData->nb_bits_tot - bits_GR;
    5117             : 
    5118             :                     /* write GR data */
    5119     3042768 :                     for ( j = 0; j < idx_shift; j++ )
    5120             :                     {
    5121     2887997 :                         bits_GR = hMetaData->nb_bits_tot;
    5122             : 
    5123     2887997 :                         ivas_qmetadata_encode_extended_gr( hMetaData, mr_idx_sur_coh[j], no_cv_shift[j], GR_ord );
    5124             : 
    5125     2887997 :                         nbits += hMetaData->nb_bits_tot - bits_GR;
    5126             :                     }
    5127             :                 }
    5128             :             }
    5129             :         }
    5130             :     }
    5131             : 
    5132       64390 :     return nbits;
    5133             : }
    5134             : 
    5135             : 
    5136             : /*-------------------------------------------------------------------*
    5137             :  * quantize_DCT_0_coh()
    5138             :  *
    5139             :  * quanization of DCT component of order zero for transformed coherence vector
    5140             :  *-------------------------------------------------------------------*/
    5141             : 
    5142             : /*! r: quantized value */
    5143     3957213 : static float quantize_DCT_0_coh(
    5144             :     const float x,                /* i  : input value                                                */
    5145             :     const int16_t j,              /* i  : subband index                                              */
    5146             :     const float *coherence_cb,    /* i  : coherence codebook                                         */
    5147             :     const float delta_var,        /* i  : azimuth variance threshold                                 */
    5148             :     const int16_t no_cb,          /* i  : maximum number of codewords                                */
    5149             :     IVAS_QDIRECTION *q_direction, /* i  : quantized metadata                                         */
    5150             :     uint16_t *idx_x,              /* o  : codewords index                                            */
    5151             :     int16_t *p_no_cb,             /* o  : actual number of codewords dependent on energy ratio value */
    5152             :     const int16_t hrmasa_flag     /* i  : flag indicating high-rate MASA MD coding                   */
    5153             : )
    5154             : {
    5155             :     float var_azi, xhat;
    5156             :     int16_t idx_sub_cb, idx;
    5157             :     int16_t min_index;
    5158             :     /* quantize first DCT component */
    5159     3957213 :     var_azi = var( q_direction->band_data[j].azimuth, q_direction->cfg.nblocks );
    5160             : 
    5161     3957213 :     if ( hrmasa_flag )
    5162             :     {
    5163           0 :         minimum_s( (int16_t *) ( q_direction->band_data[j].energy_ratio_index ), q_direction->cfg.nblocks, &min_index );
    5164           0 :         min_index = min_index >> 1;
    5165             :     }
    5166             :     else
    5167             :     {
    5168     3957213 :         min_index = q_direction->band_data[j].energy_ratio_index[0];
    5169             :     }
    5170             : 
    5171     3957213 :     if ( var_azi < delta_var )
    5172             :     {
    5173     1610307 :         idx_sub_cb = no_cb * min_index;
    5174             :     }
    5175             :     else
    5176             :     {
    5177     2346906 :         idx_sub_cb = no_cb * ( min_index + DIRAC_DIFFUSE_LEVELS );
    5178             :     }
    5179             : 
    5180     3957213 :     idx = squant( x, &xhat, &coherence_cb[idx_sub_cb], len_cb_dct0_masa[min_index] );
    5181             : 
    5182     3957213 :     *p_no_cb = len_cb_dct0_masa[min_index];
    5183     3957213 :     *idx_x = idx;
    5184             : 
    5185     3957213 :     return xhat;
    5186             : }
    5187             : 
    5188             : 
    5189             : /*-------------------------------------------------------------------*
    5190             :  * encode_coherence_indexesDCT1()
    5191             :  *
    5192             :  * Encoding DCT1 coeffs with joint index or EC
    5193             :  *-------------------------------------------------------------------*/
    5194             : 
    5195             : /*! r: number of bits written */
    5196      577703 : static int16_t encode_coherence_indexesDCT1(
    5197             :     uint16_t *idx_dct,        /* i  : data to be encoded   */
    5198             :     const int16_t len,        /* i  : number of data       */
    5199             :     BSTR_ENC_HANDLE hMetaData /* i  : metadata handle      */
    5200             : )
    5201             : {
    5202             :     int16_t i, nbits, GR_ord;
    5203             :     uint16_t av;
    5204             :     uint16_t mr_idx_dct[MASA_MAXIMUM_CODING_SUBBANDS];
    5205             : 
    5206      577703 :     GR_ord = 0;
    5207      577703 :     nbits = 0;
    5208             : 
    5209      577703 :     nbits = mean_removed_GR_new( idx_dct, MASA_NO_CV_COH1, len, 0, &GR_ord, &av, mr_idx_dct );
    5210             : 
    5211     4534916 :     for ( i = 0; i < len; i++ )
    5212             :     {
    5213     3957213 :         ivas_qmetadata_encode_extended_gr( hMetaData, mr_idx_dct[i], 2 * MASA_NO_CV_COH1, GR_ord );
    5214             :     }
    5215             : 
    5216      577703 :     nbits += len_huf_masa[av];
    5217             : 
    5218      577703 :     push_next_indice( hMetaData, huff_code_av_masa[av], len_huf_masa[av] );
    5219             : 
    5220      577703 :     return nbits;
    5221             : }
    5222             : 
    5223             : 
    5224             : /*-------------------------------------------------------------------*
    5225             :  * dct4_transform()
    5226             :  *
    5227             :  * 4D implementation of DCT transform
    5228             :  *-------------------------------------------------------------------*/
    5229             : 
    5230     7914426 : static void dct4_transform(
    5231             :     uint8_t *v,  /* i  : input 4D vector */
    5232             :     float *dct_v /* o  : output transformed vector */
    5233             : )
    5234             : {
    5235             :     float a, b, c, d;
    5236             : 
    5237     7914426 :     a = ( v[0] + v[3] ) / 256.0f;
    5238     7914426 :     b = ( v[1] + v[2] ) / 256.0f;
    5239     7914426 :     c = ( v[0] - v[3] ) / 256.0f;
    5240     7914426 :     d = ( v[1] - v[2] ) / 256.0f;
    5241             : 
    5242     7914426 :     dct_v[0] = 0.5f * ( a + b );
    5243     7914426 :     dct_v[1] = 0.653281482438188f * c + 0.270598050073099f * d;
    5244     7914426 :     dct_v[2] = 0.5f * ( a - b );
    5245     7914426 :     dct_v[3] = 0.270598050073099f * c - 0.653281482438188f * d;
    5246             : 
    5247     7914426 :     return;
    5248             : }
    5249             : 
    5250             : 
    5251             : /*-------------------------------------------------------------------*
    5252             :  * ivas_qmetadata_quantize_coherence_hr_512()
    5253             :  *
    5254             :  *
    5255             :  *-------------------------------------------------------------------*/
    5256             : 
    5257       83969 : static int16_t ivas_qmetadata_quantize_coherence_hr_512(
    5258             :     IVAS_QMETADATA *hQMetaData,       /* i/o: quantized metadata            */
    5259             :     const int16_t idx_d,              /* i  : current direction index       */
    5260             :     const int16_t all_coherence_zero, /* i  : all coherence is zero - flag  */
    5261             :     BSTR_ENC_HANDLE hMetaData,        /* i  : metadata handle               */
    5262             :     const int16_t bits_coh )
    5263             : {
    5264             :     int16_t j, k;
    5265             :     int16_t nbands, nblocks;
    5266             :     int16_t nbits;
    5267             :     int16_t nbits1, nbits0, nbits_av;
    5268             :     uint16_t idx_coh[MASA_MAXIMUM_CODING_SUBBANDS];
    5269             :     IVAS_QDIRECTION *q_direction;
    5270             :     int16_t cbsize;
    5271             :     float delta, tmp;
    5272             :     int16_t min_idx, GR_param, GR_param_av;
    5273             :     uint16_t av, mr_idx[MASA_MAXIMUM_CODING_SUBBANDS];
    5274             : 
    5275       83969 :     q_direction = &( hQMetaData->q_direction[idx_d] );
    5276       83969 :     nbands = q_direction->cfg.nbands;
    5277       83969 :     nblocks = q_direction->cfg.nblocks;
    5278       83969 :     nbits = 0;
    5279             : 
    5280       83969 :     if ( all_coherence_zero == 1 )
    5281             :     {
    5282           0 :         return nbits;
    5283             :     }
    5284       83969 :     nbits = hMetaData->nb_bits_tot;
    5285             : 
    5286       83969 :     cbsize = 1 << bits_coh;
    5287       83969 :     delta = 256.0f / cbsize;
    5288             : 
    5289      347461 :     for ( k = 0; k < nblocks; k++ )
    5290             :     {
    5291      263492 :         min_idx = 0;
    5292     5671352 :         for ( j = 0; j < nbands; j++ )
    5293             :         {
    5294     5407860 :             idx_coh[j] = usquant( (float) ( q_direction->coherence_band_data[j].spread_coherence[k] ), &tmp, delta / 2.0f, delta, cbsize );
    5295     5407860 :             q_direction->coherence_band_data[j].spread_coherence[k] = (uint8_t) ( idx_coh[j] * delta + delta / 2.0f );
    5296     5407860 :             if ( idx_coh[j] < min_idx )
    5297             :             {
    5298           0 :                 min_idx = idx_coh[j];
    5299             :             }
    5300             :         }
    5301             : 
    5302      263492 :         nbits0 = 0;
    5303      263492 :         nbits1 = 0;
    5304     5671352 :         for ( j = 0; j < nbands; j++ )
    5305             :         {
    5306     5407860 :             idx_coh[j] = idx_coh[j] - min_idx;
    5307     5407860 :             nbits0 += ivas_qmetadata_encode_extended_gr_length( idx_coh[j], cbsize - min_idx, 0 );
    5308     5407860 :             nbits1 += ivas_qmetadata_encode_extended_gr_length( idx_coh[j], cbsize - min_idx, 1 );
    5309             :         }
    5310      263492 :         if ( nbits0 < nbits1 )
    5311             :         {
    5312      168197 :             GR_param = 0;
    5313      168197 :             nbits1 = nbits0;
    5314             :         }
    5315             :         else
    5316             :         {
    5317       95295 :             GR_param = 1;
    5318             :         }
    5319             : 
    5320      263492 :         GR_param_av = 1;
    5321      263492 :         nbits_av = mean_removed_GR_new( idx_coh, cbsize, nbands, 1, &GR_param_av, &av, mr_idx );
    5322             : 
    5323      263492 :         if ( nbits_av < nbits1 )
    5324             :         {
    5325       55688 :             nbits1 = nbits_av;
    5326       55688 :             GR_param = GR_param_av;
    5327             : 
    5328             :             /* use average removed */
    5329       55688 :             push_next_indice( hMetaData, 1, 1 );
    5330             : 
    5331             :             /* write average */
    5332       55688 :             push_next_indice( hMetaData, av, bits_coh );
    5333             : 
    5334             :             /*  write GR param */
    5335       55688 :             push_next_indice( hMetaData, GR_param, 1 );
    5336             : 
    5337     1254597 :             for ( j = 0; j < nbands; j++ )
    5338             :             {
    5339     1198909 :                 ivas_qmetadata_encode_extended_gr( hMetaData, mr_idx[j], 2 * cbsize, GR_param );
    5340             :             }
    5341             :         }
    5342             :         else
    5343             :         {
    5344             :             /* use min removed */
    5345      207804 :             push_next_indice( hMetaData, 0, 1 );
    5346             : 
    5347             :             /* write min index */
    5348      207804 :             push_next_indice( hMetaData, min_idx, bits_coh );
    5349             : 
    5350             :             /*  write GR param */
    5351      207804 :             push_next_indice( hMetaData, GR_param, 1 );
    5352             : 
    5353     4416755 :             for ( j = 0; j < nbands; j++ )
    5354             :             {
    5355     4208951 :                 ivas_qmetadata_encode_extended_gr( hMetaData, idx_coh[j], cbsize - min_idx, GR_param );
    5356             :             }
    5357             :         }
    5358             :     }
    5359             : 
    5360       83969 :     nbits = hMetaData->nb_bits_tot - nbits;
    5361       83969 :     return nbits;
    5362             : }
    5363             : 
    5364             : 
    5365             : /*-------------------------------------------------------------------*
    5366             :  * ivas_qmetadata_quantize_coherence()
    5367             :  *
    5368             :  *
    5369             :  *-------------------------------------------------------------------*/
    5370             : 
    5371             : /*! r: number of bits written */
    5372     1418682 : static int16_t ivas_qmetadata_quantize_coherence(
    5373             :     IVAS_QMETADATA *hQMetaData,       /* i/o: quantized metadata                        */
    5374             :     const int16_t idx_d,              /* i  : current direction index                   */
    5375             :     const int16_t all_coherence_zero, /* i  : all coherence is zero - flag              */
    5376             :     BSTR_ENC_HANDLE hMetaData,        /* i  : metadata handle                           */
    5377             :     const int16_t write_flag,         /* i  : flag to actually write the data or not    */
    5378             :     int16_t *indice_coherence,
    5379             :     const int16_t hrmasa_flag /* i  : flag indicating high-rate MASA MD coding  */
    5380             : )
    5381             : {
    5382             :     int16_t j, k;
    5383             :     float dct_coh[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES];
    5384             :     uint16_t idx_dct[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_MAXIMUM_CODING_SUBBANDS];
    5385             :     int16_t coding_subbands;
    5386             :     int16_t nbits;
    5387             :     uint64_t no_cb;
    5388             :     int16_t MASA_grouping[MASA_MAXIMUM_CODING_SUBBANDS];
    5389             :     int16_t nbits1;
    5390             :     int16_t coding_subbands_0, d;
    5391             :     int16_t two_dir_band[MASA_MAXIMUM_CODING_SUBBANDS];
    5392             :     int16_t no_cb_vec[MASA_MAXIMUM_CODING_SUBBANDS];
    5393             :     IVAS_QDIRECTION *q_direction;
    5394             :     int16_t min_index;
    5395     1418682 :     min_index = 0;
    5396     1418682 :     q_direction = &( hQMetaData->q_direction[idx_d] );
    5397     1418682 :     coding_subbands = q_direction->cfg.nbands;
    5398     1418682 :     nbits = 0;
    5399             : 
    5400     1418682 :     if ( all_coherence_zero == 1 )
    5401             :     {
    5402           0 :         return nbits;
    5403             :     }
    5404             : 
    5405     1418682 :     if ( hQMetaData->q_direction[idx_d].cfg.nblocks == 1 )
    5406             :     {
    5407      263276 :         nbits = encode_spread_coherence_1sf( hQMetaData, idx_d, hMetaData, hrmasa_flag );
    5408             : 
    5409      263276 :         return nbits;
    5410             :     }
    5411             :     else
    5412             :     {
    5413     1155406 :         k = 0;
    5414     1155406 :         no_cb = 1;
    5415     1155406 :         coding_subbands_0 = hQMetaData->q_direction[0].cfg.nbands;
    5416     1155406 :         if ( coding_subbands_0 <= 5 )
    5417             :         {
    5418     4838520 :             for ( j = 0; j < 5; j++ )
    5419             :             {
    5420     4032100 :                 MASA_grouping[j] = j;
    5421             :             }
    5422             :         }
    5423             :         else
    5424             :         {
    5425      348986 :             if ( coding_subbands_0 <= 8 )
    5426             :             {
    5427       97708 :                 mvs2s( MASA_grouping_8_to_5, MASA_grouping, 8 );
    5428             :             }
    5429      251278 :             else if ( coding_subbands_0 <= 12 )
    5430             :             {
    5431       85892 :                 mvs2s( MASA_grouping_12_to_5, MASA_grouping, 12 );
    5432             :             }
    5433      165386 :             else if ( coding_subbands_0 <= 18 )
    5434             :             {
    5435       96582 :                 mvs2s( MASA_grouping_18_to_5, MASA_grouping, 18 );
    5436             :             }
    5437             :             else
    5438             :             {
    5439       68804 :                 if ( coding_subbands_0 <= 24 )
    5440             :                 {
    5441       68804 :                     mvs2s( MASA_grouping_24_to_5, MASA_grouping, 24 );
    5442             :                 }
    5443             :             }
    5444             :         }
    5445             : 
    5446     1155406 :         if ( coding_subbands < coding_subbands_0 )
    5447             :         {
    5448      245186 :             d = 0;
    5449     2155814 :             for ( j = 0; j < coding_subbands_0; j++ )
    5450             :             {
    5451     1910628 :                 if ( hQMetaData->twoDirBands[j] == 1 )
    5452             :                 {
    5453      721358 :                     two_dir_band[d++] = j;
    5454             :                 }
    5455             :             }
    5456             :         }
    5457             : 
    5458     9069832 :         for ( j = 0; j < coding_subbands; j++ )
    5459             :         {
    5460             :             /* DCT transform */
    5461     7914426 :             dct4_transform( hQMetaData->q_direction[idx_d].coherence_band_data[j].spread_coherence, dct_coh[j] );
    5462             : 
    5463     7914426 :             if ( hrmasa_flag )
    5464             :             {
    5465           0 :                 minimum_s( (int16_t *) ( q_direction->band_data[j].energy_ratio_index ), q_direction->cfg.nblocks, &min_index );
    5466           0 :                 no_cb_vec[j] = len_cb_dct0_masa[min_index >> 1];
    5467             :             }
    5468             :             else
    5469             :             {
    5470     7914426 :                 no_cb_vec[j] = len_cb_dct0_masa[q_direction->band_data[j].energy_ratio_index[0]];
    5471             :             }
    5472             : 
    5473     7914426 :             if ( write_flag )
    5474             :             {
    5475             :                 /* quantize first DCT parameter */
    5476     3957213 :                 dct_coh[j][0] = quantize_DCT_0_coh( dct_coh[j][0], j, coherence_cb0_masa, MASA_DELTA_AZI_DCT0, MASA_NO_CV_COH, q_direction, &idx_dct[k], &no_cb_vec[j], hrmasa_flag );
    5477             :             }
    5478             : 
    5479     7914426 :             if ( coding_subbands < coding_subbands_0 )
    5480             :             {
    5481      721358 :                 idx_dct[k + coding_subbands] = squant( dct_coh[j][1], &dct_coh[j][1], &coherence_cb1_masa[MASA_grouping[two_dir_band[j]] * MASA_NO_CV_COH1], MASA_NO_CV_COH1 );
    5482             :             }
    5483             :             else
    5484             :             {
    5485     7193068 :                 idx_dct[k + coding_subbands] = squant( dct_coh[j][1], &dct_coh[j][1], &coherence_cb1_masa[MASA_grouping[j] * MASA_NO_CV_COH1], MASA_NO_CV_COH1 );
    5486             :             }
    5487     7914426 :             k++;
    5488             : 
    5489     7914426 :             dct_coh[j][2] = 0.0f;
    5490     7914426 :             dct_coh[j][3] = 0.0f;
    5491             :         }
    5492             : 
    5493     1155406 :         nbits1 = 0;
    5494     1155406 :         if ( sum_s( no_cb_vec, coding_subbands ) > MASA_COH_LIMIT_2IDX )
    5495             :         {
    5496             :             /* make two indxes */
    5497       22170 :             no_cb = 1;
    5498             : #ifdef DEBUGGING
    5499             :             assert( coding_subbands % 2 == 0 );
    5500             : #endif
    5501             : 
    5502      265152 :             for ( j = 0; j < coding_subbands / 2; j++ )
    5503             :             {
    5504      242982 :                 no_cb *= no_cb_vec[j];
    5505             :             }
    5506             : 
    5507       22170 :             nbits = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 );
    5508       22170 :             no_cb = 1;
    5509             : 
    5510      265152 :             for ( j = coding_subbands / 2; j < coding_subbands; j++ )
    5511             :             {
    5512      242982 :                 no_cb *= no_cb_vec[j];
    5513             :             }
    5514       22170 :             nbits1 = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 );
    5515             :         }
    5516             :         else
    5517             :         {
    5518     1133236 :             no_cb = 1;
    5519             : 
    5520     8561698 :             for ( j = 0; j < coding_subbands; j++ )
    5521             :             {
    5522     7428462 :                 no_cb *= no_cb_vec[j];
    5523             :             }
    5524             : 
    5525     1133236 :             nbits = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 );
    5526             :         }
    5527             : 
    5528     1155406 :         if ( write_flag )
    5529             :         {
    5530     4534916 :             for ( j = 0; j < coding_subbands; j++ )
    5531             :             {
    5532             :                 /* inverse DCT transform */
    5533     3957213 :                 invdct4_transform( dct_coh[j], q_direction->coherence_band_data[j].spread_coherence );
    5534             :             }
    5535             : 
    5536      577703 :             nbits = encode_coherence_indexesDCT0( idx_dct, coding_subbands, no_cb_vec, hMetaData, *indice_coherence, nbits, nbits1 );
    5537             :         }
    5538             :         else
    5539             :         {
    5540             :             /* write dummy data now and save the position */
    5541      577703 :             *indice_coherence = hMetaData->nb_ind_tot;
    5542      577703 :             k = nbits;
    5543     1296507 :             while ( k > 0 )
    5544             :             {
    5545      718804 :                 push_next_indice( hMetaData, 0, min( 16, k ) );
    5546      718804 :                 k -= 16;
    5547             :             }
    5548             : 
    5549      577703 :             if ( nbits1 > 0 )
    5550             :             {
    5551       11085 :                 k = nbits1;
    5552       36103 :                 while ( k > 0 )
    5553             :                 {
    5554       25018 :                     push_next_indice( hMetaData, 0, min( 16, k ) );
    5555       25018 :                     k -= 16;
    5556             :                 }
    5557             :             }
    5558      577703 :             nbits += nbits1;
    5559      577703 :             set_s( no_cb_vec, MASA_NO_CV_COH1, coding_subbands );
    5560      577703 :             nbits += encode_coherence_indexesDCT1( &idx_dct[coding_subbands], coding_subbands, hMetaData );
    5561             : 
    5562      577703 :             return nbits;
    5563             :         }
    5564             :     }
    5565             : 
    5566      577703 :     return nbits;
    5567             : }
    5568             : 
    5569             : 
    5570             : /*-------------------------------------------------------------------*
    5571             :  * ivas_qmetadata_reorder_2dir_bands()
    5572             :  *
    5573             :  * Reorders metadata on 2dir bands such that direct-to-total ratio of first direction is
    5574             :  * always larger or equal to direct-to-total ratio of second direction.
    5575             :  *-------------------------------------------------------------------*/
    5576             : 
    5577      185042 : static void ivas_qmetadata_reorder_2dir_bands(
    5578             :     IVAS_QMETADATA_HANDLE hQMetaData )
    5579             : {
    5580             :     int16_t nbands;
    5581             :     int16_t nsubframes;
    5582             :     int16_t band, sf;
    5583             : 
    5584      185042 :     nbands = hQMetaData->q_direction[0].cfg.nbands;
    5585      185042 :     nsubframes = hQMetaData->q_direction[0].cfg.nblocks;
    5586             : 
    5587     2075391 :     for ( band = 0; band < nbands; band++ )
    5588             :     {
    5589     1890349 :         if ( hQMetaData->twoDirBands[band] == 1 )
    5590             :         {
    5591      631879 :             if ( hQMetaData->q_direction[0].band_data[band].energy_ratio[0] < hQMetaData->q_direction[1].band_data[band].energy_ratio[0] )
    5592             :             {
    5593      232263 :                 uint16_t uint16_tmp = 0;
    5594      232263 :                 float flt_tmp = 0;
    5595      232263 :                 uint8_t uint8_tmp = 0;
    5596             : 
    5597      856164 :                 for ( sf = 0; sf < nsubframes; sf++ )
    5598             :                 {
    5599      623901 :                     uint16_tmp = hQMetaData->q_direction[0].band_data[band].spherical_index[sf];
    5600      623901 :                     hQMetaData->q_direction[0].band_data[band].spherical_index[sf] = hQMetaData->q_direction[1].band_data[band].spherical_index[sf];
    5601      623901 :                     hQMetaData->q_direction[1].band_data[band].spherical_index[sf] = uint16_tmp;
    5602             : 
    5603      623901 :                     flt_tmp = hQMetaData->q_direction[0].band_data[band].azimuth[sf];
    5604      623901 :                     hQMetaData->q_direction[0].band_data[band].azimuth[sf] = hQMetaData->q_direction[1].band_data[band].azimuth[sf];
    5605      623901 :                     hQMetaData->q_direction[1].band_data[band].azimuth[sf] = flt_tmp;
    5606             : 
    5607      623901 :                     flt_tmp = hQMetaData->q_direction[0].band_data[band].elevation[sf];
    5608      623901 :                     hQMetaData->q_direction[0].band_data[band].elevation[sf] = hQMetaData->q_direction[1].band_data[band].elevation[sf];
    5609      623901 :                     hQMetaData->q_direction[1].band_data[band].elevation[sf] = flt_tmp;
    5610             : 
    5611      623901 :                     uint8_tmp = hQMetaData->q_direction[0].band_data[band].distance[sf];
    5612      623901 :                     hQMetaData->q_direction[0].band_data[band].distance[sf] = hQMetaData->q_direction[1].band_data[band].distance[sf];
    5613      623901 :                     hQMetaData->q_direction[1].band_data[band].distance[sf] = uint8_tmp;
    5614             : 
    5615      623901 :                     if ( hQMetaData->coherence_flag )
    5616             :                     {
    5617      623901 :                         uint8_tmp = hQMetaData->q_direction[0].coherence_band_data[band].spread_coherence[sf];
    5618      623901 :                         hQMetaData->q_direction[0].coherence_band_data[band].spread_coherence[sf] = hQMetaData->q_direction[1].coherence_band_data[band].spread_coherence[sf];
    5619      623901 :                         hQMetaData->q_direction[1].coherence_band_data[band].spread_coherence[sf] = uint8_tmp;
    5620             :                     }
    5621             :                 }
    5622      232263 :                 if ( hQMetaData->coherence_flag )
    5623             :                 {
    5624      232263 :                     flt_tmp = hQMetaData->q_direction[0].band_data[band].energy_ratio[0];
    5625      232263 :                     hQMetaData->q_direction[0].band_data[band].energy_ratio[0] = hQMetaData->q_direction[1].band_data[band].energy_ratio[0];
    5626      232263 :                     hQMetaData->q_direction[1].band_data[band].energy_ratio[0] = flt_tmp;
    5627             :                 }
    5628             :             }
    5629             :         }
    5630             :     }
    5631             : 
    5632      185042 :     return;
    5633             : }
    5634             : 
    5635             : 
    5636             : /*-------------------------------------------------------------------*
    5637             :  * write_2dir_info()
    5638             :  *
    5639             :  *
    5640             :  *-------------------------------------------------------------------*/
    5641             : 
    5642      387773 : static int16_t write_2dir_info(
    5643             :     BSTR_ENC_HANDLE hMetaData,
    5644             :     uint8_t *twoDirBands,
    5645             :     const int16_t n,
    5646             :     const int16_t k )
    5647             : {
    5648             :     int16_t nbits;
    5649             :     int16_t p[MASA_MAXIMUM_CODING_SUBBANDS];
    5650             :     uint16_t dif_p[MASA_MAXIMUM_CODING_SUBBANDS];
    5651             :     int16_t i, j;
    5652             : 
    5653      387773 :     j = 0;
    5654      387773 :     p[0] = 0;
    5655     4656149 :     for ( i = 0; i < n; i++ )
    5656             :     {
    5657     4268376 :         if ( twoDirBands[i] == 1 )
    5658             :         {
    5659     2841606 :             p[j] = i;
    5660     2841606 :             j++;
    5661             :         }
    5662             :     }
    5663             : 
    5664      387773 :     dif_p[0] = p[0];
    5665     2841606 :     for ( i = 1; i < j; i++ )
    5666             :     {
    5667     2453833 :         dif_p[i] = p[i] - p[i - 1] - 1;
    5668             :     }
    5669             : 
    5670             : #ifdef DEBUGGING
    5671             :     assert( k == j );
    5672             : #endif
    5673      387773 :     j = hMetaData->nb_bits_tot;
    5674     3229379 :     for ( i = 0; i < k; i++ )
    5675             :     {
    5676     2841606 :         ivas_qmetadata_encode_extended_gr( hMetaData, dif_p[i], 24, 0 );
    5677             :     }
    5678      387773 :     nbits = hMetaData->nb_bits_tot - j;
    5679             : 
    5680      387773 :     return nbits;
    5681             : }
    5682             : 
    5683             : 
    5684             : /*-------------------------------------------------------------------*
    5685             :  * transform_azimuth_dir2()
    5686             :  *
    5687             :  *
    5688             :  *-------------------------------------------------------------------*/
    5689             : 
    5690      373885 : static void transform_azimuth_dir2(
    5691             :     IVAS_QMETADATA_HANDLE hQMetaData,
    5692             :     int16_t *dir2_bands )
    5693             : {
    5694             :     int16_t i, b;
    5695             : 
    5696     3083037 :     for ( i = hQMetaData->q_direction[1].cfg.start_band; i < hQMetaData->q_direction[1].cfg.nbands; i++ )
    5697             :     {
    5698     2709152 :         if ( hQMetaData->q_direction[0].band_data[dir2_bands[i]].energy_ratio_index[0] < 7 )
    5699             :         {
    5700             :             /* transform azimuth */
    5701     9206783 :             for ( b = 0; b < hQMetaData->q_direction[1].cfg.nblocks; b++ )
    5702             :             {
    5703     7231678 :                 hQMetaData->q_direction[1].band_data[i].azimuth[b] = hQMetaData->q_direction[1].band_data[i].azimuth[b] - hQMetaData->q_direction[0].band_data[dir2_bands[i]].azimuth[b] + 180;
    5704     7231678 :                 if ( hQMetaData->q_direction[1].band_data[i].azimuth[b] >= 180 )
    5705             :                 {
    5706      995754 :                     hQMetaData->q_direction[1].band_data[i].azimuth[b] -= 360;
    5707             :                 }
    5708     7231678 :                 if ( hQMetaData->q_direction[1].band_data[i].azimuth[b] < -180 )
    5709             :                 {
    5710           0 :                     hQMetaData->q_direction[1].band_data[i].azimuth[b] += 360;
    5711             :                 }
    5712     7231678 :                 if ( hQMetaData->q_direction[1].band_data[i].azimuth[b] >= 180 )
    5713             :                 {
    5714           0 :                     hQMetaData->q_direction[1].band_data[i].azimuth[b] -= 360;
    5715             :                 }
    5716     7231678 :                 if ( hQMetaData->q_direction[1].band_data[i].azimuth[b] < -180 )
    5717             :                 {
    5718           0 :                     hQMetaData->q_direction[1].band_data[i].azimuth[b] += 360;
    5719             :                 }
    5720             : #ifdef DEBUGGING
    5721             :                 assert( hQMetaData->q_direction[1].band_data[i].azimuth[b] < 180 && hQMetaData->q_direction[1].band_data[i].azimuth[b] >= -180 );
    5722             : #endif
    5723             :             }
    5724             :         }
    5725             :     }
    5726             : 
    5727      373885 :     return;
    5728             : }
    5729             : 
    5730             : #ifdef DEBUG_MODE_QMETADATA
    5731             : /*-------------------------------------------------------------------------
    5732             :  * DEBUG function direction_distance()
    5733             :  *
    5734             :  *------------------------------------------------------------------------*/
    5735             : 
    5736             : static float direction_distance(
    5737             :     float elevation[DIRAC_MAX_NBANDS][MAX_PARAM_SPATIAL_SUBFRAMES],
    5738             :     float azimuth[DIRAC_MAX_NBANDS][MAX_PARAM_SPATIAL_SUBFRAMES],
    5739             :     IVAS_QDIRECTION *q_direction,
    5740             :     const int16_t dim1,
    5741             :     const int16_t dim2,
    5742             :     float mat_dist[DIRAC_MAX_NBANDS][MAX_PARAM_SPATIAL_SUBFRAMES] )
    5743             : {
    5744             :     float d;
    5745             :     int16_t i, j;
    5746             : 
    5747             :     d = 0;
    5748             :     for ( i = 0; i < dim1; i++ )
    5749             :     {
    5750             :         for ( j = 0; j < dim2; j++ )
    5751             :         {
    5752             :             mat_dist[i][j] = sinf( elevation[i][j] * PI_OVER_180 ) * sinf( q_direction->band_data[i].elevation[j] * PI_OVER_180 ) +
    5753             :                              cosf( elevation[i][j] * PI_OVER_180 ) * cosf( q_direction->band_data[i].elevation[j] * PI_OVER_180 ) * cosf( ( azimuth[i][j] - q_direction->band_data[i].azimuth[j] ) * PI_OVER_180 );
    5754             : 
    5755             :             d += fabsf( mat_dist[i][j] );
    5756             :         }
    5757             :     }
    5758             : 
    5759             :     return d / (float) ( dim1 * dim2 );
    5760             : }
    5761             : #endif
    5762             : 
    5763             : 
    5764      172029 : static int16_t divide_GR_orders(
    5765             :     const int16_t *q_idx,
    5766             :     const int16_t GR1,
    5767             :     const int16_t GR2,
    5768             :     const int16_t len,
    5769             :     const int16_t len_max_GR1,
    5770             :     int16_t *i_min )
    5771             : {
    5772             :     int16_t nb_GR_min;
    5773             :     int16_t i, j, nb_GR;
    5774      172029 :     nb_GR_min = 1000;
    5775      172029 :     *i_min = -1;
    5776     2496492 :     for ( i = 0; i < min( len_max_GR1, len ); i++ )
    5777             :     {
    5778     2324463 :         nb_GR = 0;
    5779             : 
    5780    19512321 :         for ( j = 0; j <= i; j++ )
    5781             :         {
    5782    17187858 :             nb_GR += ivas_qmetadata_encode_extended_gr_length( q_idx[j], 100, GR1 );
    5783             :         }
    5784    23670018 :         for ( j = i + 1; j < len; j++ )
    5785             :         {
    5786    21345555 :             nb_GR += ivas_qmetadata_encode_extended_gr_length( q_idx[j], 100, GR2 );
    5787             :         }
    5788             : 
    5789     2324463 :         if ( nb_GR < nb_GR_min )
    5790             :         {
    5791      422804 :             nb_GR_min = nb_GR;
    5792      422804 :             *i_min = i + 1;
    5793             :         }
    5794             :     }
    5795             : 
    5796      172029 :     return nb_GR_min;
    5797             : }
    5798             : 
    5799             : 
    5800       12010 : static int16_t find_optimal_GR_order(
    5801             :     const int16_t *q_idx,
    5802             :     const int16_t len,
    5803             :     int16_t *GR )
    5804             : {
    5805             :     int16_t nb_GR_0, nb_GR_1;
    5806             :     int16_t i;
    5807             :     /* find optimum length of the part encoded with GR2 */
    5808       12010 :     nb_GR_0 = 0;
    5809       12010 :     nb_GR_1 = 0;
    5810       59602 :     for ( i = 0; i < len; i++ )
    5811             :     {
    5812       47592 :         nb_GR_0 += ivas_qmetadata_encode_extended_gr_length( q_idx[i], 100, 0 );
    5813       47592 :         nb_GR_1 += ivas_qmetadata_encode_extended_gr_length( q_idx[i], 100, 1 );
    5814             :     }
    5815             : 
    5816       12010 :     if ( nb_GR_0 < nb_GR_1 )
    5817             :     {
    5818        8383 :         *GR = 0;
    5819        8383 :         return nb_GR_0;
    5820             :     }
    5821             :     else
    5822             :     {
    5823        3627 :         *GR = 1;
    5824             : 
    5825        3627 :         return nb_GR_1;
    5826             :     }
    5827             : }
    5828             : 
    5829             : 
    5830       57343 : static int16_t find_optimal_GR_orders(
    5831             :     const int16_t *q_idx,
    5832             :     const int16_t len,
    5833             :     const int16_t len_max_GR1,
    5834             :     int16_t *GR1,
    5835             :     int16_t *GR2,
    5836             :     int16_t *i_min )
    5837             : {
    5838             :     int16_t nb_GR_20, nb_GR_21, nb_GR_10, nb_GR_min;
    5839             :     int16_t i_min_20, i_min_21, i_min_10;
    5840             :     /* find optimum length of the part encoded with GR2 */
    5841       57343 :     nb_GR_20 = divide_GR_orders( q_idx, 2, 0, len, len_max_GR1, &i_min_20 );
    5842       57343 :     nb_GR_21 = divide_GR_orders( q_idx, 2, 1, len, len_max_GR1, &i_min_21 );
    5843       57343 :     nb_GR_10 = divide_GR_orders( q_idx, 1, 0, len, len_max_GR1, &i_min_10 );
    5844             : 
    5845       57343 :     if ( nb_GR_20 < nb_GR_21 && nb_GR_20 < nb_GR_10 )
    5846             :     {
    5847       20342 :         *GR1 = 2;
    5848       20342 :         *GR2 = 0;
    5849       20342 :         nb_GR_min = nb_GR_20;
    5850       20342 :         *i_min = i_min_20;
    5851             :     }
    5852             :     else
    5853             :     {
    5854       37001 :         if ( nb_GR_21 < nb_GR_20 && nb_GR_21 < nb_GR_10 )
    5855             :         {
    5856        4129 :             *GR1 = 2;
    5857        4129 :             *GR2 = 1;
    5858        4129 :             nb_GR_min = nb_GR_21;
    5859        4129 :             *i_min = i_min_21;
    5860             :         }
    5861             :         else
    5862             :         {
    5863       32872 :             *GR1 = 1;
    5864       32872 :             *GR2 = 0;
    5865       32872 :             nb_GR_min = nb_GR_10;
    5866       32872 :             *i_min = i_min_10;
    5867             :         }
    5868             :     }
    5869             : 
    5870       57343 :     return nb_GR_min;
    5871             : }
    5872             : 
    5873             : 
    5874       82794 : static int16_t write_stream_dct_coeffs_omasa(
    5875             :     int16_t *q_idx,                /* i  : array of indexes to be written                                   */
    5876             :     const int16_t len_stream,      /* i  : array length                                                     */
    5877             :     BSTR_ENC_HANDLE hMetaData,     /* i/o: metadata bitstream                                               */
    5878             :     const int16_t first_line,      /* i  : is first line of the matrix? 1/0                                 */
    5879             :     const int16_t low_bitrate_mode /* i  : is low bitrate mode? if yes, limit the number of bits written    */
    5880             : )
    5881             : {
    5882       82794 :     int16_t nb_bits = 0, bits_pos;
    5883             :     uint16_t nb_GR_min;
    5884             :     int16_t i, j;
    5885             :     int16_t changed, update_needed;
    5886             : 
    5887             :     int16_t GR1, GR2, i_min;
    5888             :     int16_t max_bits;
    5889             : 
    5890       82794 :     bits_pos = hMetaData->nb_bits_tot;
    5891       82794 :     if ( low_bitrate_mode == 1 )
    5892             :     {
    5893        7968 :         max_bits = 50;
    5894             :     }
    5895             :     else
    5896             :     {
    5897       74826 :         max_bits = 1000;
    5898             :     }
    5899             : 
    5900             :     /* write DCT 0 component */
    5901             :     /* write sign only if not the very first DCT coeff */
    5902       82794 :     if ( first_line == 0 )
    5903             :     {
    5904           0 :         if ( q_idx[0] > 0 )
    5905             :         {
    5906           0 :             push_next_indice( hMetaData, 1, 1 );
    5907           0 :             push_next_indice( hMetaData, q_idx[0], BITS_MASA2TOTTAL_DCT0 );
    5908             :         }
    5909             :         else
    5910             :         {
    5911           0 :             push_next_indice( hMetaData, 0, 1 );
    5912           0 :             push_next_indice( hMetaData, -q_idx[0], BITS_MASA2TOTTAL_DCT0 );
    5913             :         }
    5914           0 :         nb_bits += BITS_MASA2TOTTAL_DCT0 + 1;
    5915             :     }
    5916             :     else
    5917             :     {
    5918       82794 :         push_next_indice( hMetaData, q_idx[0], BITS_MASA2TOTTAL_DCT0 );
    5919       82794 :         nb_bits += BITS_MASA2TOTTAL_DCT0;
    5920             :     }
    5921             : 
    5922       82794 :     if ( q_idx[0] != 0 )
    5923             :     {
    5924       69353 :         i_min = 1;
    5925       69353 :         GR2 = 0;
    5926       69353 :         if ( len_stream >= 8 )
    5927             :         {
    5928       57343 :             nb_GR_min = find_optimal_GR_orders( &q_idx[1], len_stream - 1, 15, &GR1, &GR2, &i_min );
    5929             :         }
    5930             :         else
    5931             :         {
    5932       12010 :             nb_GR_min = find_optimal_GR_order( &q_idx[1], len_stream - 1, &GR1 );
    5933             :         }
    5934             : 
    5935       69353 :         assert( nb_GR_min < 1000 );
    5936       69353 :         changed = 1;
    5937       69353 :         update_needed = 0;
    5938       69353 :         while ( len_stream >= 8 && nb_GR_min > max_bits && changed >= 1 )
    5939             :         {
    5940           0 :             update_needed = 1;
    5941           0 :             changed = 0;
    5942           0 :             for ( j = len_stream - 1; j > 6; j-- )
    5943             :             {
    5944           0 :                 if ( q_idx[j] >= 2 )
    5945             :                 {
    5946             : 
    5947           0 :                     if ( j > i_min )
    5948             :                     {
    5949           0 :                         changed = 1;
    5950           0 :                         nb_GR_min -= ivas_qmetadata_encode_extended_gr_length( q_idx[j], 100, GR2 );
    5951           0 :                         q_idx[j] -= 2;
    5952           0 :                         nb_GR_min += ivas_qmetadata_encode_extended_gr_length( q_idx[j], 100, GR2 );
    5953             :                     }
    5954             :                     else
    5955             :                     {
    5956           0 :                         changed = 1;
    5957           0 :                         nb_GR_min -= ivas_qmetadata_encode_extended_gr_length( q_idx[j], 100, GR1 );
    5958           0 :                         q_idx[j] -= 2;
    5959           0 :                         nb_GR_min += ivas_qmetadata_encode_extended_gr_length( q_idx[j], 100, 0 );
    5960             :                     }
    5961             :                 }
    5962           0 :                 else if ( q_idx[j] == 1 )
    5963             :                 {
    5964           0 :                     if ( j > i_min )
    5965             :                     {
    5966           0 :                         changed = 1;
    5967           0 :                         nb_GR_min -= ivas_qmetadata_encode_extended_gr_length( q_idx[j], 100, GR2 );
    5968           0 :                         q_idx[j] -= 1;
    5969             : 
    5970           0 :                         nb_GR_min += ivas_qmetadata_encode_extended_gr_length( q_idx[j], 100, GR2 );
    5971             :                     }
    5972             :                     else
    5973             :                     {
    5974           0 :                         changed = 1;
    5975           0 :                         nb_GR_min -= ivas_qmetadata_encode_extended_gr_length( q_idx[j], 100, GR1 );
    5976           0 :                         q_idx[j] -= 1;
    5977           0 :                         nb_GR_min += ivas_qmetadata_encode_extended_gr_length( q_idx[j], 100, 0 );
    5978             :                     }
    5979             :                 }
    5980           0 :                 if ( nb_GR_min < max_bits )
    5981             :                 {
    5982           0 :                     break;
    5983             :                 }
    5984             :             }
    5985             :         }
    5986             : 
    5987       69353 :         if ( update_needed == 1 )
    5988             :         {
    5989             :             /* re-calculate */
    5990             :             /* find optimum length of the part encoded with GR2 */
    5991           0 :             nb_GR_min = find_optimal_GR_orders( &q_idx[1], len_stream - 1, 15, &GR1, &GR2, &i_min );
    5992             :         }
    5993             : 
    5994       69353 :         if ( len_stream >= 8 )
    5995             :         {
    5996             :             /* write number of indexes encoded with GR2 on 4 bits  */
    5997       57343 :             push_next_indice( hMetaData, i_min, 4 );
    5998       57343 :             nb_bits += 4;
    5999             :             /* write GR orders */
    6000       57343 :             push_next_indice( hMetaData, GR1 - 1, 1 );
    6001       57343 :             nb_bits += 1;
    6002       57343 :             if ( GR1 == 2 )
    6003             :             {
    6004       24471 :                 push_next_indice( hMetaData, GR2, 1 );
    6005       24471 :                 nb_bits += 1;
    6006             :             }
    6007             : 
    6008             :             /* write GR data */
    6009      245494 :             for ( i = 1; i <= i_min; i++ )
    6010             :             {
    6011      188151 :                 ivas_qmetadata_encode_extended_gr( hMetaData, q_idx[i], 100, GR1 );
    6012             :             }
    6013             : 
    6014      788061 :             for ( i = i_min + 1; i < len_stream; i++ )
    6015             :             {
    6016      730718 :                 ivas_qmetadata_encode_extended_gr( hMetaData, q_idx[i], 100, GR2 );
    6017             :             }
    6018             :         }
    6019             :         else
    6020             :         {
    6021             :             /* len_stream <= 8 */
    6022             :             /* write GR order */
    6023       12010 :             push_next_indice( hMetaData, GR1, 1 );
    6024       12010 :             nb_bits += 1;
    6025       59602 :             for ( i = 1; i < len_stream; i++ )
    6026             :             {
    6027       47592 :                 ivas_qmetadata_encode_extended_gr( hMetaData, q_idx[i], 100, GR1 );
    6028             :             }
    6029             :         }
    6030             : 
    6031       69353 :         nb_bits += nb_GR_min;
    6032             : 
    6033       69353 :         assert( nb_bits == ( hMetaData->nb_bits_tot - bits_pos ) );
    6034             :     }
    6035             : 
    6036       82794 :     return nb_bits;
    6037             : }
    6038             : 
    6039             : 
    6040             : /*-------------------------------------------------------------------------
    6041             :  * ivas_omasa_encode_masa_to_total()
    6042             :  *
    6043             :  *------------------------------------------------------------------------*/
    6044             : 
    6045       82794 : void ivas_omasa_encode_masa_to_total(
    6046             :     float masa_to_total_energy_ratio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
    6047             :     BSTR_ENC_HANDLE hMetaData,
    6048             :     const int16_t low_bitrate_mode,
    6049             :     const int16_t nbands,
    6050             :     const int16_t nblocks )
    6051             : {
    6052             :     int16_t i, j, k;
    6053             :     float data[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS];
    6054             :     float q_dct_data[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS];
    6055       82794 :     float step = STEP_M2T;
    6056             : 
    6057             :     int16_t q_idx[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS];
    6058             :     float dct_data_tmp[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS];
    6059             :     float dct_data[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS];
    6060             : 
    6061             :     int16_t bits_pos, nb_bits;
    6062             :     int16_t n_streams, len_stream;
    6063             : 
    6064             :     Word32 q_dct_data_fx[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS],
    6065             :         dct_data_tmp_fx[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS];
    6066             : 
    6067             :     int64_t step_fx;
    6068       82794 :     step_fx = STEP_M2T_FX;
    6069             : #ifdef DEBUG_MODE_QMETADATA
    6070             :     static FILE *pF = NULL;
    6071             :     static FILE *pF_ratio = NULL;
    6072             : 
    6073             :     if ( pF == NULL )
    6074             :         pF = fopen( "./res/qmetadata_ism_qidx__enc.txt", "w" );
    6075             :     if ( pF_ratio == NULL )
    6076             :         pF_ratio = fopen( "./res/qmetadata_masa2tot_enc.txt", "w" );
    6077             : 
    6078             : #endif
    6079             : 
    6080       82794 :     bits_pos = hMetaData->nb_bits_tot;
    6081       82794 :     k = 0;
    6082      678392 :     for ( i = 0; i < nbands; i++ )
    6083             :     {
    6084     1834687 :         for ( j = 0; j < nblocks; j++ )
    6085             :         {
    6086     1239089 :             data[k] = masa_to_total_energy_ratio[j][i];
    6087     1239089 :             k++;
    6088             :         }
    6089             :     }
    6090             : 
    6091             :     /* DCT2 transform */
    6092       82794 :     n_streams = 1;
    6093       82794 :     len_stream = nbands * nblocks;
    6094       82794 :     switch ( len_stream )
    6095             :     {
    6096         457 :         case 4:
    6097         457 :             matrix_product( dct4, nblocks, nblocks, 0, data, 1, nblocks, 1, dct_data );
    6098         457 :             n_streams = 1;
    6099         457 :             len_stream = 4;
    6100         457 :             break;
    6101       13321 :         case 5:
    6102       13321 :             matrix_product( dct5, nbands, nbands, 0, data, 1, nbands, 1, dct_data );
    6103       13321 :             n_streams = 1;
    6104       13321 :             len_stream = nbands;
    6105       13321 :             break;
    6106           0 :         case 8:
    6107           0 :             matrix_product( dct8, nbands, nbands, 0, data, 1, nbands, 1, dct_data );
    6108           0 :             n_streams = 1;
    6109           0 :             len_stream = nbands;
    6110           0 :             break;
    6111       26208 :         case 12:
    6112       26208 :             matrix_product( dct12, nbands, nbands, 0, data, 1, nbands, 1, dct_data );
    6113       26208 :             n_streams = 1;
    6114       26208 :             len_stream = nbands;
    6115       26208 :             break;
    6116       42808 :         case 20:
    6117       42808 :             matrix_product( dct5, nbands, nbands, 0, data, nblocks, nbands, 1, dct_data_tmp );
    6118       42808 :             matrix_product( dct_data_tmp, nbands, nblocks, 0, dct4, nblocks, nblocks, 1, dct_data );
    6119       42808 :             n_streams = 1;
    6120       42808 :             len_stream = nbands * nblocks;
    6121       42808 :             break;
    6122           0 :         case 32:
    6123           0 :             matrix_product( dct8, nbands, nbands, 0, data, nblocks, nbands, 1, dct_data_tmp );
    6124           0 :             matrix_product( dct_data_tmp, nbands, nblocks, 0, dct4, nblocks, nblocks, 1, dct_data );
    6125           0 :             n_streams = nblocks;
    6126           0 :             len_stream = nbands;
    6127           0 :             break;
    6128           0 :         default:
    6129           0 :             printf( "Incorrect number of coefficients for OMASA.\n" );
    6130           0 :             break;
    6131             :     }
    6132             : 
    6133      165588 :     for ( k = 0; k < n_streams; k++ )
    6134             :     {
    6135       82794 :         j = k * len_stream;
    6136             :         /* quantize with fixed common step */
    6137       82794 :         q_idx[j] = (int16_t) rintf( dct_data[j] / step );
    6138             : 
    6139       82794 :         if ( q_idx[j] > ( ( 1 << BITS_MASA2TOTTAL_DCT0 ) - 1 ) ) /* limit DCT0 to BITS_MASA2TOTTAL_DCT0 bit representation */
    6140             :         {
    6141           0 :             q_idx[j] = ( ( 1 << BITS_MASA2TOTTAL_DCT0 ) - 1 );
    6142             :         }
    6143             : 
    6144       82794 :         q_dct_data[j] = step * q_idx[j];
    6145             : 
    6146       82794 :         if ( q_idx[j] == 0 )
    6147             :         {
    6148       13441 :             set_s( &q_idx[j], 0, len_stream );
    6149       13441 :             set_zero( &q_dct_data[j], len_stream );
    6150             :         }
    6151             :         else
    6152             :         {
    6153     1035814 :             for ( i = 1; i < len_stream; i++ )
    6154             :             {
    6155      966461 :                 q_idx[j + i] = (int16_t) rintf( dct_data[j + i] / step );
    6156      966461 :                 q_dct_data[j + i] = step * q_idx[j + i];
    6157      966461 :                 if ( q_idx[j + i] <= 0 )
    6158             :                 {
    6159      777478 :                     q_idx[j + i] = -2 * q_idx[j + i];
    6160             :                 }
    6161             :                 else
    6162             :                 {
    6163      188983 :                     q_idx[j + i] = 2 * q_idx[j + i] - 1;
    6164             :                 }
    6165             :             }
    6166             :         }
    6167             :     }
    6168             : 
    6169             :     /* write data */
    6170       82794 :     nb_bits = 0;
    6171      165588 :     for ( i = 0; i < n_streams; i++ )
    6172             :     {
    6173       82794 :         nb_bits += write_stream_dct_coeffs_omasa( &q_idx[i * len_stream], len_stream, hMetaData, ( i == 0 ), low_bitrate_mode );
    6174             :     }
    6175             : 
    6176             :     /* reconstruct masa2total */
    6177       82794 :     q_dct_data_fx[0] = (Word32) ( ( step_fx * q_idx[0] ) >> 6 ); // Q25
    6178     1239089 :     for ( i = 1; i < len_stream; i++ )
    6179             :     {
    6180     1156295 :         if ( ( q_idx[i] & 1 ) == 0 )
    6181             :         {
    6182      967312 :             q_dct_data_fx[i] = (Word32) ( ( step_fx * ( -q_idx[i] ) ) >> 7 ); // Q25
    6183             :         }
    6184             :         ELSE
    6185             :         {
    6186      188983 :             q_dct_data_fx[i] = (Word32) ( ( step_fx * ( q_idx[i] + 1 ) ) >> 7 ); // Q25
    6187             :         }
    6188             :     }
    6189       82794 :     SWITCH( len_stream )
    6190             :     {
    6191         457 :         case 4:
    6192         457 :             matrix_product_q30_fx( dct4_fx, nblocks, nblocks, 1, q_dct_data_fx, nblocks, 1, 0, dct_data_tmp_fx );
    6193         457 :             mvl2l( dct_data_tmp_fx, q_dct_data_fx, nblocks ); /*Q30*/
    6194         457 :             BREAK;
    6195       13321 :         case 5:
    6196       13321 :             matrix_product_q30_fx( dct5_fx, nbands, nbands, 1, q_dct_data_fx, nbands, 1, 0, dct_data_tmp_fx );
    6197       13321 :             mvl2l( dct_data_tmp_fx, q_dct_data_fx, nbands ); /*Q30*/
    6198       13321 :             BREAK;
    6199           0 :         case 8:
    6200           0 :             matrix_product_q30_fx( dct8_fx, nbands, nbands, 1, q_dct_data_fx, nbands, 1, 0, dct_data_tmp_fx );
    6201           0 :             mvl2l( dct_data_tmp_fx, q_dct_data_fx, nbands ); /*Q30*/
    6202           0 :             BREAK;
    6203       26208 :         case 12:
    6204       26208 :             matrix_product_q30_fx( dct12_fx, nbands, nbands, 1, q_dct_data_fx, nbands, 1, 0, dct_data_tmp_fx );
    6205       26208 :             mvl2l( dct_data_tmp_fx, q_dct_data_fx, nbands ); /*Q30*/
    6206       26208 :             BREAK;
    6207       42808 :         case 20:
    6208       42808 :             matrix_product_fx( dct5_fx, nbands, nbands, 1, q_dct_data_fx, nbands, nblocks, 0, dct_data_tmp_fx );
    6209       42808 :             matrix_product_q30_fx( dct_data_tmp_fx, nbands, nblocks, 0, dct4_fx, nblocks, nblocks, 0, q_dct_data_fx ); /* reuse of variable*/
    6210       42808 :             BREAK;
    6211           0 :         case 32:
    6212           0 :             matrix_product_fx( dct8_fx, nbands, nbands, 1, q_dct_data_fx, nbands, nblocks, 0, dct_data_tmp_fx );
    6213           0 :             matrix_product_q30_fx( dct_data_tmp_fx, nbands, nblocks, 0, dct4_fx, nblocks, nblocks, 0, q_dct_data_fx );
    6214           0 :             BREAK;
    6215           0 :         default:
    6216           0 :             printf( "Incorrect number of coefficients for OMASA.\n" );
    6217           0 :             BREAK;
    6218             :     }
    6219             : 
    6220             :     /* this is to make sure the comparison to the threshold 0.98 will go the same way in   */
    6221             :     /* fixed point and floating point without having to drag the fixed point values to the */
    6222             :     /* comparison place in the code;                                                       */
    6223             :     /* 1052266987 is 0.98 in Q30 it is not needed in the fixed point                       */
    6224     1321883 :     for ( i = 0; i < nblocks * nbands; i++ )
    6225             :     {
    6226     1239089 :         if ( q_dct_data_fx[i] >= 1052266987 && q_dct_data_fx[i] < 1052400000 )
    6227             :         {
    6228         520 :             q_dct_data_fx[i] = 1052400000;
    6229             :         }
    6230             :     }
    6231             : 
    6232       82794 :     k = 0;
    6233      295383 :     for ( i = 0; i < nblocks; i++ )
    6234             :     {
    6235     1451678 :         for ( j = 0; j < nbands; j++ )
    6236             :         {
    6237     1239089 :             masa_to_total_energy_ratio[i][j] = q_dct_data_fx[k] / (float) ( 1 << 30 );
    6238     1239089 :             masa_to_total_energy_ratio[i][j] = max( 0.0f, masa_to_total_energy_ratio[i][j] );
    6239     1239089 :             masa_to_total_energy_ratio[i][j] = min( 1.0f, masa_to_total_energy_ratio[i][j] );
    6240     1239089 :             k++;
    6241             :         }
    6242             :     }
    6243             : 
    6244       82794 :     if ( nblocks == 1 )
    6245             :     {
    6246      158116 :         for ( i = 1; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
    6247             :         {
    6248     1261890 :             for ( j = 0; j < nbands; j++ )
    6249             :             {
    6250     1143303 :                 masa_to_total_energy_ratio[i][j] = masa_to_total_energy_ratio[0][j];
    6251             :             }
    6252             :         }
    6253             :     }
    6254             : 
    6255       82794 :     if ( nbands == 1 )
    6256             :     {
    6257        2285 :         for ( j = 1; j < 5; j++ )
    6258             :         {
    6259        9140 :             for ( i = 0; i < nblocks; i++ )
    6260             :             {
    6261        7312 :                 masa_to_total_energy_ratio[i][j] = masa_to_total_energy_ratio[i][0];
    6262             :             }
    6263             :         }
    6264             :     }
    6265             : 
    6266       82794 :     assert( nb_bits == ( hMetaData->nb_bits_tot - bits_pos ) );
    6267             : 
    6268             : #ifdef DEBUG_MODE_QMETADATA
    6269             :     {
    6270             : 
    6271             :         fprintf( pF, "frame %d:  ", frame );
    6272             :         fprintf( pF_ratio, "frame %d: ", frame );
    6273             : 
    6274             : 
    6275             :         /* direction_distance( elevation_orig, azimuth_orig, q_direction,  nbands, nblocks, mat_dist );*/
    6276             :         for ( i = 0; i < nbands; i++ )
    6277             :         {
    6278             :             for ( j = 0; j < 4; j++ )
    6279             :             {
    6280             :                 fprintf( pF_ratio, " %5.2f ", hQMetaData->masa_to_total_energy_ratio[j][i] );
    6281             :             }
    6282             :         }
    6283             :         for ( i = 0; i < 20; i++ )
    6284             :         {
    6285             :             fprintf( pF, " %4d ", q_idx[i] );
    6286             :         }
    6287             :         fprintf( pF, "\n" );
    6288             :         fprintf( pF_ratio, "\n" );
    6289             :     }
    6290             : #endif
    6291             : 
    6292       82794 :     return;
    6293             : }

Generated by: LCOV version 1.14