LCOV - code coverage report
Current view: top level - lib_enc - ivas_qmetadata_enc.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 2007 2162 92.8 %
Date: 2025-05-23 08:37:30 Functions: 53 53 100.0 %

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

Generated by: LCOV version 1.14