LCOV - code coverage report
Current view: top level - lib_dec - ivas_qmetadata_dec_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 2009 2171 92.5 %
Date: 2025-05-03 01:55:50 Functions: 32 32 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 "ivas_rom_com.h"
      39             : #include "ivas_rom_dec.h"
      40             : #include "wmc_auto.h"
      41             : #include "prot_fx.h"
      42             : 
      43             : #include "ivas_prot_fx.h"
      44             : #include "ivas_rom_com_fx.h"
      45             : 
      46             : /*-----------------------------------------------------------------------*
      47             :  * Local function prototypes
      48             :  *-----------------------------------------------------------------------*/
      49             : static Word16 ivas_qmetadata_entropy_decode_diffuseness( UWord16 *bitstream, Word16 *index, IVAS_QDIRECTION *q_direction, UWord16 *diffuseness_index_max_ec_frame );
      50             : static Word16 ivas_qmetadata_entropy_decode_df_ratio( UWord16 *bitstream, Word16 *index, IVAS_QDIRECTION *q_direction, Word16 *dfRatio_bits );
      51             : static Word16 ivas_qmetadata_raw_decode_dir_fx( IVAS_QDIRECTION *q_direction, UWord16 *bitstream, Word16 *index, const Word16 nbands, const Word16 start_band, const Word16 hrmasa_flag );
      52             : static UWord16 ivas_qmetadata_DecodeQuasiUniform( const UWord16 *bitstream, Word16 *index, const UWord16 alphabet_size );
      53             : static Word16 ivas_qmetadata_ReorderElevationDecoded( const Word16 elev_dist, const Word16 elev_avg, const Word16 elev_alph );
      54             : static Word16 read_directions_fx( IVAS_QDIRECTION *q_direction, const UWord8 coding_subbands, const UWord8 masa_subframes, UWord16 *bitstream, Word16 *pbit_pos, Word16 *ind_order );
      55             : static Word16 read_common_direction_fx( UWord16 *bitstream, IVAS_QDIRECTION *q_direction, const Word16 j, const Word16 no_subframes, const Word16 bits_total, Word16 *pbit_pos );
      56             : static Word16 decode_azimuth_fx( IVAS_QDIRECTION *q_direction, UWord16 *bitstream, Word16 *pbit_pos, const Word16 idx_subband, const Word16 masa_subframes );
      57             : static Word16 decode_fixed_rate_fx( IVAS_QDIRECTION *q_direction, const UWord16 *bitstream, Word16 *pbit_pos, const Word16 b, const Word16 nblocks );
      58             : static Word16 ivas_qmetadata_entropy_decode_diffuseness_hr_512( UWord16 *bitstream, Word16 *index, IVAS_QDIRECTION *q_direction );
      59             : static Word16 ivas_qmetadata_entropy_decode_dir_fx( IVAS_QDIRECTION *q_direction, UWord16 *bitstream, Word16 *index, const UWord16 diffuseness_index_max_ec_frame, const Word16 nbands, const Word16 start_band, const Word16 hrmasa_flag );
      60             : static Word16 read_surround_coherence_hr_fx( UWord16 *bitstream, Word16 *p_bit_pos, IVAS_QMETADATA *hQMetaData, Word64 energy_ratio[][MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES] );
      61             : static void set_zero_direction_fx( IVAS_QDIRECTION *q_direction, const Word16 idx_band, const Word16 len );
      62             : static Word16 decode_azimuth2D_fx( IVAS_QDIRECTION *q_direction, UWord16 *bitstream, const Word16 coding_subbands, Word16 *pbit_pos, const Word16 no_frames );
      63             : static Word16 read_truncGR_azimuth_fx( UWord16 *bitstream, IVAS_QDIRECTION *q_direction, const Word16 j, const Word16 no_subframes, Word16 *pbit_pos );
      64             : static void decode_combined_index_fx( UWord64 comb_index, const Word16 *no_cv_vec, UWord16 *index, const Word16 len );
      65             : static Word16 decode_elevation_fx( IVAS_QDIRECTION *q_direction, UWord16 *bitstream, Word16 *pbit_pos, const Word16 j, const Word16 masa_subframes );
      66             : static Word16 decode_fixed_rate_composed_index_coherence_fx( UWord16 *bitstream, Word16 *p_bit_pos, const Word16 no_bands, Word16 *no_cv_vec, UWord16 *decoded_index, const Word16 no_symb );
      67             : static void decode_spread_coherence_fx( IVAS_QMETADATA_HANDLE hQMetaData, Word16 idx_d, const Word16 no_frames, const Word16 hrmasa_flag );
      68             : static Word16 ivas_diffuseness_huff_ec_decode_fx( const UWord16 *bitstream, Word16 *index, Word16 av );
      69             : static void read_stream_dct_coeffs_omasa_fx( Word16 *q_idx, Word32 *q_dct_data_fx, const Word16 len_stream, UWord16 *bit_stream, Word16 *index, const Word16 first_line );
      70             : static Word16 read_coherence_data_hr_512_fx( UWord16 *bitstream, Word16 *p_bit_pos, IVAS_QMETADATA *hQMetaData, const Word16 idx_dir, const Word16 nbits_coh );
      71             : static Word16 read_coherence_data_fx( UWord16 *bitstream, Word16 *p_bit_pos, IVAS_QMETADATA *hQMetaData, const Word16 idx_dir, const Word16 hrmasa_flag );
      72             : static Word16 ivas_qmetadata_raw_decode_dir_512_fx( IVAS_QDIRECTION *q_direction, UWord16 *bitstream, Word16 *index, const Word16 nbands, const Word16 start_band, const SPHERICAL_GRID_DATA *sph_grid16 );
      73             : static Word16 read_surround_coherence( UWord16 *bitstream, Word16 *p_bit_pos, IVAS_QMETADATA *hQMetaData );
      74             : static ivas_error read_huf( Word16 *num_bits_read, const UWord16 *bitstream, UWord16 *out, const Word16 start_pos, const Word16 len, const Word16 *huff_code, const Word16 max_len );
      75             : const Word16 inv_dfRatio_qsteps[9] = { 0, 0, ONE_IN_Q14, 0, 5461, 0, 0, 0, 2341 }; // Q14
      76             : 
      77             : 
      78             : /*-----------------------------------------------------------------------*
      79             :  * Global function definitions
      80             :  *-----------------------------------------------------------------------*/
      81             : 
      82             : /*-----------------------------------------------------------------------*
      83             :  * ivas_qmetadata_dec_decode()
      84             :  *
      85             :  * Main function for decoding Spatial Metadata
      86             :  *-----------------------------------------------------------------------*/
      87             : /*! r: number of bits read */
      88      184762 : Word16 ivas_qmetadata_dec_decode(
      89             :     IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: hQMetaData handle                 */
      90             :     UWord16 *bitstream,               /* i  : bitstream                         Q0*/
      91             :     Word16 *index,                    /* i/o: bitstream position                Q0*/
      92             :     const Word16 hodirac_flag         /* i  : flag to indicate HO-DirAC mode    Q0*/
      93             : )
      94             : {
      95             :     Word16 d, b, m;
      96             :     UWord16 diffuseness_index_max_ec_frame;
      97             :     UWord16 diffuseness_index_max_ec_frame_pre[QMETADATA_MAX_NO_DIRECTIONS];
      98             :     Word16 bits_dir_raw_pre[QMETADATA_MAX_NO_DIRECTIONS];
      99             :     Word16 dir2band;
     100             :     Word16 bits_diff_sum;
     101             :     Word16 bits_diff, bits_coherence;
     102             :     Word16 bits_dir_raw;
     103             :     Word16 bits_dir;
     104             :     Word16 nbands, nblocks, start_band;
     105             :     IVAS_QDIRECTION *q_direction;
     106             :     Word16 start_index_0;
     107             :     Word16 total_bits_1dir;
     108             :     Word16 signal_bits;
     109             :     Word16 bits_no_dirs_coh, bits_sur_coherence;
     110             :     UWord16 all_coherence_zero;
     111             :     Word16 ec_flag;
     112             :     Word16 raw_flag[MASA_MAXIMUM_CODING_SUBBANDS];
     113             :     Word16 diff_bits;
     114             :     Word16 dfRatio_bits[MASA_MAXIMUM_CODING_SUBBANDS];
     115             :     Word16 no_TF;
     116             :     Word16 p[MASA_MAXIMUM_CODING_SUBBANDS], dif_p[MASA_MAXIMUM_CODING_SUBBANDS];
     117             :     Word16 bits_dir_target;
     118             :     Word16 bits_dir_used;
     119             :     Word16 reduce_bits;
     120             :     Word16 ind_order[MASA_MAXIMUM_CODING_SUBBANDS];
     121             :     Word32 tmp32;
     122             : 
     123             : 
     124      184762 :     ec_flag = 0;
     125      184762 :     move16();
     126      184762 :     start_index_0 = *index;
     127      184762 :     move16();
     128             : 
     129             :     /*Coherence flag decoding*/
     130      184762 :     bits_no_dirs_coh = 0;
     131      184762 :     move16();
     132      184762 :     all_coherence_zero = 1;
     133      184762 :     move16();
     134             : 
     135      184762 :     IF( hQMetaData->coherence_flag )
     136             :     {
     137             :         /* read if coherence is zero */
     138       25364 :         all_coherence_zero = bitstream[( *index )--]; /*Q0*/
     139       25364 :         move16();
     140       25364 :         bits_no_dirs_coh = add( bits_no_dirs_coh, 1 );
     141             :     }
     142             : 
     143      184762 :     hQMetaData->all_coherence_zero = (UWord8) all_coherence_zero;
     144             : 
     145      184762 :     IF( EQ_32( hQMetaData->no_directions, 2 ) )
     146             :     {
     147             :         /* Read which bands have 2 directions */
     148       20067 :         hQMetaData->q_direction[1].cfg.nbands = hQMetaData->numTwoDirBands; /*Q0*/
     149       20067 :         move16();
     150       20067 :         set_c( (Word8 *) hQMetaData->twoDirBands, 0, hQMetaData->q_direction[0].cfg.nbands );
     151       20067 :         d = *index;
     152       20067 :         move16();
     153       20067 :         dif_p[0] = ivas_qmetadata_DecodeExtendedGR( bitstream, index, MASA_MAXIMUM_CODING_SUBBANDS, 0 ); /*Q0*/
     154       20067 :         move16();
     155       20067 :         p[0] = dif_p[0]; /*Q0*/
     156       20067 :         move16();
     157       20067 :         hQMetaData->twoDirBands[p[0]] = 1;
     158       20067 :         move16();
     159      204816 :         FOR( b = 1; b < hQMetaData->numTwoDirBands; b++ )
     160             :         {
     161      184749 :             dif_p[b] = ivas_qmetadata_DecodeExtendedGR( bitstream, index, MASA_MAXIMUM_CODING_SUBBANDS, 0 ); /*Q0*/
     162      184749 :             move16();
     163      184749 :             p[b] = add( add( p[b - 1], dif_p[b] ), 1 );
     164      184749 :             move16();
     165      184749 :             hQMetaData->twoDirBands[p[b]] = 1;
     166      184749 :             move16();
     167             :         }
     168       20067 :         bits_no_dirs_coh = add( bits_no_dirs_coh, sub( d, *index ) );
     169             :     }
     170             : 
     171      184762 :     bits_diff_sum = 0;
     172      184762 :     move16();
     173      184762 :     bits_diff_sum = add( bits_diff_sum, ivas_qmetadata_entropy_decode_diffuseness( bitstream, index, &( hQMetaData->q_direction[0] ), &diffuseness_index_max_ec_frame_pre[0] ) );
     174             : 
     175      184762 :     IF( hodirac_flag )
     176             :     {
     177       16058 :         IF( EQ_32( hQMetaData->no_directions, 2 ) )
     178             :         {
     179             :             /* Calculate bits for dfRatio */
     180       16058 :             dir2band = 0;
     181       16058 :             move16();
     182      208754 :             FOR( b = hQMetaData->q_direction[0].cfg.start_band; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
     183             :             {
     184      192696 :                 IF( EQ_16( hQMetaData->twoDirBands[b], 1 ) )
     185             :                 {
     186      192696 :                     dfRatio_bits[dir2band] = ivas_get_df_ratio_bits_hodirac_fx( hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0] ); /*Q0*/
     187      192696 :                     move16();
     188      192696 :                     dir2band = add( dir2band, 1 );
     189             :                 }
     190             :             }
     191             : 
     192       16058 :             bits_diff_sum = add( bits_diff_sum, ivas_qmetadata_entropy_decode_df_ratio( bitstream, index, &( hQMetaData->q_direction[1] ), dfRatio_bits ) );
     193             :         }
     194             :     }
     195             :     ELSE
     196             :     {
     197      168704 :         IF( EQ_32( hQMetaData->no_directions, 2 ) )
     198             :         {
     199             :             /* Calculate bits for dfRatio */
     200        4009 :             dir2band = 0;
     201        4009 :             move16();
     202       40282 :             FOR( b = hQMetaData->q_direction[0].cfg.start_band; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
     203             :             {
     204       36273 :                 IF( EQ_16( hQMetaData->twoDirBands[b], 1 ) )
     205             :                 {
     206       12120 :                     dfRatio_bits[dir2band] = ivas_get_df_ratio_bits_fx( hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0] ); /*Q0*/
     207       12120 :                     move16();
     208       12120 :                     dir2band = add( dir2band, 1 );
     209             :                 }
     210             :             }
     211             : 
     212        4009 :             bits_diff_sum = add( bits_diff_sum, ivas_qmetadata_entropy_decode_df_ratio( bitstream, index, &( hQMetaData->q_direction[1] ), dfRatio_bits ) ); /*Q0*/
     213             :         }
     214             :     }
     215             : 
     216             :     /* Calculate direct-to-total energy ratios for both directions from diffuse-to-total ratio and distribution factor of direct-to-total ratios */
     217      184762 :     IF( EQ_32( hQMetaData->no_directions, 2 ) )
     218             :     {
     219       20067 :         dir2band = 0;
     220       20067 :         move16();
     221      249036 :         FOR( b = hQMetaData->q_direction[0].cfg.start_band; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
     222             :         {
     223      228969 :             IF( EQ_16( hQMetaData->twoDirBands[b], 1 ) )
     224             :             {
     225             :                 Word32 diffRatio_fx, dir1ratio_fx, dir2ratio_fx;
     226             :                 Word16 dfRatio_fx;
     227             :                 Word16 dfRatio_qsteps;
     228             : 
     229      204816 :                 diffRatio_fx = diffuseness_reconstructions_fx[hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]]; // Q30
     230      204816 :                 move32();
     231             : 
     232      204816 :                 dfRatio_qsteps = shl( 1, dfRatio_bits[dir2band] ); /*1 << dfRatio_bits[dir2band]*/
     233             :                 /* already encoded as total and ratios in HO-DirAC */
     234      204816 :                 IF( hodirac_flag )
     235             :                 {
     236             : 
     237      192696 :                     dfRatio_fx = usdequant_fx( hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0], 0 /* Q15 */, inv_dfRatio_qsteps[dfRatio_qsteps] ); // Q15
     238      192696 :                     dir1ratio_fx = L_sub( ONE_IN_Q30, diffRatio_fx );
     239      192696 :                     dir2ratio_fx = L_shl( (Word32) dfRatio_fx, Q15 ); /*Q30*/
     240             :                 }
     241             :                 ELSE
     242             :                 {
     243       12120 :                     dfRatio_fx = usdequant_fx( hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0], shr( MAX_16, 1 ), shr( inv_dfRatio_qsteps[dfRatio_qsteps], 1 ) ); // Q15
     244             : 
     245       12120 :                     dir1ratio_fx = Mpy_32_16_1( L_sub( ONE_IN_Q30, diffRatio_fx ), dfRatio_fx ); // Q30
     246       12120 :                     dir2ratio_fx = L_sub( L_sub( ONE_IN_Q30, diffRatio_fx ), dir1ratio_fx );     // Q30
     247             :                 }
     248             : 
     249             :                 /* Requantize the 1 - dirRatio separately for each direction to obtain inverted dirRatio index. These are used in further decoding. */
     250             : 
     251      204816 :                 hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0] = masa_sq_fx( L_sub( ONE_IN_Q30, dir1ratio_fx ), diffuseness_thresholds_fx, DIRAC_DIFFUSE_LEVELS ); /*Q0*/
     252      204816 :                 move16();
     253      204816 :                 IF( hodirac_flag )
     254             :                 {
     255             :                     Word16 tmp_fx;
     256      192696 :                     hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0] = usquant_fx( extract_h( dir2ratio_fx ), &tmp_fx, 0, INV_DIRAC_DIFFUSE_LEVELS_Q13, DIRAC_DIFFUSE_LEVELS ); /*Q0*/
     257      192696 :                     move16();
     258             :                 }
     259             :                 ELSE
     260             :                 {
     261       12120 :                     hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0] = masa_sq_fx( L_sub( ONE_IN_Q30, dir2ratio_fx ), diffuseness_thresholds_fx, DIRAC_DIFFUSE_LEVELS ); /*Q0*/
     262       12120 :                     move16();
     263             :                 }
     264             : 
     265     1015071 :                 FOR( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ )
     266             :                 {
     267      810255 :                     hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[m] = dir1ratio_fx; // Q30
     268      810255 :                     move32();
     269      810255 :                     hQMetaData->q_direction[0].band_data[b].energy_ratio_index[m] = hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]; /*Q0*/
     270      810255 :                     move16();
     271             :                 }
     272             : 
     273     1015071 :                 FOR( m = 0; m < hQMetaData->q_direction[1].cfg.nblocks; m++ )
     274             :                 {
     275      810255 :                     hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_fx[m] = dir2ratio_fx; /*Q30*/
     276      810255 :                     move32();
     277      810255 :                     hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[m] = hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0]; /*Q0*/
     278      810255 :                     move16();
     279             :                 }
     280             : 
     281      204816 :                 dir2band = add( dir2band, 1 );
     282             :             }
     283             :             ELSE
     284             :             {
     285             :                 /* 1dir band */
     286       24153 :                 hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[0] = L_sub( ONE_IN_Q30, diffuseness_reconstructions_fx[hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]] ); /*Q30*/
     287       24153 :                 move32();
     288       64401 :                 FOR( m = 1; m < hQMetaData->q_direction[0].cfg.nblocks; m++ )
     289             :                 {
     290       40248 :                     hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[m] = hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[0]; /*Q30*/
     291       40248 :                     move32();
     292       40248 :                     hQMetaData->q_direction[0].band_data[b].energy_ratio_index[m] = hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]; /*Q0*/
     293       40248 :                     move16();
     294             :                 }
     295             :             }
     296             :         }
     297             :     }
     298             :     ELSE
     299             :     {
     300             :         /* With 1dir band, the decoded index is directly diffuseness and we can decode to direct-to-total ratio with 1 - diff. */
     301      769605 :         FOR( b = hQMetaData->q_direction[0].cfg.start_band; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
     302             :         {
     303      604910 :             hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[0] = L_sub( ONE_IN_Q30, diffuseness_reconstructions_fx[hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]] ); /*Q30*/
     304      604910 :             move32();
     305     1932323 :             FOR( m = 1; m < hQMetaData->q_direction[0].cfg.nblocks; m++ )
     306             :             {
     307     1327413 :                 hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[m] = hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[0]; /*Q30*/
     308     1327413 :                 move32();
     309     1327413 :                 hQMetaData->q_direction[0].band_data[b].energy_ratio_index[m] = hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]; /*Q0*/
     310     1327413 :                 move16();
     311             :             }
     312             :         }
     313             :     }
     314             : 
     315             :     /* To decode directions correctly for 2dir bands, we need to obtain the compensated direct-to-total ratios and their
     316             :      * corresponding inverted indices. */
     317      184762 :     bits_dir_raw_pre[0] = 0;
     318      184762 :     move16();
     319      184762 :     bits_dir_raw_pre[1] = 0;
     320      184762 :     move16();
     321      184762 :     dir2band = 0;
     322      184762 :     move16();
     323     1018641 :     FOR( b = hQMetaData->q_direction[0].cfg.start_band; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
     324             :     {
     325      833879 :         test();
     326      833879 :         IF( EQ_32( hQMetaData->no_directions, 2 ) && EQ_16( hQMetaData->twoDirBands[b], 1 ) )
     327      204816 :         {
     328             :             Word16 index_dirRatio1Inv, index_dirRatio2Inv, index_dirRatio1Inv_mod, index_dirRatio2Inv_mod;
     329             : 
     330      204816 :             index_dirRatio1Inv = hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]; /*Q0*/
     331      204816 :             move16();
     332      204816 :             index_dirRatio2Inv = hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0]; /*Q0*/
     333      204816 :             move16();
     334             : 
     335      204816 :             masa_compensate_two_dir_energy_ratio_index_fx( index_dirRatio1Inv, index_dirRatio2Inv, &index_dirRatio1Inv_mod, &index_dirRatio2Inv_mod, hodirac_flag );
     336             : 
     337     1015071 :             FOR( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ )
     338             :             {
     339      810255 :                 hQMetaData->q_direction[0].band_data[b].energy_ratio_index_mod[m] = index_dirRatio1Inv_mod; /*Q0*/
     340      810255 :                 move16();
     341      810255 :                 hQMetaData->q_direction[0].band_data[b].bits_sph_idx[m] = bits_direction_masa[index_dirRatio1Inv_mod]; /*Q0*/
     342      810255 :                 move16();
     343      810255 :                 bits_dir_raw_pre[0] = add( bits_dir_raw_pre[0], hQMetaData->q_direction[0].band_data[b].bits_sph_idx[m] );
     344      810255 :                 move16();
     345             :             }
     346             : 
     347     1015071 :             FOR( m = 0; m < hQMetaData->q_direction[1].cfg.nblocks; m++ )
     348             :             {
     349      810255 :                 hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index_mod[m] = index_dirRatio2Inv_mod; /*Q0*/
     350      810255 :                 move16();
     351      810255 :                 hQMetaData->q_direction[1].band_data[dir2band].bits_sph_idx[m] = bits_direction_masa[index_dirRatio2Inv_mod]; /*Q0*/
     352      810255 :                 move16();
     353      810255 :                 bits_dir_raw_pre[1] = add( bits_dir_raw_pre[1], hQMetaData->q_direction[1].band_data[dir2band].bits_sph_idx[m] );
     354      810255 :                 move16();
     355             :             }
     356             : 
     357      204816 :             dir2band = add( dir2band, 1 );
     358             :         }
     359             :         ELSE
     360             :         {
     361     2625787 :             FOR( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ )
     362             :             {
     363     1996724 :                 hQMetaData->q_direction[0].band_data[b].energy_ratio_index_mod[m] = hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]; /*Q0*/
     364     1996724 :                 move16();
     365     1996724 :                 hQMetaData->q_direction[0].band_data[b].bits_sph_idx[m] = bits_direction_masa[hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]]; /*Q0*/
     366     1996724 :                 move16();
     367     1996724 :                 bits_dir_raw_pre[0] = add( bits_dir_raw_pre[0], hQMetaData->q_direction[0].band_data[b].bits_sph_idx[m] );
     368     1996724 :                 move16();
     369             :             }
     370             :         }
     371             :     }
     372             : 
     373      184762 :     IF( EQ_32( hQMetaData->no_directions, 2 ) )
     374             :     {
     375       20067 :         no_TF = add( i_mult2( hQMetaData->q_direction[0].cfg.nbands, hQMetaData->q_direction[0].cfg.nblocks ), i_mult2( hQMetaData->q_direction[1].cfg.nbands, hQMetaData->q_direction[1].cfg.nblocks ) ); /*Q0*/
     376       20067 :         tmp32 = L_sub( L_deposit_h( sub( sub( hQMetaData->metadata_max_bits, bits_no_dirs_coh ), bits_diff_sum ) ), L_mult0( 17612 /* 4.2998046875f in Q12 */, shl( no_TF, 4 ) ) );                        /*Q16*/
     377       20067 :         test();
     378       20067 :         IF( !all_coherence_zero && GE_32( tmp32, L_deposit_h( MASA_MIN_BITS_SURR_COH ) ) )
     379             :         {
     380        4009 :             bits_sur_coherence = read_surround_coherence( bitstream, index, hQMetaData ); /*Q0*/
     381             :         }
     382             :         ELSE
     383             :         {
     384       16058 :             bits_sur_coherence = 0;
     385       16058 :             move16();
     386             :             /*Surround coherence*/
     387      208754 :             FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
     388             :             {
     389      192696 :                 IF( hQMetaData->surcoh_band_data != NULL )
     390             :                 {
     391           0 :                     set_c( (Word8 *) hQMetaData->surcoh_band_data[b].surround_coherence, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
     392             :                 }
     393             :             }
     394             :         }
     395       20067 :         bits_no_dirs_coh = add( bits_no_dirs_coh, bits_sur_coherence );
     396       20067 :         total_bits_1dir = extract_l( L_mult0( sub( hQMetaData->metadata_max_bits, bits_no_dirs_coh ), i_mult2( hQMetaData->q_direction[0].cfg.nbands, hQMetaData->q_direction[0].cfg.nblocks ) ) / no_TF ); /*Q0*/
     397             :     }
     398             :     ELSE
     399             :     {
     400      164695 :         no_TF = i_mult2( hQMetaData->q_direction[0].cfg.nbands, hQMetaData->q_direction[0].cfg.nblocks );                                                                           /*Q0*/
     401      164695 :         tmp32 = L_sub( L_deposit_h( sub( sub( hQMetaData->metadata_max_bits, bits_no_dirs_coh ), bits_diff_sum ) ), L_mult0( 17612 /* 4.2998046875f in Q12 */, shl( no_TF, 4 ) ) ); /*Q16*/
     402      164695 :         test();
     403      164695 :         IF( !all_coherence_zero && GE_32( tmp32, L_deposit_h( MASA_MIN_BITS_SURR_COH ) ) )
     404             :         {
     405       20176 :             bits_sur_coherence = read_surround_coherence( bitstream, index, hQMetaData ); /*Q0*/
     406             :         }
     407             :         ELSE
     408             :         {
     409      144519 :             bits_sur_coherence = 0;
     410      144519 :             move16();
     411             :             /*Surround coherence*/
     412      608646 :             FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
     413             :             {
     414      464127 :                 IF( hQMetaData->surcoh_band_data != NULL )
     415             :                 {
     416       13902 :                     set_c( (Word8 *) hQMetaData->surcoh_band_data[b].surround_coherence, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
     417             :                 }
     418             :             }
     419             :         }
     420      164695 :         bits_no_dirs_coh = add( bits_no_dirs_coh, bits_sur_coherence );
     421             : 
     422      164695 :         total_bits_1dir = sub( hQMetaData->metadata_max_bits, bits_no_dirs_coh );
     423             :     }
     424             : 
     425      184762 :     bits_dir_target = 0;
     426      184762 :     move16();
     427      184762 :     bits_dir_used = 0;
     428      184762 :     move16();
     429             : 
     430      389591 :     FOR( d = 0; d < hQMetaData->no_directions; d++ )
     431             :     {
     432      204829 :         q_direction = &hQMetaData->q_direction[d];
     433      204829 :         nbands = q_direction->cfg.nbands; /*Q0*/
     434      204829 :         move16();
     435      204829 :         nblocks = q_direction->cfg.nblocks; /*Q0*/
     436      204829 :         move16();
     437      204829 :         start_band = q_direction->cfg.start_band; /*Q0*/
     438      204829 :         move16();
     439             : 
     440      204829 :         diffuseness_index_max_ec_frame = diffuseness_index_max_ec_frame_pre[0]; /*Q0*/
     441      204829 :         move16();
     442      204829 :         IF( d == 0 )
     443             :         {
     444      184762 :             bits_diff = bits_diff_sum; /*Q0*/
     445      184762 :             move16();
     446             :         }
     447             :         ELSE
     448             :         {
     449       20067 :             bits_diff = 0;
     450       20067 :             move16();
     451             :         }
     452      204829 :         bits_dir_raw = bits_dir_raw_pre[d]; /*Q0*/
     453      204829 :         move16();
     454             : 
     455             :         /* Read coherence, if any */
     456      204829 :         bits_coherence = 0;
     457      204829 :         move16();
     458             : 
     459      204829 :         IF( all_coherence_zero == 0 )
     460             :         {
     461       28286 :             bits_coherence = read_coherence_data_fx( bitstream, index, hQMetaData, d, 0 ); /*Q0*/
     462             :         }
     463             :         ELSE
     464             :         {
     465             :             /*Surround coherence*/
     466     1025602 :             FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
     467             :             {
     468      849059 :                 IF( hQMetaData->surcoh_band_data != NULL )
     469             :                 {
     470       13442 :                     set_c( (Word8 *) hQMetaData->surcoh_band_data[b].surround_coherence, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
     471             :                 }
     472             : 
     473      849059 :                 IF( hQMetaData->q_direction[d].coherence_band_data != NULL )
     474             :                 {
     475       13442 :                     set_c( (Word8 *) hQMetaData->q_direction[d].coherence_band_data[b].spread_coherence, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
     476             :                 }
     477             :             }
     478             :         }
     479             : 
     480             :         /* Read 2D signaling*/
     481      204829 :         q_direction->not_in_2D = bitstream[( *index )--]; /*Q0*/
     482      204829 :         move16();
     483      204829 :         signal_bits = 1;
     484      204829 :         move16();
     485             : 
     486             :         /* Read EC signaling */
     487      204829 :         ec_flag = 0;
     488      204829 :         move16();
     489      204829 :         IF( LE_16( add( total_bits_1dir, bits_sur_coherence ), hQMetaData->qmetadata_max_bit_req ) )
     490             :         {
     491      141862 :             ec_flag = bitstream[( *index )];
     492      141862 :             move16();
     493      141862 :             ( *index ) = sub( ( *index ), 1 );
     494      141862 :             move16();
     495      141862 :             signal_bits = add( signal_bits, 1 );
     496      141862 :             IF( GT_16( nblocks, 1 ) )
     497             :             {
     498      105684 :                 IF( ec_flag )
     499             :                 {
     500        6737 :                     ec_flag = add( ec_flag, (Word16) bitstream[( *index )--] );
     501        6737 :                     signal_bits = add( signal_bits, 1 );
     502             :                 }
     503             :             }
     504             :         }
     505             : 
     506             :         /* Decode quantized directions frame-wise */
     507      204829 :         test();
     508      204829 :         IF( !ec_flag ) /* EC 1*/
     509             :         {
     510      194845 :             bits_dir = 0;
     511      194845 :             move16();
     512      194845 :             raw_flag[0] = bitstream[( *index )--]; /*Q0*/
     513      194845 :             move16();
     514      194845 :             bits_dir = add( bits_dir, 1 );
     515             : 
     516      194845 :             IF( !raw_flag[0] )
     517             :             {
     518      104332 :                 bits_dir = add( bits_dir, ivas_qmetadata_entropy_decode_dir_fx( q_direction, bitstream, index, diffuseness_index_max_ec_frame, nbands, start_band, 0 ) );
     519             :             }
     520             :             ELSE
     521             :             {
     522       90513 :                 bits_dir = add( bits_dir, ivas_qmetadata_raw_decode_dir_fx( q_direction, bitstream, index, nbands, start_band, 0 ) );
     523             :             }
     524             :         }
     525             :         /* Decode quantized directions band-wise */
     526        9984 :         ELSE IF( EQ_16( ec_flag, 1 ) && GT_16( nblocks, 1 ) ) /* EC2 */
     527             :         {
     528        1828 :             bits_dir = 0;
     529        1828 :             move16();
     530        9029 :             FOR( b = start_band; b < nbands; b++ )
     531             :             {
     532        7201 :                 raw_flag[b] = bitstream[( *index )--]; /*Q0*/
     533        7201 :                 move16();
     534        7201 :                 bits_dir = add( bits_dir, 1 );
     535             :             }
     536             : 
     537             :             /* Read EC bits*/
     538        1828 :             diff_bits = add( bits_diff, add( bits_coherence, sub( signal_bits, total_bits_1dir ) ) );
     539             : 
     540        9029 :             FOR( b = start_band; b < nbands; b++ )
     541             :             {
     542        7201 :                 IF( !raw_flag[b] )
     543             :                 {
     544        2585 :                     bits_dir = add( bits_dir, ivas_qmetadata_entropy_decode_dir_fx( q_direction, bitstream, index, diffuseness_index_max_ec_frame, b + 1, b, 0 ) );
     545             :                 }
     546             :                 ELSE
     547             :                 {
     548        4616 :                     diff_bits = add( diff_bits, q_direction->band_data[b].bits_sph_idx[0] * q_direction->cfg.nblocks );
     549             :                 }
     550             :             }
     551        1828 :             diff_bits = add( diff_bits, bits_dir );
     552             : 
     553             :             /* Small requantization?*/
     554        1828 :             IF( q_direction->not_in_2D > 0 )
     555             :             {
     556             :                 /* This is not an ideal solution but mirrors better encoder */
     557             :                 Word16 i, j;
     558             :                 UWord16 bits_temp[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES];
     559             : 
     560        8876 :                 FOR( i = q_direction->cfg.start_band; i < q_direction->cfg.nbands; i++ )
     561             :                 {
     562       35380 :                     FOR( j = 0; j < q_direction->cfg.nblocks; j++ )
     563             :                     {
     564       28304 :                         bits_temp[i][j] = q_direction->band_data[i].bits_sph_idx[j]; /*Q0*/
     565       28304 :                         move16();
     566             :                     }
     567             :                 }
     568             : 
     569        1800 :                 small_reduction_direction_fx( q_direction, bits_temp, raw_flag, &diff_bits );
     570             : 
     571        8876 :                 FOR( i = q_direction->cfg.start_band; i < q_direction->cfg.nbands; i++ )
     572             :                 {
     573       35380 :                     FOR( j = 0; j < q_direction->cfg.nblocks; j++ )
     574             :                     {
     575       28304 :                         q_direction->band_data[i].bits_sph_idx[j] = bits_temp[i][j]; /*Q0*/
     576       28304 :                         move16();
     577             :                     }
     578             :                 }
     579             :             }
     580             : 
     581             :             /* Read raw-coded bits*/
     582        9029 :             FOR( b = start_band; b < nbands; b++ )
     583             :             {
     584        7201 :                 IF( raw_flag[b] )
     585             :                 {
     586        4616 :                     bits_dir = add( bits_dir, ivas_qmetadata_raw_decode_dir_fx( q_direction, bitstream, index, b + 1, b, 0 ) );
     587             :                 }
     588             :             }
     589             :         }
     590             :         /* Decode requantized directions */
     591             :         ELSE /* EC3 */
     592             :         {
     593             :             Word16 dummy;
     594        8156 :             ec_flag = 2;
     595        8156 :             move16();
     596             : 
     597        8156 :             IF( hQMetaData->is_masa_ivas_format == 0 )
     598             :             {
     599        2976 :                 reduce_bits = sub( bits_dir_raw, sub( sub( sub( total_bits_1dir, bits_diff ), bits_coherence ), signal_bits ) ); /*Q0*/
     600        2976 :                 ind_order[0] = -1;
     601        2976 :                 move16();
     602             :             }
     603             :             ELSE
     604             :             {
     605        5180 :                 ind_order[0] = 0;
     606        5180 :                 move16();
     607        5180 :                 reduce_bits = s_min( add( i_mult2( nbands, nblocks ), MASA_BIT_REDUCT_PARAM ), sub( bits_dir_raw, sub( sub( sub( total_bits_1dir, bits_diff ), bits_coherence ), signal_bits ) ) ); /*Q0*/
     608        5180 :                 IF( GT_16( reduce_bits, sub( bits_dir_raw, i_mult2( nbands, nblocks ) ) ) )
     609             :                 {
     610          71 :                     reduce_bits = sub( bits_dir_raw, i_mult2( nbands, nblocks ) );
     611             :                 }
     612             :             }
     613        8156 :             only_reduce_bits_direction_fx( &dummy, q_direction, reduce_bits, nbands, nblocks, ind_order );
     614             : 
     615             :             /* Read directions */
     616        8156 :             bits_dir = read_directions_fx( q_direction, (UWord8) nbands, (UWord8) nblocks, bitstream, index, ind_order ); /*Q0*/
     617             :         }
     618             : 
     619      204829 :         IF( bits_coherence > 0 )
     620             :         {
     621       27429 :             IF( GT_16( nblocks, 1 ) )
     622             :             {
     623       20277 :                 decode_spread_coherence_fx( hQMetaData, d, nblocks, 0 );
     624             :             }
     625             :         }
     626             :         ELSE
     627             :         {
     628     1030447 :             FOR( b = start_band; b < nbands; b++ )
     629             :             {
     630      853047 :                 IF( q_direction->coherence_band_data != NULL )
     631             :                 {
     632       17430 :                     set_c( (Word8 *) q_direction->coherence_band_data[b].spread_coherence, 0, nblocks );
     633             :                 }
     634             :             }
     635             :         }
     636      204829 :         IF( d == 0 )
     637             :         {
     638      184762 :             total_bits_1dir = sub( hQMetaData->metadata_max_bits, sub( start_index_0, *index ) ); /*Q0*/
     639             :         }
     640             : 
     641      204829 :         bits_dir_target = add( bits_dir_target, bits_dir_raw );
     642      204829 :         bits_dir_used = add( bits_dir_used, bits_dir );
     643             :     }
     644             :     /* move 2 dir data to its correct subband */
     645      184762 :     IF( EQ_32( hQMetaData->no_directions, 2 ) )
     646             :     {
     647       20067 :         d = sub( hQMetaData->q_direction[1].cfg.nbands, 1 );
     648       20067 :         nblocks = hQMetaData->q_direction[0].cfg.nblocks;
     649       20067 :         move16();
     650             : 
     651      249036 :         FOR( b = hQMetaData->q_direction[0].cfg.nbands - 1; b >= 0; b-- )
     652             :         {
     653      228969 :             IF( EQ_16( hQMetaData->twoDirBands[b], 1 ) )
     654             :             {
     655      204816 :                 Copy32( hQMetaData->q_direction[1].band_data[d].azimuth_fx, hQMetaData->q_direction[1].band_data[b].azimuth_fx, nblocks );           /*Q22*/
     656      204816 :                 Copy32( hQMetaData->q_direction[1].band_data[d].elevation_fx, hQMetaData->q_direction[1].band_data[b].elevation_fx, nblocks );       /*Q22*/
     657      204816 :                 Copy32( hQMetaData->q_direction[1].band_data[d].energy_ratio_fx, hQMetaData->q_direction[1].band_data[b].energy_ratio_fx, nblocks ); /*Q30*/
     658             : 
     659      204816 :                 IF( LT_32( hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0], 7 ) )
     660             :                 {
     661      722537 :                     FOR( m = 0; m < nblocks; m++ )
     662             :                     {
     663      576328 :                         Word32 a1 = hQMetaData->q_direction[1].band_data[b].azimuth_fx[m]; /*Q22*/
     664      576328 :                         move32();
     665      576328 :                         a1 = L_shr( hQMetaData->q_direction[1].band_data[b].azimuth_fx[m], 1 ); /*Q21*/
     666      576328 :                         Word32 b1 = hQMetaData->q_direction[0].band_data[b].azimuth_fx[m];      /*Q22*/
     667      576328 :                         move32();
     668      576328 :                         b1 = L_shr( hQMetaData->q_direction[0].band_data[b].azimuth_fx[m], 1 ); /*Q21*/
     669      576328 :                         Word32 c = L_shr( DEGREE_180_Q_22, 1 );                                 /*Q21*/
     670      576328 :                         a1 = L_add( a1, L_sub( b1, c ) );
     671      576328 :                         IF( GE_32( a1, L_shr( DEGREE_180_Q_22, 1 ) ) )
     672             :                         {
     673           0 :                             a1 = L_sub( a1, L_shr( DEGREE_360_Q_22, 1 ) ); /*Q21*/
     674             :                         }
     675      576328 :                         IF( LT_32( a1, L_shr( -DEGREE_180_Q_22, 1 ) ) )
     676             :                         {
     677      108633 :                             a1 = L_add( a1, L_shr( DEGREE_360_Q_22, 1 ) ); /*Q21*/
     678             :                         }
     679             : 
     680      576328 :                         hQMetaData->q_direction[1].band_data[b].azimuth_fx[m] = L_shl( a1, 1 ); /*Q22*/
     681      576328 :                         move32();
     682             :                     }
     683             :                 }
     684             : 
     685      204816 :                 IF( hQMetaData->q_direction[1].coherence_band_data != NULL )
     686             :                 {
     687       12120 :                     mvc2c( hQMetaData->q_direction[1].coherence_band_data[d].spread_coherence, hQMetaData->q_direction[1].coherence_band_data[b].spread_coherence, nblocks ); /*Q0*/
     688             :                 }
     689      204816 :                 d = sub( d, 1 );
     690             :             }
     691             :             ELSE
     692             :             {
     693       24153 :                 set32_fx( hQMetaData->q_direction[1].band_data[b].azimuth_fx, 0, nblocks );
     694       24153 :                 set32_fx( hQMetaData->q_direction[1].band_data[b].elevation_fx, 0, nblocks );
     695       24153 :                 set32_fx( hQMetaData->q_direction[1].band_data[b].energy_ratio_fx, 0, nblocks );
     696             : 
     697       24153 :                 IF( hQMetaData->q_direction[1].coherence_band_data != NULL )
     698             :                 {
     699       24153 :                     set_c( (Word8 *) hQMetaData->q_direction[1].coherence_band_data[b].spread_coherence, 0, nblocks );
     700             :                 }
     701             :             }
     702             :         }
     703             : 
     704             :         /* Scale energy ratios that sum to over one */
     705       20067 :         IF( hodirac_flag == 0 )
     706             :         {
     707       40282 :             FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
     708             :             {
     709             :                 Word32 ratioSum_flt_fx;
     710             : 
     711       36273 :                 ratioSum_flt_fx = L_add( hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[0], hQMetaData->q_direction[1].band_data[b].energy_ratio_fx[0] ); /*Q30*/
     712             : 
     713       36273 :                 IF( GT_32( ratioSum_flt_fx, ONE_IN_Q30 ) )
     714             :                 {
     715           0 :                     set32_fx( hQMetaData->q_direction[0].band_data[b].energy_ratio_fx, L_shl( (Word32) divide3232( hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[0], ratioSum_flt_fx ), 15 ) /* Q30 */, nblocks ); /*Q30*/
     716           0 :                     set32_fx( hQMetaData->q_direction[1].band_data[b].energy_ratio_fx, L_shl( (Word32) divide3232( hQMetaData->q_direction[1].band_data[b].energy_ratio_fx[0], ratioSum_flt_fx ), 15 ) /* Q30 */, nblocks ); /*Q30*/
     717             :                 }
     718             :             }
     719             :         }
     720             :     }
     721             : 
     722             :     /* Store status information for renderer use */
     723      184762 :     hQMetaData->ec_flag = ec_flag;
     724      184762 :     move16();
     725             : 
     726      184762 :     IF( GT_16( bits_dir_used, bits_dir_target ) )
     727             :     {
     728       71696 :         hQMetaData->dir_comp_ratio_fx = MAX_WORD16; /*Q15*/
     729       71696 :         move16();
     730             :     }
     731             :     ELSE
     732             :     {
     733      113066 :         hQMetaData->dir_comp_ratio_fx = divide3232( bits_dir_used, bits_dir_target ); /*Q15*/
     734             :     }
     735      184762 :     return sub( start_index_0, *index );
     736             : }
     737             : 
     738             : /*-----------------------------------------------------------------------*
     739             :  * ivas_qmetadata_dec_decode_hr_384_512()
     740             :  *
     741             :  * Main function for decoding Spatial Metadata at HRs
     742             :  *-----------------------------------------------------------------------*/
     743             : 
     744             : /*! r: number of bits read */
     745        2241 : Word16 ivas_qmetadata_dec_decode_hr_384_512(
     746             :     IVAS_QMETADATA_HANDLE hQMetaData,      /* i/o: hQMetaData handle             */
     747             :     UWord16 *bitstream,                    /* i  : bitstream                     Q0*/
     748             :     Word16 *index,                         /* i/o: bitstream position            Q0*/
     749             :     const SPHERICAL_GRID_DATA *sph_grid16, /* i  : spherical grid for deindexing */
     750             :     const Word16 bits_sph_idx,
     751             :     const Word16 bits_sp_coh,
     752             :     const UWord8 ncoding_bands_config )
     753             : {
     754             :     Word16 d, b, m;
     755             :     Word16 nbands, start_band;
     756             :     IVAS_QDIRECTION *q_direction;
     757             :     Word16 start_index_0;
     758             :     UWord16 all_coherence_zero;
     759             :     Word16 p[MASA_MAXIMUM_CODING_SUBBANDS], dif_p[MASA_MAXIMUM_CODING_SUBBANDS];
     760             :     Word16 codedBands, sf_nbands0, sf_nbands1;
     761        2241 :     sf_nbands1 = 1;
     762        2241 :     move16();
     763             :     Word64 W_nrg_ratio[2][MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES];
     764             : 
     765        2241 :     start_index_0 = *index;
     766        2241 :     move16();
     767             :     /* read number of higher inactive/not encoded  bands */
     768        2241 :     IF( bitstream[( *index )--] )
     769             :     {
     770         290 :         codedBands = sub( sub( MASA_MAXIMUM_CODING_SUBBANDS, ivas_qmetadata_DecodeExtendedGR( bitstream, index, MASA_MAXIMUM_CODING_SUBBANDS, 1 ) ), 1 ); /*Q0*/
     771             :     }
     772             :     ELSE
     773             :     {
     774        1951 :         codedBands = MASA_MAXIMUM_CODING_SUBBANDS; /*Q0*/
     775        1951 :         move16();
     776             :     }
     777        2531 :     FOR( b = codedBands; b < ncoding_bands_config; b++ )
     778             :     {
     779        1450 :         FOR( m = 0; m < MAX_PARAM_SPATIAL_SUBFRAMES; m++ )
     780             :         {
     781             : 
     782        1160 :             hQMetaData->q_direction[0].band_data[b].azimuth_fx[m] = 0;
     783        1160 :             move32();
     784        1160 :             hQMetaData->q_direction[0].band_data[b].elevation_fx[m] = 0;
     785        1160 :             move32();
     786        1160 :             hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[m] = 0;
     787        1160 :             move32();
     788        1160 :             W_nrg_ratio[0][b][m] = 0;
     789        1160 :             move64();
     790             : 
     791        1160 :             test();
     792        1160 :             IF( hQMetaData->coherence_flag && hQMetaData->q_direction[0].coherence_band_data != NULL )
     793             :             {
     794        1160 :                 hQMetaData->q_direction[0].coherence_band_data[b].spread_coherence[m] = 0u;
     795        1160 :                 move16();
     796             :             }
     797             : 
     798        1160 :             IF( EQ_32( hQMetaData->no_directions, 2 ) )
     799             :             {
     800             : 
     801        1160 :                 hQMetaData->q_direction[1].band_data[b].azimuth_fx[m] = 0;
     802        1160 :                 move32();
     803        1160 :                 hQMetaData->q_direction[1].band_data[b].elevation_fx[m] = 0;
     804        1160 :                 move32();
     805        1160 :                 hQMetaData->q_direction[1].band_data[b].energy_ratio_fx[m] = 0;
     806        1160 :                 move32();
     807        1160 :                 W_nrg_ratio[1][b][m] = 0;
     808        1160 :                 move64();
     809             : 
     810        1160 :                 test();
     811        1160 :                 IF( hQMetaData->coherence_flag && hQMetaData->q_direction[1].coherence_band_data != NULL )
     812             :                 {
     813        1160 :                     hQMetaData->q_direction[1].coherence_band_data[b].spread_coherence[m] = 0u;
     814        1160 :                     move16();
     815             :                 }
     816             :             }
     817             : 
     818        1160 :             test();
     819        1160 :             IF( hQMetaData->coherence_flag && hQMetaData->surcoh_band_data != NULL )
     820             :             {
     821        1160 :                 hQMetaData->surcoh_band_data[b].surround_coherence[m] = 0u;
     822        1160 :                 move16();
     823             :             }
     824             :         }
     825             : 
     826         290 :         IF( EQ_32( hQMetaData->no_directions, 2 ) )
     827             :         {
     828         290 :             hQMetaData->twoDirBands[b] = 0;
     829         290 :             move16();
     830             :         }
     831             :     }
     832        2241 :     sf_nbands0 = hQMetaData->q_direction[0].cfg.nbands; /*Q0*/
     833        2241 :     move16();
     834             : 
     835        2241 :     hQMetaData->q_direction[0].cfg.nbands = codedBands; /*Q0*/
     836        2241 :     move16();
     837             : 
     838             :     /*Coherence flag decoding*/
     839        2241 :     all_coherence_zero = 1;
     840        2241 :     move16();
     841        2241 :     IF( hQMetaData->coherence_flag )
     842             :     {
     843             :         /* read if coherence is zero */
     844        2241 :         all_coherence_zero = bitstream[( *index )--]; /*Q0*/
     845        2241 :         move16();
     846             :     }
     847             : 
     848        2241 :     hQMetaData->all_coherence_zero = (UWord8) all_coherence_zero; /*Q0*/
     849             : 
     850        2241 :     IF( EQ_32( hQMetaData->no_directions, 2 ) )
     851             :     {
     852        1244 :         set_c( (Word8 *) hQMetaData->twoDirBands, 1, hQMetaData->q_direction[0].cfg.nbands );
     853             :     }
     854             : 
     855        2241 :     test();
     856        2241 :     IF( EQ_16( bits_sph_idx, 11 ) && EQ_32( hQMetaData->no_directions, 2 ) )
     857             :     {
     858             :         /* Read which bands have 2 directions */
     859         864 :         hQMetaData->q_direction[1].cfg.nbands = hQMetaData->numTwoDirBands; /*Q0*/
     860         864 :         move16();
     861         864 :         sf_nbands1 = hQMetaData->q_direction[1].cfg.nbands; /*Q0*/
     862         864 :         move16();
     863         864 :         if ( GT_16( hQMetaData->q_direction[1].cfg.nbands, codedBands ) )
     864             :         {
     865           0 :             hQMetaData->q_direction[1].cfg.nbands = codedBands; /*Q0*/
     866           0 :             move16();
     867             :         }
     868         864 :         set_c( (Word8 *) hQMetaData->twoDirBands, 0, hQMetaData->q_direction[0].cfg.nbands );
     869         864 :         d = *index;
     870         864 :         move16();
     871         864 :         dif_p[0] = ivas_qmetadata_DecodeExtendedGR( bitstream, index, MASA_MAXIMUM_CODING_SUBBANDS, 0 ); /*Q0*/
     872         864 :         move16();
     873         864 :         p[0] = dif_p[0];
     874         864 :         move16();
     875         864 :         hQMetaData->twoDirBands[p[0]] = 1;
     876         864 :         move16();
     877        8214 :         FOR( b = 1; b < hQMetaData->q_direction[1].cfg.nbands; b++ )
     878             :         {
     879        7350 :             dif_p[b] = ivas_qmetadata_DecodeExtendedGR( bitstream, index, MASA_MAXIMUM_CODING_SUBBANDS, 0 ); /*Q0*/
     880        7350 :             move16();
     881        7350 :             p[b] = add( add( p[b - 1], dif_p[b] ), 1 );
     882        7350 :             move16();
     883        7350 :             hQMetaData->twoDirBands[p[b]] = 1;
     884        7350 :             move16();
     885             :         }
     886             :     }
     887             : 
     888        2241 :     test();
     889        2241 :     IF( EQ_16( bits_sph_idx, 16 ) && EQ_32( hQMetaData->no_directions, 2 ) )
     890             :     {
     891         380 :         sf_nbands1 = hQMetaData->q_direction[1].cfg.nbands; /*Q0*/
     892         380 :         move16();
     893         380 :         IF( GT_16( hQMetaData->q_direction[1].cfg.nbands, codedBands ) )
     894             :         {
     895           0 :             hQMetaData->q_direction[1].cfg.nbands = codedBands; /*Q0*/
     896           0 :             move16();
     897             :         }
     898             :     }
     899        2241 :     ivas_qmetadata_entropy_decode_diffuseness_hr_512( bitstream, index, &( hQMetaData->q_direction[0] ) );
     900             : 
     901        2241 :     IF( EQ_32( hQMetaData->no_directions, 2 ) )
     902             :     {
     903        1244 :         ivas_qmetadata_entropy_decode_diffuseness_hr_512( bitstream, index, &( hQMetaData->q_direction[1] ) );
     904             :     }
     905             : 
     906             : 
     907       55735 :     FOR( b = hQMetaData->q_direction[0].cfg.start_band; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
     908             :     {
     909      257396 :         FOR( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ )
     910             :         {
     911      203902 :             W_nrg_ratio[0][b][m] = W_sub( ONE_IN_Q62, diffuseness_reconstructions_hr_fx[hQMetaData->q_direction[0].band_data[b].energy_ratio_index[m]] ); /*Q62*/
     912      203902 :             move64();
     913             :         }
     914             :     }
     915        2241 :     IF( EQ_32( hQMetaData->no_directions, 2 ) )
     916             :     {
     917             :         Word32 ratioSum;
     918        1244 :         IF( EQ_16( bits_sph_idx, 16 ) )
     919             :         {
     920        9500 :             FOR( b = hQMetaData->q_direction[1].cfg.start_band; b < hQMetaData->q_direction[1].cfg.nbands; b++ )
     921             :             {
     922       45600 :                 FOR( m = 0; m < hQMetaData->q_direction[1].cfg.nblocks; m++ )
     923             :                 {
     924       36480 :                     W_nrg_ratio[1][b][m] = W_sub( ONE_IN_Q62, diffuseness_reconstructions_hr_fx[hQMetaData->q_direction[1].band_data[b].energy_ratio_index[m]] ); /*Q62*/
     925       36480 :                     move64();
     926             : 
     927             :                     /* Scale energy ratios that sum to over one */
     928       36480 :                     ratioSum = W_round64_L( W_add( W_nrg_ratio[0][b][m], W_nrg_ratio[1][b][m] ) ); /*Q30*/
     929             : 
     930       36480 :                     IF( GT_32( ratioSum, ONE_IN_Q30 ) )
     931             :                     {
     932        1294 :                         W_nrg_ratio[0][b][m] = W_shl( (Word64) ( W_nrg_ratio[0][b][m] / ratioSum ), 30 ); // Q62
     933        1294 :                         move64();
     934        1294 :                         W_nrg_ratio[1][b][m] = W_shl( (Word64) ( W_nrg_ratio[1][b][m] / ratioSum ), 30 ); // Q62
     935        1294 :                         move64();
     936             :                     }
     937             :                 }
     938             :             }
     939             :         }
     940             :         ELSE
     941             :         {
     942             :             Word16 pos_2dir_band[MASA_MAXIMUM_CODING_SUBBANDS];
     943         864 :             d = 0;
     944         864 :             move16();
     945       21310 :             FOR( b = hQMetaData->q_direction[0].cfg.start_band; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
     946             :             {
     947       20446 :                 IF( EQ_16( hQMetaData->twoDirBands[b], 1 ) )
     948             :                 {
     949        8214 :                     pos_2dir_band[d] = b; /*Q0*/
     950        8214 :                     move16();
     951        8214 :                     d = add( d, 1 );
     952             :                 }
     953             :                 ELSE
     954             :                 {
     955       12232 :                     pos_2dir_band[d] = 0;
     956       12232 :                     move16();
     957             :                 }
     958             :             }
     959        9078 :             FOR( b = hQMetaData->q_direction[1].cfg.start_band; b < hQMetaData->q_direction[1].cfg.nbands; b++ )
     960             :             {
     961       35814 :                 FOR( m = 0; m < hQMetaData->q_direction[1].cfg.nblocks; m++ )
     962             :                 {
     963             : 
     964       27600 :                     W_nrg_ratio[1][b][m] = W_sub( ONE_IN_Q62, diffuseness_reconstructions_hr_fx[hQMetaData->q_direction[1].band_data[b].energy_ratio_index[m]] ); /*Q62*/
     965       27600 :                     move64();
     966             : 
     967       27600 :                     ratioSum = W_round64_L( W_add( W_nrg_ratio[0][pos_2dir_band[b]][m], W_nrg_ratio[1][b][m] ) ); /*Q30*/
     968             : 
     969       27600 :                     IF( GT_32( ratioSum, ONE_IN_Q30 ) )
     970             :                     {
     971         322 :                         W_nrg_ratio[0][pos_2dir_band[b]][m] = W_shl( (Word64) ( W_nrg_ratio[0][pos_2dir_band[b]][m] / ratioSum ), 30 ); /*Q62*/
     972         322 :                         move64();
     973         322 :                         W_nrg_ratio[1][b][m] = W_shl( (Word64) ( W_nrg_ratio[1][b][m] / ratioSum ), 30 ); /*Q62*/
     974         322 :                         move64();
     975             :                     }
     976             :                 }
     977             :             }
     978             :         }
     979             :     }
     980             : 
     981        2241 :     IF( EQ_32( hQMetaData->no_directions, 2 ) )
     982             :     {
     983       18578 :         FOR( b = hQMetaData->q_direction[1].cfg.start_band; b < hQMetaData->q_direction[1].cfg.nbands; b++ )
     984             :         {
     985       81414 :             FOR( m = 0; m < hQMetaData->q_direction[1].cfg.nblocks; m++ )
     986             :             {
     987       64080 :                 hQMetaData->q_direction[1].band_data[b].energy_ratio_index_mod[m] = hQMetaData->q_direction[1].band_data[b].energy_ratio_index[m]; /*Q0*/
     988       64080 :                 move16();
     989       64080 :                 hQMetaData->q_direction[1].band_data[b].bits_sph_idx[m] = bits_sph_idx; /*Q0*/
     990       64080 :                 move16();
     991             :             }
     992             :         }
     993             :     }
     994             : 
     995       55735 :     FOR( b = hQMetaData->q_direction[0].cfg.start_band; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
     996             :     {
     997      257396 :         FOR( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ )
     998             :         {
     999      203902 :             hQMetaData->q_direction[0].band_data[b].energy_ratio_index_mod[m] = hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]; /*Q0*/
    1000      203902 :             move16();
    1001      203902 :             hQMetaData->q_direction[0].band_data[b].bits_sph_idx[m] = bits_sph_idx; /*Q0*/
    1002      203902 :             move16();
    1003             :         }
    1004             :     }
    1005             : 
    1006        2241 :     IF( !all_coherence_zero )
    1007             :     {
    1008        2241 :         read_surround_coherence_hr_fx( bitstream, index, hQMetaData, W_nrg_ratio );
    1009             :     }
    1010             :     ELSE
    1011             :     {
    1012             :         /*Surround coherence*/
    1013           0 :         FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
    1014             :         {
    1015           0 :             IF( hQMetaData->surcoh_band_data != NULL )
    1016             :             {
    1017           0 :                 set_c( (Word8 *) hQMetaData->surcoh_band_data[b].surround_coherence, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
    1018             :             }
    1019             :         }
    1020             :     }
    1021             : 
    1022        5726 :     FOR( d = 0; d < hQMetaData->no_directions; d++ )
    1023             :     {
    1024        3485 :         q_direction = &hQMetaData->q_direction[d];
    1025        3485 :         nbands = q_direction->cfg.nbands;
    1026        3485 :         move16();
    1027        3485 :         start_band = q_direction->cfg.start_band;
    1028        3485 :         move16();
    1029             : 
    1030             :         /* Read coherence, IF any */
    1031        3485 :         IF( !all_coherence_zero )
    1032             :         {
    1033        3485 :             read_coherence_data_hr_512_fx( bitstream, index, hQMetaData, d, bits_sp_coh );
    1034             :         }
    1035             :         ELSE
    1036             :         {
    1037             :             /*Surround coherence*/
    1038           0 :             FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
    1039             :             {
    1040           0 :                 IF( hQMetaData->surcoh_band_data != NULL )
    1041             :                 {
    1042           0 :                     set_c( (Word8 *) hQMetaData->surcoh_band_data[b].surround_coherence, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
    1043             :                 }
    1044             : 
    1045           0 :                 IF( hQMetaData->q_direction[d].coherence_band_data != NULL )
    1046             :                 {
    1047           0 :                     set_c( (Word8 *) hQMetaData->q_direction[d].coherence_band_data[b].spread_coherence, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
    1048             :                 }
    1049             :             }
    1050             :         }
    1051             : 
    1052             :         /* Decode quantized directions frame-wise */
    1053             : 
    1054        3485 :         ivas_qmetadata_raw_decode_dir_512_fx( q_direction, bitstream, index, nbands, start_band, sph_grid16 );
    1055             :     }
    1056             : 
    1057        2241 :     IF( EQ_32( hQMetaData->no_directions, 2 ) )
    1058             :     {
    1059             :         /* move 2 dir data to its correct subband */
    1060        1244 :         IF( EQ_16( bits_sph_idx, 11 ) )
    1061             :         {
    1062             :             Word16 nblocks;
    1063         864 :             d = sub( hQMetaData->q_direction[1].cfg.nbands, 1 );
    1064         864 :             nblocks = hQMetaData->q_direction[0].cfg.nblocks;
    1065         864 :             move16();
    1066             : 
    1067       21310 :             FOR( b = hQMetaData->q_direction[0].cfg.nbands - 1; b >= 0; b-- )
    1068             :             {
    1069       20446 :                 IF( EQ_16( hQMetaData->twoDirBands[b], 1 ) )
    1070             :                 {
    1071             : 
    1072        8214 :                     Copy32( hQMetaData->q_direction[1].band_data[d].azimuth_fx, hQMetaData->q_direction[1].band_data[b].azimuth_fx, nblocks );           /*Q22*/
    1073        8214 :                     Copy32( hQMetaData->q_direction[1].band_data[d].elevation_fx, hQMetaData->q_direction[1].band_data[b].elevation_fx, nblocks );       /*Q22*/
    1074        8214 :                     Copy32( hQMetaData->q_direction[1].band_data[d].energy_ratio_fx, hQMetaData->q_direction[1].band_data[b].energy_ratio_fx, nblocks ); /*Q30*/
    1075        8214 :                     Copy64( W_nrg_ratio[1][d], W_nrg_ratio[1][b], nblocks );
    1076             : 
    1077        8214 :                     IF( hQMetaData->q_direction[1].coherence_band_data != NULL )
    1078             :                     {
    1079        8214 :                         mvc2c( hQMetaData->q_direction[1].coherence_band_data[d].spread_coherence, hQMetaData->q_direction[1].coherence_band_data[b].spread_coherence, nblocks ); /*Q0*/
    1080             :                     }
    1081        8214 :                     d = sub( d, 1 );
    1082             :                 }
    1083             :                 ELSE
    1084             :                 {
    1085       12232 :                     set32_fx( hQMetaData->q_direction[1].band_data[b].azimuth_fx, 0, nblocks );
    1086       12232 :                     set32_fx( hQMetaData->q_direction[1].band_data[b].elevation_fx, 0, nblocks );
    1087       12232 :                     set32_fx( hQMetaData->q_direction[1].band_data[b].energy_ratio_fx, 0, nblocks );
    1088       12232 :                     set64_fx( W_nrg_ratio[1][b], 0, nblocks );
    1089             : 
    1090       12232 :                     IF( hQMetaData->q_direction[1].coherence_band_data != NULL )
    1091             :                     {
    1092       12232 :                         set_c( (Word8 *) hQMetaData->q_direction[1].coherence_band_data[b].spread_coherence, 0, nblocks );
    1093             :                     }
    1094             :                 }
    1095             :             }
    1096             :         }
    1097             : 
    1098             :         /* Scale energy ratios that sum to over one */
    1099       30810 :         FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
    1100             :         {
    1101      137756 :             FOR( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ )
    1102             :             {
    1103             :                 Word32 ratioSum;
    1104      108190 :                 ratioSum = W_round64_L( W_add( W_nrg_ratio[0][b][m], W_nrg_ratio[1][b][m] ) ); /*Q30*/
    1105      108190 :                 IF( GT_32( ratioSum, ONE_IN_Q30 ) )
    1106             :                 {
    1107           0 :                     W_nrg_ratio[0][b][m] = W_shl( (Word64) ( W_nrg_ratio[0][b][m] / ratioSum ), 30 ); /*Q62*/
    1108           0 :                     move64();
    1109           0 :                     W_nrg_ratio[1][b][m] = W_shl( (Word64) ( W_nrg_ratio[1][b][m] / ratioSum ), 30 ); /*Q62*/
    1110           0 :                     move64();
    1111             :                 }
    1112             :             }
    1113             :         }
    1114             :     }
    1115             : 
    1116       55735 :     FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
    1117             :     {
    1118      257396 :         FOR( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ )
    1119             :         {
    1120      203902 :             hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[m] = W_round64_L( W_nrg_ratio[0][b][m] ); /*Q30*/
    1121      203902 :             move32();
    1122             :         }
    1123             :     }
    1124        2241 :     IF( EQ_32( hQMetaData->no_directions, 2 ) )
    1125             :     {
    1126       30810 :         FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
    1127             :         {
    1128      137756 :             FOR( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ )
    1129             :             {
    1130      108190 :                 hQMetaData->q_direction[1].band_data[b].energy_ratio_fx[m] = W_round64_L( W_nrg_ratio[1][b][m] ); /*Q30*/
    1131      108190 :                 move32();
    1132             :             }
    1133             :         }
    1134             :     }
    1135             :     /* Store status information for renderer use */
    1136        2241 :     hQMetaData->ec_flag = 0;
    1137        2241 :     move16();
    1138        2241 :     hQMetaData->dir_comp_ratio_fx = MAX_WORD16; /*Q15*/
    1139        2241 :     move16();
    1140             : 
    1141             : 
    1142        2241 :     hQMetaData->q_direction[0].cfg.nbands = sf_nbands0; /*Q0*/
    1143        2241 :     move16();
    1144        2241 :     IF( EQ_32( hQMetaData->no_directions, 2 ) )
    1145             :     {
    1146        1244 :         hQMetaData->q_direction[1].cfg.nbands = sf_nbands1; /*Q0*/
    1147        1244 :         move16();
    1148             :     }
    1149             : 
    1150        2241 :     return sub( start_index_0, *index );
    1151             : }
    1152             : 
    1153             : 
    1154             : /*-----------------------------------------------------------------------*
    1155             :  * ivas_qmetadata_dec_sid_decode()
    1156             :  *
    1157             :  * Main function for decoding SID for Spatial Metadata
    1158             :  *-----------------------------------------------------------------------*/
    1159             : 
    1160             : /*! r: number of bits written */
    1161         762 : Word16 ivas_qmetadata_dec_sid_decode(
    1162             :     IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle                    */
    1163             :     UWord16 *bitstream,               /* i  : bitstream                            Q0*/
    1164             :     Word16 *index,                    /* i/o: bitstream position                   Q0*/
    1165             :     const Word16 nchan_transport,     /* i  : number of transport channels         Q0*/
    1166             :     Word16 *element_mode,             /* o  : element mode                         Q0*/
    1167             :     const Word16 ivas_format          /* i  : IVAS format                          Q0*/
    1168             : )
    1169             : {
    1170             :     Word16 b, m, i;
    1171             :     UWord16 value;
    1172             :     UWord16 diffuseness_index[DIRAC_MAX_NBANDS];
    1173             :     Word16 nbands, nblocks, start_band;
    1174             :     IVAS_QDIRECTION *q_direction;
    1175             :     Word16 start_index;
    1176             :     Word32 avg_elevation_fx, avg_azimuth_fx;
    1177             :     Word32 avg_direction_vector_fx[3];
    1178             :     Word32 direction_vector_fx[3];
    1179             :     Word16 metadata_sid_bits; /* bits allocated to SID for metadata */
    1180             :     Word16 bits_delta, bits_dir;
    1181             : 
    1182         762 :     IF( EQ_16( ivas_format, SBA_FORMAT ) )
    1183             :     {
    1184         557 :         metadata_sid_bits = (Word16) ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - ( SPAR_DTX_BANDS * SPAR_SID_BITS_TAR_PER_BAND ) - 2 - SID_FORMAT_NBITS; /* -1 for inactive mode header bit*/
    1185         557 :         move16();
    1186             :     }
    1187             :     ELSE
    1188             :     {
    1189         205 :         metadata_sid_bits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS;
    1190         205 :         move16();
    1191             :     }
    1192             : 
    1193         762 :     start_index = *index;
    1194         762 :     move16();
    1195             : 
    1196             :     /* read MASA SID descriptor */
    1197         762 :     test();
    1198         762 :     IF( EQ_16( ivas_format, MASA_FORMAT ) && EQ_16( nchan_transport, 2 ) )
    1199             :     {
    1200          74 :         b = bitstream[( *index )--]; /*Q0*/
    1201          74 :         move16();
    1202          74 :         IF( b )
    1203             :         {
    1204           0 :             *element_mode = IVAS_CPE_MDCT;
    1205           0 :             move16();
    1206             :         }
    1207             :         ELSE
    1208             :         {
    1209          74 :             *element_mode = IVAS_CPE_DFT;
    1210          74 :             move16();
    1211             :         }
    1212             :     }
    1213             : 
    1214             :     /* Fix configuration for SID */
    1215         762 :     q_direction = &hQMetaData->q_direction[0]; /* only 1 direction */
    1216         762 :     IF( EQ_16( ivas_format, SBA_FORMAT ) )
    1217             :     {
    1218         557 :         nbands = DIRAC_DTX_BANDS; /* only 2 bands transmitted */
    1219         557 :         move16();
    1220             :     }
    1221             :     ELSE
    1222             :     {
    1223         205 :         nbands = 5; /* only 5 bands transmitted */
    1224         205 :         move16();
    1225             :     }
    1226             : 
    1227         762 :     nblocks = q_direction->cfg.nblocks; /* only 1 block transmitted but up to 4 blocks re-generated Q0*/
    1228         762 :     move16();
    1229         762 :     start_band = 0; /* start from band 0 */
    1230         762 :     move16();
    1231             : 
    1232             :     /* Read 2D signaling*/
    1233         762 :     IF( NE_16( ivas_format, SBA_FORMAT ) )
    1234             :     {
    1235         205 :         q_direction->not_in_2D = bitstream[( *index )--]; /*Q0*/
    1236         205 :         move16();
    1237             :     }
    1238             :     ELSE
    1239             :     {
    1240         557 :         q_direction->not_in_2D = 1;
    1241         557 :         move16();
    1242             :     }
    1243             : 
    1244         762 :     bits_dir = 0;
    1245         762 :     move16();
    1246         762 :     IF( NE_16( ivas_format, SBA_FORMAT ) )
    1247             :     {
    1248             :         /* Decode diffuseness*/
    1249        1230 :         FOR( b = start_band; b < nbands; b++ )
    1250             :         {
    1251        1025 :             diffuseness_index[b] = (UWord16) L_add( ivas_qmetadata_DecodeQuasiUniform( bitstream, index, sub( DIRAC_DIFFUSE_LEVELS, 4 ) ), 4 ); /*Q0*/
    1252        1025 :             move16();
    1253        1025 :             q_direction->band_data[b].energy_ratio_index[0] = diffuseness_index[b]; /*Q0*/
    1254        1025 :             move16();
    1255        1025 :             q_direction->band_data[b].bits_sph_idx[0] = bits_direction_masa[diffuseness_index[b]]; /*Q0*/
    1256        1025 :             move16();
    1257        1025 :             bits_dir = extract_l( L_add( bits_dir, q_direction->band_data[b].bits_sph_idx[0] ) );                            /*Q0*/
    1258        1025 :             q_direction->band_data[b].azimuth_m_alphabet[0] = no_phi_masa[q_direction->band_data[b].bits_sph_idx[0] - 1][0]; /*Q0*/
    1259        1025 :             move16();
    1260             :         }
    1261             : 
    1262         205 :         bits_delta = sub( sub( metadata_sid_bits, sub( start_index, *index ) ), bits_dir ); /* bit_diff is already read */
    1263             : 
    1264         205 :         IF( bits_delta > 0 )
    1265             :         {
    1266         978 :             WHILE( bits_delta > 0 )
    1267             :             {
    1268        4206 :                 FOR( b = start_band; b < nbands && ( bits_delta > 0 ); b++ )
    1269             :                 {
    1270        3433 :                     IF( LT_32( q_direction->band_data[b].bits_sph_idx[0], 11 ) )
    1271             :                     {
    1272        3433 :                         bits_delta = sub( bits_delta, 1 );
    1273        3433 :                         q_direction->band_data[b].bits_sph_idx[0] = add( q_direction->band_data[b].bits_sph_idx[0], 1 );
    1274        3433 :                         move16();
    1275             :                     }
    1276             :                 }
    1277             :             }
    1278             : 
    1279         205 :             IF( q_direction->not_in_2D == 0 )
    1280             :             {
    1281           0 :                 FOR( b = start_band; b < nbands; b++ )
    1282             :                 {
    1283           0 :                     q_direction->band_data[b].azimuth_m_alphabet[0] = shl( 1, extract_l( L_min( 8, q_direction->band_data[b].bits_sph_idx[0] ) ) );
    1284           0 :                     move16();
    1285             :                 }
    1286             :             }
    1287             :         }
    1288             :         ELSE
    1289             :         {
    1290           0 :             WHILE( bits_delta < 0 )
    1291             :             {
    1292           0 :                 FOR( b = nbands - 1; b >= start_band && ( bits_delta < 0 ); b-- )
    1293             :                 {
    1294           0 :                     IF( GE_32( q_direction->band_data[b].bits_sph_idx[0], 4 ) )
    1295             :                     {
    1296           0 :                         bits_delta = add( bits_delta, 1 );
    1297           0 :                         q_direction->band_data[b].bits_sph_idx[0] = sub( q_direction->band_data[b].bits_sph_idx[0], 1 );
    1298           0 :                         move16();
    1299             :                     }
    1300             :                 }
    1301             : 
    1302           0 :                 IF( q_direction->not_in_2D == 0 )
    1303             :                 {
    1304           0 :                     FOR( b = start_band; b < nbands; b++ )
    1305             :                     {
    1306           0 :                         q_direction->band_data[b].azimuth_m_alphabet[0] = shl( 1, extract_l( L_min( 8, q_direction->band_data[b].bits_sph_idx[0] ) ) );
    1307           0 :                         move16();
    1308             :                     }
    1309             :                 }
    1310             :             }
    1311             :         }
    1312             :     }
    1313             :     ELSE
    1314             :     {
    1315             :         /* Decode diffuseness*/
    1316        1671 :         FOR( b = start_band; b < nbands; b++ )
    1317             :         {
    1318        1114 :             diffuseness_index[b] = (UWord16) L_add( ivas_qmetadata_DecodeQuasiUniform( bitstream, index, DIRAC_DIFFUSE_LEVELS - 4 ), 4 ); /*Q0*/
    1319        1114 :             move16();
    1320        1114 :             q_direction->band_data[b].energy_ratio_index[0] = diffuseness_index[b];
    1321        1114 :             move16();
    1322        1114 :             q_direction->band_data[b].bits_sph_idx[0] = bits_direction_masa[diffuseness_index[b]];
    1323        1114 :             move16();
    1324        1114 :             q_direction->band_data[b].azimuth_m_alphabet[0] = no_phi_masa[q_direction->band_data[b].bits_sph_idx[0] - 1][0];
    1325        1114 :             move16();
    1326             :         }
    1327             :     }
    1328             : 
    1329        2901 :     FOR( b = start_band; b < nbands; b++ )
    1330             :     {
    1331        2139 :         q_direction->band_data[b].energy_ratio_fx[0] = L_sub( ONE_IN_Q30, diffuseness_reconstructions_fx[diffuseness_index[b]] ); /*Q30*/
    1332        2139 :         move32();
    1333       10563 :         FOR( i = 0; i < nblocks; i++ )
    1334             :         {
    1335        8424 :             q_direction->band_data[b].energy_ratio_fx[i] = q_direction->band_data[b].energy_ratio_fx[0]; /*Q30*/
    1336        8424 :             move32();
    1337             :         }
    1338             :     }
    1339             : 
    1340             :     /* Decoder DOAs*/
    1341         762 :     IF( q_direction->not_in_2D > 0 )
    1342             :     {
    1343        2901 :         FOR( b = start_band; b < nbands; b++ )
    1344             :         {
    1345        2139 :             value = 0;
    1346        2139 :             move16();
    1347       14241 :             FOR( i = 0; i < q_direction->band_data[b].bits_sph_idx[0]; i++ )
    1348             :             {
    1349       12102 :                 value = (UWord16) L_add( L_shl( value, 1 ), bitstream[( *index )--] );
    1350             :             }
    1351       10563 :             FOR( i = 0; i < nblocks; i++ )
    1352             :             {
    1353        8424 :                 q_direction->band_data[b].spherical_index[i] = value;
    1354        8424 :                 move16();
    1355             :             }
    1356             : 
    1357        2139 :             deindex_spherical_component_fx( q_direction->band_data[b].spherical_index[0], &avg_azimuth_fx, &avg_elevation_fx, &q_direction->band_data[b].azimuth_index[0], &q_direction->band_data[b].elevation_index[0], q_direction->band_data[b].bits_sph_idx[0], q_direction->cfg.mc_ls_setup );
    1358             : 
    1359        2139 :             ivas_qmetadata_azimuth_elevation_to_direction_vector_fx( avg_azimuth_fx, avg_elevation_fx, avg_direction_vector_fx );
    1360        2139 :             ivas_qmetadata_azimuth_elevation_to_direction_vector_fx( q_direction->band_data[b].azimuth_fx[nblocks - 1], q_direction->band_data[b].elevation_fx[nblocks - 1], direction_vector_fx );
    1361             : 
    1362        2139 :             v_shr_32( direction_vector_fx, direction_vector_fx, 3, 5 );         /*Q25*/
    1363        2139 :             v_shr_32( avg_direction_vector_fx, avg_direction_vector_fx, 3, 5 ); /*Q25*/
    1364        8424 :             FOR( m = 0; m < nblocks - 1; m++ )
    1365             :             {
    1366        6285 :                 v_add_32( direction_vector_fx, avg_direction_vector_fx, direction_vector_fx, 3 ); /*Q25*/
    1367        6285 :                 ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( direction_vector_fx, sub( 30, 5 ), &q_direction->band_data[b].azimuth_fx[m], &q_direction->band_data[b].elevation_fx[m] );
    1368             :             }
    1369        2139 :             ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( avg_direction_vector_fx, sub( 30, 5 ), &q_direction->band_data[b].azimuth_fx[nblocks - 1], &q_direction->band_data[b].elevation_fx[nblocks - 1] );
    1370             :         }
    1371             :     }
    1372             :     ELSE
    1373             :     {
    1374           0 :         FOR( b = start_band; b < nbands; b++ )
    1375             :         {
    1376             :             Word32 temp_result;
    1377           0 :             IF( EQ_16( ivas_format, SBA_FORMAT ) )
    1378             :             {
    1379           0 :                 q_direction->band_data[b].azimuth_m_alphabet[0] = shl( 1, extract_l( L_min( 5, q_direction->band_data[b].bits_sph_idx[0] ) ) );
    1380           0 :                 move16();
    1381             :             }
    1382           0 :             q_direction->band_data[b].azimuth_index[0] = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, q_direction->band_data[b].azimuth_m_alphabet[0] ); /*Q0*/
    1383           0 :             move16();
    1384           0 :             q_direction->band_data[b].azimuth_index[0] = add( ivas_qmetadata_dereorder_generic_fx( q_direction->band_data[b].azimuth_index[0] ), shr( q_direction->band_data[b].azimuth_m_alphabet[0], 1 ) ); /*Q0*/
    1385           0 :             move16();
    1386             : 
    1387           0 :             temp_result = div_s( ( shl( q_direction->band_data[b].azimuth_index[0], 6 ) ), ( shl( q_direction->band_data[b].azimuth_m_alphabet[0], 6 ) ) ); /*Q15*/
    1388           0 :             temp_result = Mpy_32_16_1( DEGREE_360_Q_22, (Word16) temp_result );                                                                             /*Q22*/
    1389           0 :             avg_azimuth_fx = L_sub( temp_result, DEGREE_180_Q_22 );                                                                                         /*Q22*/
    1390             : 
    1391           0 :             avg_elevation_fx = 0;
    1392           0 :             move32();
    1393             : 
    1394           0 :             ivas_qmetadata_azimuth_elevation_to_direction_vector_fx( avg_azimuth_fx, avg_elevation_fx, avg_direction_vector_fx );
    1395           0 :             ivas_qmetadata_azimuth_elevation_to_direction_vector_fx( q_direction->band_data[b].azimuth_fx[nblocks - 1], q_direction->band_data[b].elevation_fx[nblocks - 1], direction_vector_fx );
    1396             : 
    1397           0 :             v_shr_32( direction_vector_fx, direction_vector_fx, 3, 5 );         /*Q25*/
    1398           0 :             v_shr_32( avg_direction_vector_fx, avg_direction_vector_fx, 3, 5 ); /*Q25*/
    1399           0 :             FOR( m = 0; m < nblocks - 1; m++ )
    1400             :             {
    1401           0 :                 v_add_32( direction_vector_fx, avg_direction_vector_fx, direction_vector_fx, 3 ); /*Q25*/
    1402           0 :                 ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( direction_vector_fx, 30 - 5, &q_direction->band_data[b].azimuth_fx[m], &q_direction->band_data[b].elevation_fx[m] );
    1403             :             }
    1404           0 :             ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( avg_direction_vector_fx, 30 - 5, &q_direction->band_data[b].azimuth_fx[nblocks - 1], &q_direction->band_data[b].elevation_fx[nblocks - 1] );
    1405             : 
    1406           0 :             FOR( i = 0; i < nblocks; i++ )
    1407             :             {
    1408           0 :                 q_direction->band_data[b].spherical_index[i] = q_direction->band_data[b].azimuth_index[0];
    1409           0 :                 move16();
    1410             :             }
    1411             :         }
    1412             :     }
    1413             : 
    1414             : 
    1415             :     /*Read filling bits*/
    1416        3323 :     WHILE( LT_16( sub( start_index, *index ), metadata_sid_bits ) )
    1417             :     {
    1418        2561 :         b = bitstream[( *index )--];
    1419        2561 :         move16();
    1420             :     }
    1421             : 
    1422         762 :     return sub( start_index, *index );
    1423             : }
    1424             : 
    1425             : /*-----------------------------------------------------------------------*
    1426             :  * Local function definitions for diffuseness/energy ratios
    1427             :  *-----------------------------------------------------------------------*/
    1428             : 
    1429      146520 : static Word16 ivas_diffuseness_huff_ec_decode_fx(
    1430             :     const UWord16 *bitstream, /*Q0*/
    1431             :     Word16 *index,            /*Q0*/
    1432             :     Word16 av /*Q0*/ )
    1433             : {
    1434             :     Word16 val;
    1435             : 
    1436      146520 :     val = 0;
    1437      146520 :     move16();
    1438      323380 :     WHILE( LE_16( val, DIFF_EC_HUFF_GR0_LIMIT ) )
    1439             :     {
    1440      319101 :         IF( EQ_16( bitstream[( *index )--], 1 ) )
    1441             :         {
    1442      176860 :             val = add( val, 1 );
    1443             :         }
    1444             :         ELSE
    1445             :         {
    1446      142241 :             BREAK;
    1447             :         }
    1448             :     }
    1449             : 
    1450      146520 :     IF( EQ_16( val, DIFF_EC_HUFF_GR0_LIMIT + 1 ) )
    1451             :     {
    1452        4279 :         val = add( val, shl( bitstream[( *index )--], 1 ) );
    1453        4279 :         val = add( val, bitstream[( *index )--] );
    1454             :     }
    1455             : 
    1456      146520 :     IF( val % 2 == 0 )
    1457             :     {
    1458       80635 :         return add( negate( shr( val, 1 ) ), av );
    1459             :     }
    1460             :     ELSE
    1461             :     {
    1462       65885 :         return add( shr( add( val, 1 ), 1 ), av );
    1463             :     }
    1464             : }
    1465             : 
    1466             : /*-------------------------------------------------------------------*
    1467             :  * ivas_qmetadata_entropy_decode_diffuseness()
    1468             :  *
    1469             :  *
    1470             :  *-------------------------------------------------------------------*/
    1471      184762 : static Word16 ivas_qmetadata_entropy_decode_diffuseness(
    1472             :     UWord16 *bitstream, /* i  : bitstream               Q0*/
    1473             :     Word16 *index,      /*Q0*/
    1474             :     IVAS_QDIRECTION *q_direction,
    1475             :     UWord16 *diffuseness_index_max_ec_frame /*Q0*/ )
    1476             : {
    1477             :     Word16 b;
    1478             :     UWord16 dif_min;
    1479             :     Word16 index_start;
    1480             :     Word16 nbands;
    1481             :     Word16 start_band;
    1482             : 
    1483      184762 :     index_start = *index;
    1484      184762 :     move16();
    1485      184762 :     nbands = q_direction->cfg.nbands;
    1486      184762 :     move16();
    1487      184762 :     start_band = q_direction->cfg.start_band;
    1488      184762 :     move16();
    1489             : 
    1490             :     /* diffuseness decoding */
    1491             :     /* Handle one band as special case*/
    1492      184762 :     IF( EQ_16( nbands, 1 ) )
    1493             :     {
    1494        3777 :         q_direction->band_data[0].energy_ratio_index[0] = 0;
    1495        3777 :         move16();
    1496       15108 :         FOR( b = 0; b < MASA_BITS_ER; b++ )
    1497             :         {
    1498       11331 :             q_direction->band_data[0].energy_ratio_index[0] = (UWord16) L_add( L_shl( q_direction->band_data[0].energy_ratio_index[0], 1 ), bitstream[( *index )--] ); /*Q0*/
    1499       11331 :             move16();
    1500             :         }
    1501        3777 :         *diffuseness_index_max_ec_frame = 5;
    1502        3777 :         move16();
    1503             : 
    1504        3777 :         return MASA_BITS_ER;
    1505             :     }
    1506             : 
    1507      180985 :     IF( bitstream[( *index )--] == 0 ) /* dif_use_raw_coding */
    1508             :     {
    1509             :         /* Decode with similarity strategy with low band count. On higher band counts, decode with Huffman-coding strategy. */
    1510       93491 :         IF( LT_16( nbands, DIFF_EC_HUFF_BAND_LIMIT ) )
    1511             :         {
    1512       81864 :             IF( bitstream[( *index )--] ) /* dif_have_unique_value */
    1513             :             {
    1514       46489 :                 dif_min = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, DIRAC_DIFFUSE_LEVELS ); /* dif_unique_value Q0*/
    1515             : 
    1516      183874 :                 FOR( b = start_band; b < nbands; b++ )
    1517             :                 {
    1518      137385 :                     q_direction->band_data[b].energy_ratio_index[0] = dif_min; /*Q0*/
    1519      137385 :                     move16();
    1520             :                 }
    1521             :             }
    1522             :             ELSE /* all diffuseness values are dif_min_value or dif_min_value + 1 */
    1523             :             {
    1524       35375 :                 dif_min = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, DIRAC_DIFFUSE_LEVELS - 1 ); /* dif_min_value Q0*/
    1525             : 
    1526      154972 :                 FOR( b = start_band; b < nbands; b++ )
    1527             :                 {
    1528      119597 :                     q_direction->band_data[b].energy_ratio_index[0] = (UWord16) L_add( dif_min, bitstream[( *index )--] ); /* dif_bit_offset_values Q0*/
    1529      119597 :                     move16();
    1530             :                 }
    1531             :             }
    1532             :         }
    1533             :         ELSE
    1534             :         {
    1535             :             Word16 av;
    1536             : 
    1537             :             /* read average on 3 bits*/
    1538       11627 :             av = 0;
    1539       11627 :             move16();
    1540       46508 :             FOR( b = 0; b < MASA_BITS_ER; b++ )
    1541             :             {
    1542       34881 :                 av = add( av, i_mult( (Word16) bitstream[( *index )--], shl( 1, sub( sub( MASA_BITS_ER, 1 ), b ) ) ) ); /*Q0*/
    1543             :             }
    1544             : 
    1545       11627 :             dif_min = DIRAC_DIFFUSE_LEVELS;
    1546       11627 :             move16();
    1547             :             /* read average removed data (average is added inside)*/
    1548      158147 :             FOR( b = start_band; b < nbands; b++ )
    1549             :             {
    1550      146520 :                 q_direction->band_data[b].energy_ratio_index[0] = ivas_diffuseness_huff_ec_decode_fx( bitstream, index, av ); /*Q0*/
    1551      146520 :                 move16();
    1552      146520 :                 dif_min = (UWord16) L_min( dif_min, q_direction->band_data[b].energy_ratio_index[0] );
    1553      146520 :                 move16();
    1554             :             }
    1555             :         }
    1556             :     }
    1557             :     ELSE /* different values for diffuseness */
    1558             :     {
    1559       87494 :         dif_min = DIRAC_DIFFUSE_LEVELS;
    1560       87494 :         move16();
    1561             : 
    1562      514094 :         FOR( b = start_band; b < nbands; b++ )
    1563             :         {
    1564      426600 :             q_direction->band_data[b].energy_ratio_index[0] = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, DIRAC_DIFFUSE_LEVELS ); /*Q0*/
    1565      426600 :             move16();
    1566      426600 :             dif_min = (UWord16) L_min( dif_min, q_direction->band_data[b].energy_ratio_index[0] );
    1567      426600 :             move16();
    1568             :         }
    1569             :     }
    1570             : 
    1571      180985 :     *diffuseness_index_max_ec_frame = 5;
    1572      180985 :     move16();
    1573             :     /* adaptively select the diffuseness_index_max_ec threshold */
    1574      180985 :     if ( GT_32( dif_min, 5 ) )
    1575             :     {
    1576       64385 :         *diffuseness_index_max_ec_frame = (UWord16) DIRAC_DIFFUSE_LEVELS - 1;
    1577       64385 :         move16();
    1578             :     }
    1579             : 
    1580      180985 :     return sub( index_start, *index );
    1581             : }
    1582             : 
    1583             : /*-------------------------------------------------------------------*
    1584             :  * ivas_qmetadata_entropy_decode_diffuseness_hr_512()
    1585             :  *
    1586             :  *
    1587             :  *-------------------------------------------------------------------*/
    1588             : 
    1589        3485 : static Word16 ivas_qmetadata_entropy_decode_diffuseness_hr_512(
    1590             :     UWord16 *bitstream, /* i  : bitstream               Q0*/
    1591             :     Word16 *index,      /*Q0*/
    1592             :     IVAS_QDIRECTION *q_direction )
    1593             : {
    1594             :     Word16 b, k;
    1595             : 
    1596             :     Word16 index_start;
    1597             :     Word16 nbands, nblocks;
    1598             :     Word16 start_band;
    1599             : 
    1600        3485 :     index_start = *index;
    1601        3485 :     move16();
    1602        3485 :     nbands = q_direction->cfg.nbands;
    1603        3485 :     move16();
    1604        3485 :     nblocks = q_direction->cfg.nblocks;
    1605        3485 :     move16();
    1606        3485 :     start_band = q_direction->cfg.start_band;
    1607        3485 :     move16();
    1608             : 
    1609             :     /* diffuseness decoding */
    1610             :     /* Handle one band as special case*/
    1611        3485 :     IF( EQ_16( nbands, 1 ) )
    1612             :     {
    1613           0 :         q_direction->band_data[0].energy_ratio_index[0] = 0;
    1614           0 :         move16();
    1615           0 :         FOR( b = 0; b < MASA_BITS_ER_HR; b++ )
    1616             :         {
    1617           0 :             q_direction->band_data[0].energy_ratio_index[0] = (UWord16) L_add( (UWord16) L_shl( q_direction->band_data[0].energy_ratio_index[0], 1 ), bitstream[( *index )--] ); /*Q0*/
    1618           0 :             move16();
    1619             :         }
    1620             : 
    1621           0 :         return MASA_BITS_ER_HR;
    1622             :     }
    1623             : 
    1624       74313 :     FOR( b = start_band; b < nbands; b++ )
    1625             :     {
    1626      338810 :         FOR( k = 0; k < nblocks; k++ )
    1627             :         {
    1628      267982 :             q_direction->band_data[b].energy_ratio_index[k] = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, HR_MASA_ER_LEVELS ); /*Q0*/
    1629      267982 :             move16();
    1630             :         }
    1631             :     }
    1632             : 
    1633        3485 :     return sub( index_start, *index );
    1634             : }
    1635             : 
    1636             : 
    1637             : /*-------------------------------------------------------------------*
    1638             :  * ivas_qmetadata_entropy_decode_df_ratio()
    1639             :  *
    1640             :  *
    1641             :  *-------------------------------------------------------------------*/
    1642       20067 : static Word16 ivas_qmetadata_entropy_decode_df_ratio(
    1643             :     UWord16 *bitstream, /*Q0*/
    1644             :     Word16 *index,      /*Q0*/
    1645             :     IVAS_QDIRECTION *q_direction,
    1646             :     Word16 *dfRatio_bits /*Q0*/ )
    1647             : {
    1648             :     Word16 b;
    1649             :     Word16 bits_raw;
    1650             :     Word16 max_dfRatio_bits;
    1651             :     UWord16 ratio_min;
    1652             :     Word16 index_start;
    1653             :     Word16 nbands;
    1654             :     Word16 start_band;
    1655             :     Word16 ec_mode;
    1656             :     Word16 dec_mode;
    1657             :     Word16 max_alphabet_size;
    1658             : 
    1659       20067 :     index_start = *index;
    1660       20067 :     move16();
    1661       20067 :     nbands = q_direction->cfg.nbands;
    1662       20067 :     move16();
    1663       20067 :     start_band = q_direction->cfg.start_band;
    1664       20067 :     move16();
    1665             : 
    1666             :     /* Handle one band as special case*/
    1667       20067 :     IF( EQ_16( nbands, 1 ) )
    1668             :     {
    1669        1371 :         q_direction->band_data[0].energy_ratio_index[0] = 0;
    1670        1371 :         move16();
    1671        4245 :         FOR( b = 0; b < dfRatio_bits[0]; b++ )
    1672             :         {
    1673             :             // q_direction->band_data[0].energy_ratio_index[0] = ( q_direction->band_data[0].energy_ratio_index[0] << 1 ) + bitstream[( *index )--];
    1674        2874 :             q_direction->band_data[0].energy_ratio_index[0] = (UWord16) L_add( L_shl( q_direction->band_data[0].energy_ratio_index[0], 1 ), bitstream[( *index )--] ); /*Q0*/
    1675        2874 :             move16();
    1676             :         }
    1677        1371 :         return dfRatio_bits[0];
    1678             :     }
    1679             : 
    1680             :     /* Calculate raw coding bits and decide what modes are possible */
    1681       18696 :     bits_raw = 0;
    1682       18696 :     move16();
    1683       18696 :     max_dfRatio_bits = 0;
    1684       18696 :     move16();
    1685      222141 :     FOR( b = start_band; b < nbands; b++ )
    1686             :     {
    1687             :         // bits_raw += dfRatio_bits[b];
    1688      203445 :         bits_raw = add( bits_raw, dfRatio_bits[b] );
    1689      203445 :         max_dfRatio_bits = s_max( max_dfRatio_bits, dfRatio_bits[b] );
    1690             :     }
    1691             : 
    1692             :     /* Decide what modes are possible */
    1693       18696 :     IF( GE_16( bits_raw, add( add( max_dfRatio_bits, 2 ), nbands ) ) )
    1694             :     {
    1695       12284 :         ec_mode = 2;
    1696       12284 :         move16();
    1697             :     }
    1698        6412 :     ELSE IF( GE_16( bits_raw, add( max_dfRatio_bits, 1 ) ) )
    1699             :     {
    1700        6412 :         ec_mode = 1;
    1701        6412 :         move16();
    1702             :     }
    1703             :     ELSE
    1704             :     {
    1705           0 :         ec_mode = 0;
    1706           0 :         move16();
    1707             :     }
    1708       18696 :     max_alphabet_size = shl( 1, max_dfRatio_bits ); /* 1 << max_dfRatio_bits */
    1709             : 
    1710       18696 :     dec_mode = 2; /* Default to raw decoding */
    1711       18696 :     move16();
    1712       18696 :     IF( EQ_16( ec_mode, 1 ) )
    1713             :     {
    1714        6412 :         if ( bitstream[( *index )--] == 0 )
    1715             :         {
    1716         253 :             dec_mode = 1; /* Switch to one value EC coding */
    1717         253 :             move16();
    1718             :         }
    1719             :     }
    1720       12284 :     ELSE IF( EQ_16( ec_mode, 2 ) )
    1721             :     {
    1722       12284 :         IF( bitstream[( *index )--] == 0 )
    1723             :         {
    1724        1451 :             IF( bitstream[( *index )--] == 0 )
    1725             :             {
    1726          99 :                 dec_mode = 1; /* Switch to one value EC coding */
    1727          99 :                 move16();
    1728             :             }
    1729             :             ELSE
    1730             :             {
    1731        1352 :                 dec_mode = 0; /* Use one-bit diff bandwise mode */
    1732        1352 :                 move16();
    1733             :             }
    1734             :         }
    1735             :     }
    1736             : 
    1737       18696 :     IF( EQ_16( dec_mode, 2 ) ) /* Raw decoding */
    1738             :     {
    1739      205792 :         FOR( b = start_band; b < nbands; b++ )
    1740             :         {
    1741      188800 :             q_direction->band_data[b].energy_ratio_index[0] = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, (UWord16) L_shl( 1, dfRatio_bits[b] ) ); /*Q0*/
    1742      188800 :             move16();
    1743             :         }
    1744             :     }
    1745        1704 :     ELSE IF( EQ_16( dec_mode, 1 ) ) /* One value decoding */
    1746             :     {
    1747         352 :         ratio_min = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, max_alphabet_size ); /* dif_unique_value Q0*/
    1748             : 
    1749        1931 :         FOR( b = start_band; b < nbands; b++ )
    1750             :         {
    1751        1579 :             q_direction->band_data[b].energy_ratio_index[0] = ratio_min; /*Q0*/
    1752        1579 :             move16();
    1753             :         }
    1754             :     }
    1755             :     ELSE /* Bandwise 1-bit diff decoding */
    1756             :     {
    1757        1352 :         ratio_min = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, max_alphabet_size - 1 ); /* dif_min_value Q0*/
    1758             : 
    1759       14418 :         FOR( b = start_band; b < nbands; b++ )
    1760             :         {
    1761       13066 :             q_direction->band_data[b].energy_ratio_index[0] = (UWord16) L_add( ratio_min, bitstream[( *index )--] ); /* dif_bit_offset_values Q0*/
    1762       13066 :             move16();
    1763             :         }
    1764             :     }
    1765             : 
    1766       18696 :     return sub( index_start, *index );
    1767             : }
    1768             : 
    1769             : 
    1770             : /*-----------------------------------------------------------------------*
    1771             :  * Local functions (EC1)
    1772             :  *-----------------------------------------------------------------------*/
    1773             : 
    1774             : /*-------------------------------------------------------------------------
    1775             :  * ivas_qmetadata_entropy_decode_dir_fx()
    1776             :  *
    1777             :  * Main function for entropy decoding of the directions
    1778             :  *------------------------------------------------------------------------*/
    1779      106917 : static Word16 ivas_qmetadata_entropy_decode_dir_fx(
    1780             :     IVAS_QDIRECTION *q_direction,                 /* i/o: quantized direction structure   */
    1781             :     UWord16 *bitstream,                           /* i  : bitstream                       Q0*/
    1782             :     Word16 *index,                                /*Q0*/
    1783             :     const UWord16 diffuseness_index_max_ec_frame, /*Q0*/
    1784             :     const Word16 nbands,                          /*Q0*/
    1785             :     const Word16 start_band,                      /*Q0*/
    1786             :     const Word16 hrmasa_flag                      /* i  : flag indicating high-rate MASA MD coding Q0*/
    1787             : )
    1788             : {
    1789             :     Word16 b, m;
    1790             :     Word16 diff_idx;
    1791             :     Word16 diff_idx_min;
    1792             :     Word16 nblocks;
    1793             :     Word16 index_start;
    1794             : 
    1795             :     UWord16 gr_param_elev, gr_param_azith;
    1796             :     Word16 bands_entropic[MASA_MAXIMUM_CODING_SUBBANDS];
    1797             :     Word16 elev_alph[MASA_MAXIMUM_CODING_SUBBANDS];
    1798             :     Word16 azith_alph[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES];
    1799             : 
    1800             :     Word16 avg_elevation_alphabet, avg_azimuth_alphabet;
    1801             :     Word16 avg_elevation_idx, avg_azimuth_index;
    1802             :     Word16 avg_elevation_index_projected, avg_azimuth_index_projected;
    1803             :     Word32 direction_vector_fx[3], avg_direction_vector_fx[3], avg_azimuth_fx, avg_elevation_fx;
    1804             :     Word16 use_adapt_avg, idx;
    1805             : 
    1806      106917 :     index_start = *index;
    1807      106917 :     move16();
    1808      106917 :     nblocks = q_direction->cfg.nblocks;
    1809      106917 :     move16();
    1810             : 
    1811      106917 :     diff_idx_min = DIRAC_DIFFUSE_LEVELS;
    1812      106917 :     move16();
    1813             : 
    1814             :     /*Raw coding for high diffuseness*/
    1815      737613 :     FOR( b = start_band; b < nbands; b++ )
    1816             :     {
    1817      630696 :         IF( hrmasa_flag )
    1818             :         {
    1819           0 :             diff_idx = 0;
    1820           0 :             move16();
    1821             :         }
    1822             :         ELSE
    1823             :         {
    1824      630696 :             diff_idx = q_direction->band_data[b].energy_ratio_index_mod[0]; /*Q0*/
    1825      630696 :             move16();
    1826             :         }
    1827             : 
    1828      630696 :         diff_idx_min = s_min( diff_idx_min, diff_idx );
    1829      630696 :         IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
    1830             :         {
    1831       24206 :             elev_alph[b] = no_theta_masa[( bits_direction_masa[diff_idx] - 3 )]; /*Q0*/
    1832       24206 :             move16();
    1833             :         }
    1834             :         ELSE
    1835             :         {
    1836      606490 :             elev_alph[b] = sub( shl( no_theta_masa[( bits_direction_masa[diff_idx] - 3 )], 1 ), 1 ); /*Q0*/
    1837      606490 :             move16();
    1838             :         }
    1839             : 
    1840      630696 :         IF( GT_32( q_direction->band_data[b].energy_ratio_index_mod[0], diffuseness_index_max_ec_frame ) )
    1841             :         {
    1842      192703 :             bands_entropic[b] = 0;
    1843      192703 :             move16();
    1844             : 
    1845      192703 :             IF( q_direction->not_in_2D > 0 )
    1846             :             {
    1847      171481 :                 decode_fixed_rate_fx( q_direction, bitstream, index, b, nblocks );
    1848             :             }
    1849             :             ELSE
    1850             :             {
    1851             :                 /* in 2D */
    1852       99216 :                 FOR( m = 0; m < nblocks; m++ )
    1853             :                 {
    1854       77994 :                     q_direction->band_data[b].elevation_fx[m] = 0;
    1855       77994 :                     move32();
    1856       77994 :                     q_direction->band_data[b].elevation_index[m] = 0;
    1857       77994 :                     move16();
    1858             : 
    1859       77994 :                     azith_alph[b][m] = no_phi_masa[( bits_direction_masa[diff_idx] - 1 )][0]; /*Q0*/
    1860       77994 :                     move16();
    1861       77994 :                     q_direction->band_data[b].azimuth_index[m] = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, azith_alph[b][m] ); /*Q0*/
    1862       77994 :                     move16();
    1863       77994 :                     q_direction->band_data[b].azimuth_fx[m] = deindex_azimuth_fx( q_direction->band_data[b].azimuth_index[m], q_direction->band_data[b].bits_sph_idx[m], 0, 1, q_direction->cfg.mc_ls_setup ); /*Q22*/
    1864       77994 :                     move32();
    1865             :                 }
    1866             :             }
    1867             :         }
    1868             :         ELSE
    1869             :         {
    1870      437993 :             bands_entropic[b] = 1;
    1871      437993 :             move16();
    1872             :         }
    1873             :     }
    1874             : 
    1875             :     /*EC for the low diffuseness*/
    1876             : 
    1877             :     /*Elevation only if not 2D  */
    1878      106917 :     IF( q_direction->not_in_2D > 0 )
    1879             :     {
    1880       89454 :         IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
    1881             :         {
    1882         863 :             avg_elevation_alphabet = no_theta_masa[( bits_direction_masa[diff_idx_min] - 3 )]; /*Q0*/
    1883         863 :             move16();
    1884         863 :             avg_elevation_idx = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, avg_elevation_alphabet ); /*Q0*/
    1885             :         }
    1886             :         ELSE
    1887             :         {
    1888       88591 :             avg_elevation_alphabet = sub( shl( no_theta_masa[( bits_direction_masa[diff_idx_min] - 3 )], 1 ), 1 ); /*Q0*/
    1889       88591 :             avg_elevation_idx = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, avg_elevation_alphabet );
    1890       88591 :             avg_elevation_idx = add( ivas_qmetadata_dereorder_generic_fx( avg_elevation_idx ), shr( avg_elevation_alphabet, 1 ) ); /*Q0*/
    1891             :         }
    1892             : 
    1893       89454 :         gr_param_elev = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, 4 + 1 );
    1894       89454 :         move16();
    1895       89454 :         IF( EQ_32( gr_param_elev, 4 ) ) /* all the elevation distances are zero */
    1896             :         {
    1897       88369 :             FOR( b = start_band; b < nbands; b++ )
    1898             :             {
    1899       73132 :                 IF( bands_entropic[b] )
    1900             :                 {
    1901             :                     Word16 tmp_index;
    1902       22350 :                     IF( hrmasa_flag )
    1903             :                     {
    1904           0 :                         diff_idx = 0;
    1905           0 :                         move16();
    1906             :                     }
    1907             :                     ELSE
    1908             :                     {
    1909       22350 :                         diff_idx = q_direction->band_data[b].energy_ratio_index_mod[0]; /*Q0*/
    1910       22350 :                         move16();
    1911             :                     }
    1912             : 
    1913       22350 :                     IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
    1914             :                     {
    1915         544 :                         avg_elevation_index_projected = ivas_chan_project_elevation_index_fx( avg_elevation_idx, avg_elevation_alphabet, elev_alph[b] ); /*Q0*/
    1916             :                     }
    1917             :                     ELSE
    1918             :                     {
    1919       21806 :                         avg_elevation_index_projected = ivas_dirac_project_elevation_index_fx( avg_elevation_idx, avg_elevation_alphabet, elev_alph[b] ); /*Q0*/
    1920             : 
    1921             :                         /*reorder elevation indexing*/
    1922       21806 :                         tmp_index = sub( avg_elevation_index_projected, shr( elev_alph[b], 1 ) ); /*Q0*/
    1923       21806 :                         IF( tmp_index < 0 )
    1924             :                         {
    1925        6821 :                             tmp_index = negate( imult1616( tmp_index, 2 ) );
    1926             :                         }
    1927       14985 :                         ELSE IF( tmp_index > 0 )
    1928             :                         {
    1929        2787 :                             tmp_index = sub( imult1616( tmp_index, 2 ), 1 );
    1930             :                         }
    1931       21806 :                         avg_elevation_index_projected = tmp_index;
    1932       21806 :                         move16();
    1933             :                     }
    1934             : 
    1935       96078 :                     FOR( m = 0; m < nblocks; m++ )
    1936             :                     {
    1937       73728 :                         q_direction->band_data[b].elevation_index[m] = avg_elevation_index_projected; /*Q0*/
    1938       73728 :                         move16();
    1939             : 
    1940             :                         /*deduce aplhabet for azimuth*/
    1941       73728 :                         IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
    1942             :                         {
    1943        1963 :                             azith_alph[b][m] = no_phi_masa[( bits_direction_masa[diff_idx] - 1 )][q_direction->band_data[b].elevation_index[m]]; /*Q0*/
    1944        1963 :                             move16();
    1945             :                         }
    1946             :                         ELSE
    1947             :                         {
    1948       71765 :                             azith_alph[b][m] = no_phi_masa[( bits_direction_masa[diff_idx] - 1 )][extract_l( L_shr( L_add( q_direction->band_data[b].elevation_index[m], 1 ), 1 ) )]; /*Q0*/
    1949       71765 :                             move16();
    1950             :                         }
    1951             : 
    1952             :                         /*decode elevation*/
    1953       73728 :                         q_direction->band_data[b].elevation_fx[m] = deindex_elevation_fx( &q_direction->band_data[b].elevation_index[m], q_direction->band_data[b].bits_sph_idx[m], q_direction->cfg.mc_ls_setup ); /*Q22*/
    1954       73728 :                         move32();
    1955             :                     }
    1956             :                 }
    1957             :             }
    1958             :         }
    1959             :         ELSE
    1960             :         {
    1961      544546 :             FOR( b = start_band; b < nbands; b++ )
    1962             :             {
    1963      470329 :                 IF( bands_entropic[b] )
    1964             :                 {
    1965      349630 :                     IF( hrmasa_flag )
    1966             :                     {
    1967           0 :                         diff_idx = 0;
    1968           0 :                         move16();
    1969             :                     }
    1970             :                     ELSE
    1971             :                     {
    1972      349630 :                         diff_idx = q_direction->band_data[b].energy_ratio_index_mod[0]; /*Q0*/
    1973      349630 :                         move16();
    1974             :                     }
    1975             : 
    1976     1664321 :                     FOR( m = 0; m < nblocks; m++ )
    1977             :                     {
    1978             :                         Word16 tmp_index;
    1979     1314691 :                         IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
    1980             :                         {
    1981        7019 :                             avg_elevation_index_projected = ivas_chan_project_elevation_index_fx( avg_elevation_idx, avg_elevation_alphabet, elev_alph[b] ); /*Q0*/
    1982        7019 :                             tmp_index = ivas_qmetadata_DecodeExtendedGR( bitstream, index, sub( shl( elev_alph[b], 1 ), 1 ), gr_param_elev );                /*Q0*/
    1983        7019 :                             IF( s_and( tmp_index, 1 ) )
    1984             :                             {
    1985         717 :                                 tmp_index = add( avg_elevation_index_projected, shr( add( tmp_index, 1 ), 1 ) ); /*Q0*/
    1986             :                             }
    1987             :                             ELSE
    1988             :                             {
    1989        6302 :                                 tmp_index = sub( avg_elevation_index_projected, shr( tmp_index, 1 ) );
    1990             :                             }
    1991        7019 :                             q_direction->band_data[b].elevation_index[m] = tmp_index;
    1992        7019 :                             move16();
    1993             : 
    1994             :                             /*deduce aplhabet for azimuth*/
    1995        7019 :                             azith_alph[b][m] = no_phi_masa[( bits_direction_masa[diff_idx] - 1 )][q_direction->band_data[b].elevation_index[m]]; /*Q0*/
    1996        7019 :                             move16();
    1997             :                         }
    1998             :                         ELSE
    1999             :                         {
    2000     1307672 :                             avg_elevation_index_projected = ivas_dirac_project_elevation_index_fx( avg_elevation_idx, avg_elevation_alphabet, elev_alph[b] ); /*Q0*/
    2001             : 
    2002     1307672 :                             tmp_index = ivas_qmetadata_DecodeExtendedGR( bitstream, index, elev_alph[b], gr_param_elev );                 /*Q0*/
    2003     1307672 :                             tmp_index = ivas_qmetadata_ReorderElevationDecoded( tmp_index, avg_elevation_index_projected, elev_alph[b] ); /*Q0*/
    2004             : 
    2005             :                             /*reorder elevation indexing*/
    2006     1307672 :                             tmp_index = sub( tmp_index, elev_alph[b] / 2 );
    2007     1307672 :                             IF( tmp_index < 0 )
    2008             :                             {
    2009      539795 :                                 tmp_index = negate( shl( tmp_index, 1 ) );
    2010             :                             }
    2011      767877 :                             ELSE IF( tmp_index > 0 )
    2012             :                             {
    2013      258619 :                                 tmp_index = sub( shl( tmp_index, 1 ), 1 );
    2014             :                             }
    2015     1307672 :                             q_direction->band_data[b].elevation_index[m] = tmp_index;
    2016     1307672 :                             move16();
    2017             : 
    2018             :                             /*deduce aplhabet for azimuth*/
    2019     1307672 :                             azith_alph[b][m] = no_phi_masa[( bits_direction_masa[diff_idx] - 1 )][extract_l( L_shr( L_add( q_direction->band_data[b].elevation_index[m], 1 ), 1 ) )]; /*Q0*/
    2020     1307672 :                             move16();
    2021             :                         }
    2022             : 
    2023             :                         /*decode elevation*/
    2024     1314691 :                         q_direction->band_data[b].elevation_fx[m] = deindex_elevation_fx( &q_direction->band_data[b].elevation_index[m], q_direction->band_data[b].bits_sph_idx[m], q_direction->cfg.mc_ls_setup ); /*Q22*/
    2025     1314691 :                         move32();
    2026             :                     }
    2027             :                 }
    2028             :             }
    2029             :         }
    2030             :     }
    2031             :     ELSE
    2032             :     {
    2033      104698 :         FOR( b = start_band; b < nbands; b++ )
    2034             :         {
    2035       87235 :             IF( bands_entropic[b] )
    2036             :             {
    2037       66013 :                 IF( hrmasa_flag )
    2038             :                 {
    2039           0 :                     diff_idx = 0;
    2040           0 :                     move16();
    2041             :                 }
    2042             :                 ELSE
    2043             :                 {
    2044       66013 :                     diff_idx = q_direction->band_data[b].energy_ratio_index_mod[0]; /*Q0*/
    2045       66013 :                     move16();
    2046             :                 }
    2047             : 
    2048      271106 :                 FOR( m = 0; m < nblocks; m++ )
    2049             :                 {
    2050      205093 :                     q_direction->band_data[b].elevation_index[m] = 0;
    2051      205093 :                     move16();
    2052             : 
    2053             :                     /*deduce alphabet for azimuth*/
    2054      205093 :                     IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
    2055             :                     {
    2056       31588 :                         azith_alph[b][m] = no_phi_masa[( bits_direction_masa[diff_idx] - 1 )][q_direction->band_data[b].elevation_index[m]]; /*Q0*/
    2057       31588 :                         move16();
    2058             :                     }
    2059             :                     ELSE
    2060             :                     {
    2061      173505 :                         azith_alph[b][m] = no_phi_masa[( bits_direction_masa[diff_idx] - 1 )][add( q_direction->band_data[b].elevation_index[m], 1 ) / 2]; /*Q0*/
    2062      173505 :                         move16();
    2063             :                     }
    2064             : 
    2065             :                     /*decode elevation*/
    2066      205093 :                     q_direction->band_data[b].elevation_fx[m] = deindex_elevation_fx( &q_direction->band_data[b].elevation_index[m], q_direction->band_data[b].bits_sph_idx[m], q_direction->cfg.mc_ls_setup ); /*Q22*/
    2067      205093 :                     move32();
    2068             :                 }
    2069             :             }
    2070             :         }
    2071             :     }
    2072             : 
    2073             :     /*Azimuth*/
    2074      106917 :     avg_azimuth_alphabet = no_phi_masa[( bits_direction_masa[diff_idx_min] - 1 )][0]; /* average azimuth is quantized on the equatorial plane Q0*/
    2075      106917 :     move16();
    2076      106917 :     avg_azimuth_index = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, avg_azimuth_alphabet ); /*Q0*/
    2077      106917 :     avg_azimuth_index = ivas_qmetadata_dereorder_generic_fx( avg_azimuth_index );                    /*Q0*/
    2078      106917 :     avg_azimuth_index = add( avg_azimuth_index, shr( avg_azimuth_alphabet, 1 ) );                    /*Q0*/
    2079             : 
    2080      106917 :     gr_param_azith = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, 5 + 1 ); /*Q0*/
    2081      106917 :     IF( EQ_32( gr_param_azith, 5 ) )                                               /* all the azimuth distances are zero */
    2082             :     {
    2083      104637 :         FOR( b = start_band; b < nbands; b++ )
    2084             :         {
    2085       86690 :             IF( bands_entropic[b] )
    2086             :             {
    2087      128590 :                 FOR( m = 0; m < nblocks; m++ )
    2088             :                 {
    2089       94703 :                     q_direction->band_data[b].azimuth_index[m] = ivas_dirac_project_azimuth_index_fx( avg_azimuth_index, avg_azimuth_alphabet, azith_alph[b][m] ); /*Q0*/
    2090       94703 :                     move16();
    2091             : 
    2092       94703 :                     IF( EQ_16( azith_alph[b][m], 1 ) )
    2093             :                     {
    2094          15 :                         q_direction->band_data[b].azimuth_fx[m] = 0;
    2095          15 :                         move32();
    2096             :                     }
    2097             :                     ELSE
    2098             :                     {
    2099       94688 :                         q_direction->band_data[b].azimuth_fx[m] = deindex_azimuth_fx( q_direction->band_data[b].azimuth_index[m], q_direction->band_data[b].bits_sph_idx[m], q_direction->band_data[b].elevation_index[m], 0, q_direction->cfg.mc_ls_setup ); /*Q22*/
    2100       94688 :                         move32();
    2101             :                     }
    2102             :                 }
    2103             :             }
    2104             :         }
    2105             :     }
    2106             :     ELSE
    2107             :     {
    2108       88970 :         set32_fx( avg_direction_vector_fx, 0, 3 );
    2109       88970 :         use_adapt_avg = 0;
    2110       88970 :         move16();
    2111       88970 :         idx = 0;
    2112       88970 :         move16();
    2113             : 
    2114      632976 :         FOR( b = start_band; b < nbands; b++ )
    2115             :         {
    2116      544006 :             IF( bands_entropic[b] )
    2117             :             {
    2118     1902915 :                 FOR( m = 0; m < nblocks; m++ )
    2119             :                 {
    2120     1498809 :                     IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) && EQ_16( idx, MASA_LIMIT_IDX_AVG_AZI ) && GT_16( nblocks, 1 ) )
    2121             :                     {
    2122        1215 :                         use_adapt_avg = bitstream[*index]; /*Q0*/
    2123        1215 :                         move16();
    2124        1215 :                         ( *index ) = sub( *index, 1 );
    2125        1215 :                         move16();
    2126             :                     }
    2127     1498809 :                     avg_azimuth_index_projected = ivas_dirac_project_azimuth_index_fx( avg_azimuth_index, avg_azimuth_alphabet, azith_alph[b][m] );     /*Q0*/
    2128     1498809 :                     q_direction->band_data[b].azimuth_index[m] = ivas_qmetadata_DecodeExtendedGR( bitstream, index, azith_alph[b][m], gr_param_azith ); /*Q0*/
    2129     1498809 :                     move16();
    2130     1498809 :                     q_direction->band_data[b].azimuth_index[m] = ivas_qmetadata_ReorderElevationDecoded( q_direction->band_data[b].azimuth_index[m], avg_azimuth_index_projected, azith_alph[b][m] ); /*Q0*/
    2131     1498809 :                     move16();
    2132             : 
    2133     1498809 :                     IF( EQ_16( azith_alph[b][m], 1 ) )
    2134             :                     {
    2135         379 :                         q_direction->band_data[b].azimuth_fx[m] = 0;
    2136         379 :                         move32();
    2137             :                     }
    2138             :                     ELSE
    2139             :                     {
    2140     1498430 :                         q_direction->band_data[b].azimuth_fx[m] = deindex_azimuth_fx( q_direction->band_data[b].azimuth_index[m], q_direction->band_data[b].bits_sph_idx[m], q_direction->band_data[b].elevation_index[m], 0, q_direction->cfg.mc_ls_setup ); /*Q22*/
    2141     1498430 :                         move32();
    2142             :                     }
    2143             : 
    2144     1498809 :                     test();
    2145     1498809 :                     IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) && GT_16( nblocks, 1 ) )
    2146             :                     {
    2147       22728 :                         IF( LT_16( idx, MASA_LIMIT_IDX_AVG_AZI ) )
    2148             :                         {
    2149        7500 :                             ivas_qmetadata_azimuth_elevation_to_direction_vector_fx( q_direction->band_data[b].azimuth_fx[m], q_direction->band_data[b].elevation_fx[m], direction_vector_fx );
    2150        7500 :                             v_shr_32( direction_vector_fx, direction_vector_fx, 3, 5 );                           /*Q25*/
    2151        7500 :                             v_add_32( avg_direction_vector_fx, direction_vector_fx, avg_direction_vector_fx, 3 ); /*Q25*/
    2152             :                         }
    2153             :                         ELSE
    2154             :                         {
    2155       15228 :                             IF( EQ_16( use_adapt_avg, 1 ) )
    2156             :                             {
    2157        8376 :                                 IF( m == 0 )
    2158             :                                 {
    2159        8376 :                                     FOR( Word16 l = 0; l < 3; l++ )
    2160             :                                     {
    2161        6282 :                                         avg_direction_vector_fx[l] = L_shr( avg_direction_vector_fx[l], 1 ); /*0.5f*/
    2162        6282 :                                         move32();
    2163             :                                     }
    2164             :                                 }
    2165             :                                 /*compute the average direction per already coded subband */
    2166        8376 :                                 ivas_qmetadata_azimuth_elevation_to_direction_vector_fx( q_direction->band_data[b].azimuth_fx[m], q_direction->band_data[b].elevation_fx[m], direction_vector_fx );
    2167        8376 :                                 v_shr_32( direction_vector_fx, direction_vector_fx, 3, 5 );                           /*Q25*/
    2168        8376 :                                 v_add_32( avg_direction_vector_fx, direction_vector_fx, avg_direction_vector_fx, 3 ); /*Q25*/
    2169        8376 :                                 ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( avg_direction_vector_fx, 30 - 5, &avg_azimuth_fx, &avg_elevation_fx );
    2170        8376 :                                 avg_azimuth_index = quantize_phi_fx( L_add( avg_azimuth_fx, DEGREE_180_Q_22 ), 0, &avg_azimuth_fx, avg_azimuth_alphabet ); /*Q0*/
    2171             :                             }
    2172             :                         }
    2173       22728 :                         idx = add( idx, 1 );
    2174             :                     }
    2175             :                 }
    2176             :             }
    2177             :         }
    2178             :     }
    2179             : 
    2180      106917 :     return sub( index_start, *index );
    2181             : }
    2182             : 
    2183             : /*-------------------------------------------------------------------------
    2184             :  * ivas_qmetadata_raw_decode_dir_512_fx()
    2185             :  *
    2186             :  * Main function for raw decoding of the directions
    2187             :  *------------------------------------------------------------------------*/
    2188        3485 : static Word16 ivas_qmetadata_raw_decode_dir_512_fx(
    2189             :     IVAS_QDIRECTION *q_direction,         /* i/o: quantized direction structure   */
    2190             :     UWord16 *bitstream,                   /* i  : bitstream                       Q0*/
    2191             :     Word16 *index,                        /*Q0*/
    2192             :     const Word16 nbands,                  /*Q0*/
    2193             :     const Word16 start_band,              /*Q0*/
    2194             :     const SPHERICAL_GRID_DATA *sph_grid16 /* i  : spherical grid for deindexing */
    2195             : )
    2196             : {
    2197             :     Word16 b, m, i;
    2198             :     Word16 nblocks;
    2199             :     Word16 index_start;
    2200             :     UWord16 value;
    2201             : 
    2202        3485 :     index_start = *index;
    2203        3485 :     move16();
    2204        3485 :     nblocks = q_direction->cfg.nblocks;
    2205        3485 :     move16();
    2206             : 
    2207       74313 :     FOR( b = start_band; b < nbands; b++ )
    2208             :     {
    2209      338810 :         FOR( m = 0; m < nblocks; m++ )
    2210             :         {
    2211      267982 :             value = 0;
    2212      267982 :             move16();
    2213     3775944 :             FOR( i = 0; i < q_direction->band_data[b].bits_sph_idx[m]; i++ )
    2214             :             {
    2215     3507962 :                 value = (UWord16) L_add( (UWord16) L_shl( value, 1 ), bitstream[( *index )--] );
    2216             :             }
    2217      267982 :             q_direction->band_data[b].spherical_index[m] = value;
    2218      267982 :             move16();
    2219             : 
    2220      267982 :             IF( EQ_32( q_direction->band_data[b].bits_sph_idx[m], 16 ) )
    2221             :             {
    2222      112032 :                 deindex_sph_idx_fx( value, sph_grid16, &( q_direction->band_data[b].elevation_fx[m] ), &( q_direction->band_data[b].azimuth_fx[m] ) );
    2223             :             }
    2224             :             ELSE
    2225             :             {
    2226      155950 :                 deindex_spherical_component_fx( q_direction->band_data[b].spherical_index[m], &q_direction->band_data[b].azimuth_fx[m], &q_direction->band_data[b].elevation_fx[m], &q_direction->band_data[b].azimuth_index[m], &q_direction->band_data[b].elevation_index[m], q_direction->band_data[b].bits_sph_idx[m], q_direction->cfg.mc_ls_setup );
    2227             :             }
    2228             :         }
    2229             :     }
    2230             : 
    2231        3485 :     return sub( index_start, *index );
    2232             : }
    2233             : 
    2234             : 
    2235       95129 : static Word16 ivas_qmetadata_raw_decode_dir_fx(
    2236             :     IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure   */
    2237             :     UWord16 *bitstream,           /* i  : bitstream                       Q0*/
    2238             :     Word16 *index,                /*Q0*/
    2239             :     const Word16 nbands,          /*Q0*/
    2240             :     const Word16 start_band,      /*Q0*/
    2241             :     const Word16 hrmasa_flag      /* i  : flag indicating high-rate MASA MD coding Q0*/
    2242             : )
    2243             : {
    2244             :     Word16 b, m, azith_alph;
    2245             :     Word16 diff_idx;
    2246             :     Word16 nblocks;
    2247             :     Word16 index_start;
    2248             : 
    2249       95129 :     index_start = *index;
    2250       95129 :     move16();
    2251       95129 :     nblocks = q_direction->cfg.nblocks;
    2252       95129 :     move16();
    2253             : 
    2254      464444 :     FOR( b = start_band; b < nbands; b++ )
    2255             :     {
    2256      369315 :         IF( q_direction->not_in_2D > 0 )
    2257             :         {
    2258      308272 :             decode_fixed_rate_fx( q_direction, bitstream, index, b, nblocks );
    2259             :         }
    2260             :         ELSE
    2261             :         {
    2262       61043 :             IF( hrmasa_flag )
    2263             :             {
    2264           0 :                 diff_idx = 0;
    2265           0 :                 move16();
    2266             :             }
    2267             :             ELSE
    2268             :             {
    2269       61043 :                 diff_idx = q_direction->band_data[b].energy_ratio_index_mod[0]; /*Q0*/
    2270       61043 :                 move16();
    2271             :             }
    2272             : 
    2273      220477 :             FOR( m = 0; m < nblocks; m++ )
    2274             :             {
    2275      159434 :                 q_direction->band_data[b].elevation_fx[m] = 0;
    2276      159434 :                 move32();
    2277      159434 :                 q_direction->band_data[b].elevation_index[m] = 0;
    2278      159434 :                 move16();
    2279      159434 :                 azith_alph = no_phi_masa[bits_direction_masa[diff_idx] - 1][0]; /*Q0*/
    2280      159434 :                 move16();
    2281      159434 :                 q_direction->band_data[b].azimuth_index[m] = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, azith_alph ); /*Q0*/
    2282      159434 :                 move16();
    2283      159434 :                 q_direction->band_data[b].azimuth_fx[m] = deindex_azimuth_fx( q_direction->band_data[b].azimuth_index[m], q_direction->band_data[b].bits_sph_idx[m], 0, 1, q_direction->cfg.mc_ls_setup ); /*Q22*/
    2284      159434 :                 move32();
    2285             :             }
    2286             :         }
    2287             :     }
    2288             : 
    2289       95129 :     return sub( index_start, *index );
    2290             : }
    2291             : 
    2292             : /*-------------------------------------------------------------------------
    2293             :  * ivas_qmetadata_DecodeQuasiUniform()
    2294             :  *
    2295             :  * Read the bitstream following the encoding scheme of EncodeQuasiUniform
    2296             :  *------------------------------------------------------------------------*/
    2297             : 
    2298             : /*! r: Value read from the bitstream */
    2299     1868157 : static UWord16 ivas_qmetadata_DecodeQuasiUniform(
    2300             :     const UWord16 *bitstream,   /* i  : pointer to the bitstream to read                                        Q0*/
    2301             :     Word16 *index,              /* i  : position in the bitstream to start reading (gets updated with reading)  Q0*/
    2302             :     const UWord16 alphabet_size /* i  : size of the alphabet, used to calculate the number of bits needed       Q0*/
    2303             : )
    2304             : {
    2305             :     Word16 i, bits;
    2306             :     UWord16 tresh, value;
    2307             : 
    2308             : 
    2309     1868157 :     bits = sub( 30, norm_l( alphabet_size ) ); /* bits = floor(log2(alphabet_size)) */
    2310     1868157 :     tresh = (UWord16) L_sub( (UWord16) L_shl( 1U, add( bits, 1 ) ), alphabet_size );
    2311             : 
    2312     1868157 :     value = 0;
    2313     1868157 :     move16();
    2314     7476706 :     FOR( i = 0; i < bits; i++ )
    2315             :     {
    2316     5608549 :         value = (UWord16) L_add( (UWord16) L_shl( value, 1 ), bitstream[( *index )--] ); /*Q0*/
    2317             :     }
    2318             : 
    2319     1868157 :     IF( GE_32( value, tresh ) )
    2320             :     {
    2321      268372 :         value = (UWord16) L_add( (UWord16) L_sub( (UWord16) L_shl( value, 1 ), tresh ), bitstream[( *index )--] ); /*Q0*/
    2322             :     }
    2323             : 
    2324     1868157 :     return value;
    2325             : }
    2326             : 
    2327             : 
    2328             : /*-------------------------------------------------------------------------
    2329             :  * ivas_qmetadata_DecodeExtendedGR()
    2330             :  *
    2331             :  * Reads the bitstream and decodes the value using the ExtendedGR algorithm
    2332             :  *------------------------------------------------------------------------*/
    2333             : 
    2334             : /*! r: Value decoded from the bitstream */
    2335             : 
    2336     3947936 : Word16 ivas_qmetadata_DecodeExtendedGR(
    2337             :     UWord16 *bitstream,     /* i  : pointer to the bitstream to read                                            Q0*/
    2338             :     Word16 *index,          /* i/o: position in the bitstream to start reading (gets updated with reading)      */
    2339             :     const Word16 alph_size, /* i  : size of the alphabet, used to calculate the number of bits needed           */
    2340             :     const Word16 gr_param   /* i  : GR parameter that indicates the limit for the most significant bits (msb)   */
    2341             : )
    2342             : {
    2343             :     Word16 i, msb_size;
    2344             :     UWord16 value;
    2345             :     Word16 msb, lsb;
    2346             : 
    2347     3947936 :     msb_size = shr( add( alph_size, sub( shl( 1, gr_param ), 1 ) ), gr_param ); /* ceil division Q0*/
    2348     3947936 :     IF( LE_16( msb_size, 3 ) )
    2349             :     {
    2350      247028 :         value = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, alph_size ); /*Q0*/
    2351             :     }
    2352             :     ELSE
    2353             :     {
    2354     3700908 :         msb = 0;
    2355     3700908 :         move16();
    2356     3700908 :         test();
    2357     6491089 :         WHILE( LT_16( msb, sub( msb_size, 1 ) ) && bitstream[*index] )
    2358             :         {
    2359     2790181 :             test();
    2360     2790181 :             msb = add( msb, 1 );
    2361     2790181 :             ( *index ) = sub( ( *index ), 1 );
    2362     2790181 :             move16();
    2363             :         }
    2364             : 
    2365     3700908 :         IF( EQ_16( msb, sub( msb_size, 1 ) ) )
    2366             :         {
    2367       21870 :             lsb = ivas_qmetadata_DecodeQuasiUniform( bitstream, index, sub( alph_size, shl( sub( msb_size, 1 ), gr_param ) ) ); /*Q0*/
    2368             :         }
    2369             :         ELSE
    2370             :         {
    2371     3679038 :             ( *index ) = sub( ( *index ), 1 );
    2372     3679038 :             move16();
    2373     3679038 :             lsb = 0;
    2374     3679038 :             move16();
    2375     6583981 :             FOR( i = 0; i < gr_param; i++ )
    2376             :             {
    2377     2904943 :                 lsb = extract_l( L_add( shl( lsb, 1 ), bitstream[( *index )--] ) ); /*Q0*/
    2378             :             }
    2379             :         }
    2380             : 
    2381     3700908 :         value = (UWord16) add( shl( msb, gr_param ), lsb ); /*Q0*/
    2382             :     }
    2383             : 
    2384     3947936 :     return value;
    2385             : }
    2386             : 
    2387             : /*-------------------------------------------------------------------------
    2388             :  * ivas_qmetadata_ReorderElevationDecoded()
    2389             :  *
    2390             :  * Calculates the correct elevation index from the decoded data
    2391             :  *------------------------------------------------------------------------*/
    2392             : 
    2393             : /*! r: Elevation index as it will be read by the dequantizer */
    2394     2806481 : static Word16 ivas_qmetadata_ReorderElevationDecoded(
    2395             :     const Word16 elev_dist, /* i  : Distance to the average extracted from the bitstream        Q0*/
    2396             :     const Word16 elev_avg,  /* i  : Average value over time-blocks extracted from the bitstream Q0*/
    2397             :     const Word16 elev_alph  /* i  : elevation alphabet                                          Q0*/
    2398             : )
    2399             : {
    2400             :     Word16 dist_reorder;
    2401             :     Word16 elev_index_reorder;
    2402             : 
    2403     2806481 :     dist_reorder = ivas_qmetadata_dereorder_generic_fx( elev_dist ); /*Q0*/
    2404     2806481 :     elev_index_reorder = add( elev_avg, dist_reorder );
    2405             : 
    2406     2806481 :     IF( elev_index_reorder < 0 )
    2407             :     {
    2408       18045 :         elev_index_reorder = add( elev_index_reorder, elev_alph );
    2409             :     }
    2410     2788436 :     ELSE IF( GE_16( elev_index_reorder, elev_alph ) )
    2411             :     {
    2412       50271 :         elev_index_reorder = sub( elev_index_reorder, elev_alph );
    2413             :     }
    2414             : 
    2415     2806481 :     return elev_index_reorder; /*Q0*/
    2416             : }
    2417             : 
    2418             : 
    2419             : /*-----------------------------------------------------------------------*
    2420             :  * Local functions: requentizeEC3
    2421             :  *-----------------------------------------------------------------------*/
    2422             : 
    2423             : /*! r: number of bits read */
    2424        8156 : static Word16 read_directions_fx(
    2425             :     IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure   */
    2426             :     const UWord8 coding_subbands, /* i  : number of directions            Q0*/
    2427             :     const UWord8 masa_subframes,  /* i  : number of tiles                 Q0*/
    2428             :     UWord16 *bitstream,           /* i  : bitstream to be read            Q0*/
    2429             :     Word16 *pbit_pos,             /*Q0*/
    2430             :     Word16 *ind_order /*Q0*/ )
    2431             : {
    2432             :     Word16 j, k, allowed_bits, last_j, nbits, fixed_rate;
    2433             :     Word16 i;
    2434             :     Word16 diff;
    2435             :     UWord16 byteBuffer;
    2436             :     Word16 use_vq, max_nb_idx;
    2437             :     Word16 bit_pos;
    2438             :     Word16 *bits_dir0;
    2439             : 
    2440        8156 :     bit_pos = *pbit_pos;
    2441        8156 :     move16();
    2442             : 
    2443        8156 :     diff = 0;
    2444        8156 :     move16();
    2445        8156 :     IF( q_direction->not_in_2D )
    2446             :     {
    2447             : 
    2448        7850 :         IF( GT_16( coding_subbands, 1 ) )
    2449             :         {
    2450        7781 :             j = ind_order[( coding_subbands - 1 )];
    2451        7781 :             move16();
    2452        7781 :             allowed_bits = 0;
    2453        7781 :             move16();
    2454             : 
    2455       29440 :             FOR( k = 0; k < masa_subframes; k++ )
    2456             :             {
    2457       21659 :                 allowed_bits = extract_l( L_add( allowed_bits, q_direction->band_data[j].bits_sph_idx[k] ) ); /*Q0*/
    2458             :             }
    2459             : 
    2460        7781 :             last_j = sub( j, (Word16) ( allowed_bits == 0 ) );
    2461             : 
    2462       32678 :             FOR( j = 0; j < last_j; j++ )
    2463             :             {
    2464       24897 :                 i = ind_order[j];
    2465       24897 :                 move16();
    2466       24897 :                 bits_dir0 = (Word16 *) q_direction->band_data[i].bits_sph_idx; /*Q0*/
    2467             : 
    2468       24897 :                 nbits = 0;
    2469       24897 :                 move16();
    2470       24897 :                 allowed_bits = sum16_fx( bits_dir0, q_direction->cfg.nblocks );
    2471       24897 :                 use_vq = 0;
    2472       24897 :                 move16();
    2473       24897 :                 max_nb_idx = 0;
    2474       24897 :                 move16();
    2475             : 
    2476       90723 :                 FOR( k = 0; k < q_direction->cfg.nblocks; k++ )
    2477             :                 {
    2478       65826 :                     IF( GT_16( bits_dir0[k], use_vq ) )
    2479             :                     {
    2480       29958 :                         use_vq = bits_dir0[k];
    2481       29958 :                         move16();
    2482       29958 :                         max_nb_idx = k;
    2483       29958 :                         move16();
    2484             :                     }
    2485             :                 }
    2486             : 
    2487       24897 :                 IF( EQ_16( q_direction->cfg.nblocks, 1 ) )
    2488             :                 {
    2489       11254 :                     byteBuffer = 0;
    2490       11254 :                     move16();
    2491             :                 }
    2492             :                 ELSE
    2493             :                 {
    2494       13643 :                     byteBuffer = 0;
    2495       13643 :                     move16();
    2496       13643 :                     if ( LE_16( use_vq, 1 ) )
    2497             :                     {
    2498          29 :                         byteBuffer = 1;
    2499          29 :                         move16();
    2500             :                     }
    2501       13643 :                     test();
    2502       13643 :                     IF( GT_16( use_vq, 1 ) && LE_16( use_vq, LIMIT_USE_COMMON ) )
    2503             :                     {
    2504        2206 :                         bits_dir0[max_nb_idx] = sub( bits_dir0[max_nb_idx], 1 );
    2505        2206 :                         move16();
    2506        2206 :                         allowed_bits = sub( allowed_bits, 1 );
    2507             :                         /* read 1 bit to tell if joint of VQ coding */
    2508        2206 :                         byteBuffer = bitstream[bit_pos--];
    2509        2206 :                         move16();
    2510             :                     }
    2511             :                 }
    2512             : 
    2513       90723 :                 FOR( k = 0; k < masa_subframes; k++ )
    2514             :                 {
    2515       65826 :                     q_direction->band_data[i].bits_sph_idx[k] = bits_dir0[k]; /*Q0*/
    2516       65826 :                     move16();
    2517       65826 :                     IF( GT_16( bits_dir0[k], 2 ) )
    2518             :                     {
    2519       62586 :                         IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
    2520             :                         {
    2521        3731 :                             q_direction->band_data[i].elevation_m_alphabet[k] = no_theta_masa[bits_dir0[k] - 3]; /*Q0*/
    2522        3731 :                             move16();
    2523             :                         }
    2524             :                         ELSE
    2525             :                         {
    2526       58855 :                             q_direction->band_data[i].elevation_m_alphabet[k] = shl( no_theta_masa[bits_dir0[k] - 3], 1 ) - 1;
    2527       58855 :                             move16();
    2528             :                         }
    2529             :                     }
    2530             :                     ELSE
    2531             :                     {
    2532        3240 :                         q_direction->band_data[i].elevation_m_alphabet[k] = 1;
    2533        3240 :                         move16();
    2534             :                     }
    2535             :                 }
    2536             : 
    2537       24897 :                 IF( allowed_bits > 0 )
    2538             :                 {
    2539       24897 :                     IF( EQ_32( byteBuffer, 1 ) )
    2540             :                     {
    2541        2185 :                         nbits = read_common_direction_fx( bitstream, q_direction, i, masa_subframes, allowed_bits, &bit_pos ); /*Q0*/
    2542             :                     }
    2543             :                     ELSE
    2544             :                     {
    2545       22712 :                         test();
    2546       22712 :                         IF( EQ_16( q_direction->cfg.nblocks, 1 ) && LE_32( q_direction->band_data[i].bits_sph_idx[0], L_add( MASA_MIN_BITS_TF, 1 ) ) )
    2547             :                         {
    2548             :                             /* there is fixed rate only, no need to read  */
    2549        5734 :                             fixed_rate = 1;
    2550        5734 :                             move16();
    2551        5734 :                             nbits = 0;
    2552        5734 :                             move16();
    2553             :                         }
    2554             :                         ELSE
    2555             :                         {
    2556             :                             /* check if fixed_rate */
    2557       16978 :                             fixed_rate = bitstream[bit_pos--];
    2558       16978 :                             move16();
    2559       16978 :                             nbits = 1;
    2560       16978 :                             move16();
    2561             :                         }
    2562             : 
    2563       22712 :                         IF( EQ_16( fixed_rate, 1 ) )
    2564             :                         {
    2565             :                             /* decode_fixed_rate()*/
    2566       15680 :                             nbits = add( nbits, decode_fixed_rate_fx( q_direction, bitstream, &bit_pos, i, masa_subframes ) );
    2567             :                         }
    2568             :                         ELSE
    2569             :                         {
    2570             : 
    2571             :                             /* decode elevation */
    2572        7032 :                             nbits = add( nbits, decode_elevation_fx( q_direction, bitstream, &bit_pos, i, masa_subframes ) ); /*Q0*/
    2573             :                             /* decode azimuth */
    2574        7032 :                             nbits = add( nbits, decode_azimuth_fx( q_direction, bitstream, &bit_pos, i, masa_subframes ) ); /*Q0*/
    2575             :                         }
    2576             :                     }
    2577             :                 }
    2578             :                 ELSE
    2579             :                 {
    2580           0 :                     set_zero_direction_fx( q_direction, i, masa_subframes );
    2581             :                 }
    2582             : 
    2583       24897 :                 diff = add( diff, sub( nbits, allowed_bits ) );
    2584             : 
    2585             :                 /* update bits for next block */
    2586       24897 :                 update_bits_next_block_fx( q_direction, &diff, ind_order[j + 1], coding_subbands, masa_subframes );
    2587             :             }
    2588             :         }
    2589             :         ELSE
    2590             :         {
    2591          69 :             last_j = q_direction->cfg.start_band; /*Q0*/
    2592          69 :             move16();
    2593             :         }
    2594             : 
    2595             : 
    2596       20453 :         FOR( j = last_j; j < coding_subbands; j++ )
    2597             :         {
    2598       12603 :             i = ind_order[j];
    2599       12603 :             move16();
    2600       12603 :             bits_dir0 = (Word16 *) q_direction->band_data[i].bits_sph_idx; /*Q0*/
    2601             : 
    2602       12603 :             nbits = 0;
    2603       12603 :             move16();
    2604       12603 :             allowed_bits = sum16_fx( bits_dir0, q_direction->cfg.nblocks ); /*Q0*/
    2605       12603 :             test();
    2606       12603 :             IF( allowed_bits > 0 && EQ_16( masa_subframes, 1 ) )
    2607             :             {
    2608        5440 :                 nbits = add( nbits, decode_fixed_rate_fx( q_direction, bitstream, &bit_pos, i, masa_subframes ) ); /*Q0*/
    2609             :             }
    2610             :             ELSE
    2611             :             {
    2612        7163 :                 IF( allowed_bits > 0 )
    2613             :                 {
    2614        7163 :                     use_vq = 0;
    2615        7163 :                     move16();
    2616        7163 :                     max_nb_idx = 0;
    2617        7163 :                     move16();
    2618       35815 :                     FOR( k = 0; k < masa_subframes; k++ )
    2619             :                     {
    2620       28652 :                         IF( GT_16( bits_dir0[k], use_vq ) )
    2621             :                         {
    2622        9689 :                             use_vq = bits_dir0[k]; /*Q0*/
    2623        9689 :                             move16();
    2624        9689 :                             max_nb_idx = k;
    2625        9689 :                             move16();
    2626             :                         }
    2627             :                     }
    2628             : 
    2629        7163 :                     byteBuffer = 0;
    2630        7163 :                     move16();
    2631             : 
    2632        7163 :                     test();
    2633        7163 :                     IF( GT_16( use_vq, 1 ) && LE_16( use_vq, LIMIT_USE_COMMON ) )
    2634             :                     {
    2635        1042 :                         bits_dir0[max_nb_idx] = sub( bits_dir0[max_nb_idx], 1 );
    2636        1042 :                         move16();
    2637        1042 :                         allowed_bits = sub( allowed_bits, 1 );
    2638             : 
    2639             :                         /* read 1 bit to tell if joint of VQ coding */
    2640        1042 :                         byteBuffer = bitstream[bit_pos--];
    2641        1042 :                         move16();
    2642             :                     }
    2643             : 
    2644        7163 :                     IF( allowed_bits > 0 )
    2645             :                     {
    2646        7163 :                         test();
    2647        7163 :                         IF( EQ_32( byteBuffer, 1 ) || LE_16( use_vq, 1 ) )
    2648             :                         {
    2649        1001 :                             nbits = read_common_direction_fx( bitstream, q_direction, i, masa_subframes, allowed_bits, &bit_pos ); /*Q0*/
    2650             :                         }
    2651             :                         ELSE
    2652             :                         {
    2653             :                             /* decode_fixed_rate()*/
    2654        6162 :                             nbits = add( nbits, decode_fixed_rate_fx( q_direction, bitstream, &bit_pos, i, masa_subframes ) );
    2655             :                         }
    2656             :                     }
    2657             :                     ELSE
    2658             :                     {
    2659           0 :                         set_zero_direction_fx( q_direction, i, masa_subframes );
    2660             :                     }
    2661             :                 }
    2662             :                 ELSE
    2663             :                 {
    2664           0 :                     set_zero_direction_fx( q_direction, i, masa_subframes );
    2665             :                 }
    2666             :             }
    2667             :         }
    2668             :     }
    2669             :     ELSE
    2670             :     {
    2671             :         /* 2D */
    2672        1490 :         FOR( j = 0; j < coding_subbands; j++ )
    2673             :         {
    2674        4309 :             FOR( k = 0; k < q_direction->cfg.nblocks; k++ )
    2675             :             {
    2676        3125 :                 q_direction->band_data[j].elevation_fx[k] = 0;
    2677        3125 :                 move32();
    2678        3125 :                 q_direction->band_data[j].elevation_index[k] = 0;
    2679        3125 :                 move16();
    2680             :             }
    2681             :         }
    2682             : 
    2683         306 :         nbits = decode_azimuth2D_fx( q_direction, bitstream, coding_subbands, &bit_pos, masa_subframes ); /*Q0*/
    2684             :     }
    2685        8156 :     nbits = sub( *pbit_pos, bit_pos );
    2686        8156 :     *pbit_pos = bit_pos;
    2687        8156 :     move16();
    2688             : 
    2689        8156 :     return nbits;
    2690             : }
    2691             : 
    2692             : /*-------------------------------------------------------------------*
    2693             :  * decode_azimuth()
    2694             :  *
    2695             :  * read and decode the azimuth indexes for one subband
    2696             :  *-------------------------------------------------------------------*/
    2697             : 
    2698             : /*! r: number of bits read  */
    2699        7032 : static Word16 decode_azimuth_fx(
    2700             :     IVAS_QDIRECTION *q_direction, /* i/o: quantized metadata structure    */
    2701             :     UWord16 *bitstream,           /* i  : bitstream to be read            Q0*/
    2702             :     Word16 *pbit_pos,             /* i/o: current position in bitstream   Q0*/
    2703             :     const Word16 idx_subband,     /* i  : subband index                   Q0*/
    2704             :     const Word16 masa_subframes   /* i  : number of tiles                 Q0*/
    2705             : )
    2706             : {
    2707             :     Word16 bit_pos, nbits, k;
    2708             :     UWord16 use_context, byteBuffer;
    2709             :     UWord16 min_idx;
    2710             :     Word16 j_az, max_val;
    2711             : 
    2712        7032 :     nbits = 0;
    2713        7032 :     move16();
    2714        7032 :     bit_pos = *pbit_pos;
    2715        7032 :     move16();
    2716        7032 :     byteBuffer = 0;
    2717        7032 :     move16();
    2718             : 
    2719        7032 :     j_az = 0;
    2720        7032 :     move16();
    2721             :     /* check number of valid indexes to decode */
    2722       35019 :     FOR( k = 0; k < masa_subframes; k++ )
    2723             :     {
    2724       27987 :         IF( LT_32( q_direction->band_data[idx_subband].azimuth_index[k], MASA_NO_INDEX ) )
    2725             :         {
    2726       27985 :             j_az = add( j_az, 1 );
    2727             :         }
    2728             :         ELSE
    2729             :         {
    2730           2 :             q_direction->band_data[idx_subband].azimuth_fx[k] = 0; /*To be in sync with encoder values.*/
    2731           2 :             move32();
    2732             :         }
    2733             :     }
    2734             : 
    2735        7032 :     IF( !j_az )
    2736             :     {
    2737           0 :         return nbits;
    2738             :     }
    2739             : 
    2740        7032 :     IF( !byteBuffer )
    2741             :     {
    2742             :         /* use context */
    2743        7032 :         use_context = 0;
    2744        7032 :         move16();
    2745       35019 :         FOR( k = 0; k < masa_subframes; k++ )
    2746             :         {
    2747       27987 :             if ( LE_32( q_direction->band_data[idx_subband].bits_sph_idx[k], 1 ) )
    2748             :             {
    2749           0 :                 use_context = 1;
    2750           0 :                 move16();
    2751             :             }
    2752             :         }
    2753             : 
    2754        7032 :         IF( EQ_32( use_context, 1 ) )
    2755             :         {
    2756           0 :             FOR( k = 0; k < masa_subframes; k++ )
    2757             :             {
    2758           0 :                 IF( q_direction->band_data[idx_subband].bits_sph_idx[k] == 0 )
    2759             :                 {
    2760           0 :                     q_direction->band_data[idx_subband].azimuth_index[k] = 0;
    2761           0 :                     move16();
    2762           0 :                     q_direction->band_data[idx_subband].azimuth_fx[k] = 0;
    2763           0 :                     move32();
    2764             :                 }
    2765             :                 ELSE
    2766             :                 {
    2767           0 :                     IF( EQ_32( q_direction->band_data[idx_subband].bits_sph_idx[k], 1 ) )
    2768             :                     {
    2769           0 :                         byteBuffer = bitstream[bit_pos--];
    2770           0 :                         move16();
    2771           0 :                         q_direction->band_data[idx_subband].azimuth_index[k] = byteBuffer; /*Q0*/
    2772           0 :                         move16();
    2773             : 
    2774           0 :                         q_direction->band_data[idx_subband].azimuth_fx[k] = L_shl( L_mult0( q_direction->band_data[idx_subband].azimuth_index[k], -180 ), Q22 ); /*Q22*/
    2775           0 :                         move32();
    2776             :                     }
    2777             :                     ELSE
    2778             :                     {
    2779           0 :                         q_direction->band_data[idx_subband].azimuth_index[k] = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, q_direction->band_data[idx_subband].azimuth_m_alphabet[k], sub( MASA_GR_ORD_AZ, (Word16) EQ_32( q_direction->band_data[idx_subband].bits_sph_idx[k], 2 ) ) ); /*Q0*/
    2780           0 :                         move16();
    2781             : 
    2782           0 :                         q_direction->band_data[idx_subband].azimuth_fx[k] = deindex_azimuth_fx( q_direction->band_data[idx_subband].azimuth_index[k], q_direction->band_data[idx_subband].bits_sph_idx[k], q_direction->band_data[idx_subband].elevation_index[k], 1, q_direction->cfg.mc_ls_setup ); /*Q22*/
    2783           0 :                         move32();
    2784             :                     }
    2785             :                 }
    2786             :             }
    2787             :         }
    2788             :         ELSE
    2789             :         {
    2790             :             /* read bit to check if min removed encoding */
    2791        7032 :             byteBuffer = bitstream[bit_pos]; /*Q22*/
    2792        7032 :             move16();
    2793        7032 :             bit_pos = sub( bit_pos, 1 );
    2794        7032 :             IF( byteBuffer == 0 ) /* regular GR coding5 */
    2795             :             {
    2796             :                 /* read GR_order */
    2797        2291 :                 byteBuffer = bitstream[bit_pos];
    2798        2291 :                 move16();
    2799        2291 :                 bit_pos = sub( bit_pos, 1 );
    2800        2291 :                 nbits = add( nbits, 1 );
    2801             : 
    2802       11314 :                 FOR( k = 0; k < masa_subframes; k++ )
    2803             :                 {
    2804        9023 :                     IF( q_direction->band_data[idx_subband].bits_sph_idx[k] > 0 )
    2805             :                     {
    2806        9023 :                         IF( GT_16( no_phi_masa[L_sub( q_direction->band_data[idx_subband].bits_sph_idx[k], 1 )][q_direction->band_data[idx_subband].elevation_index[k]], 1 ) )
    2807             :                         {
    2808        9021 :                             q_direction->band_data[idx_subband].azimuth_index[k] = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, q_direction->band_data[idx_subband].azimuth_m_alphabet[k], extract_l( L_sub( MASA_GR_ORD_AZ, byteBuffer ) ) ); /*Q0*/
    2809        9021 :                             move16();
    2810        9021 :                             q_direction->band_data[idx_subband].azimuth_fx[k] = deindex_azimuth_fx( q_direction->band_data[idx_subband].azimuth_index[k], q_direction->band_data[idx_subband].bits_sph_idx[k], q_direction->band_data[idx_subband].elevation_index[k], 1, q_direction->cfg.mc_ls_setup ); /*Q22*/
    2811        9021 :                             move32();
    2812             :                         }
    2813             :                         ELSE
    2814             :                         {
    2815           2 :                             q_direction->band_data[idx_subband].azimuth_fx[k] = 0;
    2816           2 :                             move32();
    2817           2 :                             q_direction->band_data[idx_subband].azimuth_index[k] = 0;
    2818           2 :                             move16();
    2819             :                         }
    2820             :                     }
    2821             :                     ELSE
    2822             :                     {
    2823           0 :                         q_direction->band_data[idx_subband].azimuth_fx[k] = 0;
    2824           0 :                         move32();
    2825           0 :                         q_direction->band_data[idx_subband].azimuth_index[k] = 0;
    2826           0 :                         move16();
    2827             :                     }
    2828             :                 }
    2829             :             }
    2830             :             ELSE
    2831             :             {
    2832             :                 /* min removed GR coding */
    2833             :                 /* read GR_order */
    2834        4741 :                 byteBuffer = bitstream[bit_pos]; /*Q0*/
    2835        4741 :                 move16();
    2836        4741 :                 bit_pos = sub( bit_pos, 1 );
    2837             :                 /* read min index value */
    2838        4741 :                 maximum_s( q_direction->band_data[idx_subband].azimuth_m_alphabet, masa_subframes, &max_val );
    2839        4741 :                 min_idx = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, max_val, MASA_GR_ORD_AZ ); /*Q0*/
    2840             : 
    2841       23705 :                 FOR( k = 0; k < masa_subframes; k++ )
    2842             :                 {
    2843       18964 :                     IF( q_direction->band_data[idx_subband].bits_sph_idx[k] > 0 )
    2844             :                     {
    2845       18964 :                         IF( GT_16( no_phi_masa[q_direction->band_data[idx_subband].bits_sph_idx[k] - 1][q_direction->band_data[idx_subband].elevation_index[k]], 1 ) )
    2846             :                         {
    2847       18964 :                             q_direction->band_data[idx_subband].azimuth_index[k] = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, q_direction->band_data[idx_subband].azimuth_m_alphabet[k], extract_l( L_sub( MASA_GR_ORD_AZ - 1, byteBuffer ) ) ); /*Q0*/
    2848       18964 :                             move16();
    2849       18964 :                             q_direction->band_data[idx_subband].azimuth_index[k] = (UWord16) L_add( q_direction->band_data[idx_subband].azimuth_index[k], min_idx ); /*Q0*/
    2850       18964 :                             move16();
    2851       18964 :                             q_direction->band_data[idx_subband].azimuth_fx[k] = deindex_azimuth_fx( q_direction->band_data[idx_subband].azimuth_index[k], q_direction->band_data[idx_subband].bits_sph_idx[k], q_direction->band_data[idx_subband].elevation_index[k], 1, q_direction->cfg.mc_ls_setup ); /*Q22*/
    2852       18964 :                             move32();
    2853             :                         }
    2854             :                         ELSE
    2855             :                         {
    2856           0 :                             q_direction->band_data[idx_subband].azimuth_fx[k] = 0;
    2857           0 :                             move32();
    2858           0 :                             q_direction->band_data[idx_subband].azimuth_index[k] = 0;
    2859           0 :                             move16();
    2860             :                         }
    2861             :                     }
    2862             :                     ELSE
    2863             :                     {
    2864           0 :                         q_direction->band_data[idx_subband].azimuth_fx[k] = 0;
    2865           0 :                         move32();
    2866           0 :                         q_direction->band_data[idx_subband].azimuth_index[k] = 0;
    2867           0 :                         move16();
    2868             :                     }
    2869             :                 }
    2870             :             }
    2871             :         }
    2872             :     }
    2873             : 
    2874        7032 :     nbits = sub( *pbit_pos, bit_pos );
    2875             : 
    2876        7032 :     *pbit_pos = bit_pos;
    2877        7032 :     move16();
    2878             : 
    2879        7032 :     return nbits;
    2880             : }
    2881             : 
    2882             : 
    2883             : /*-------------------------------------------------------------------*
    2884             :  * decode_elevation()
    2885             :  *
    2886             :  * Reads the bitstream and decode the elevation index
    2887             :  *-------------------------------------------------------------------*/
    2888             : 
    2889             : /*! r: number of bits read */
    2890        7032 : static Word16 decode_elevation_fx(
    2891             :     IVAS_QDIRECTION *q_direction, /* i/o: quantized metadata structure            */
    2892             :     UWord16 *bitstream,           /* i  : input bitstream                         Q0*/
    2893             :     Word16 *pbit_pos,             /* i/o: current position to be read in bitstream Q0*/
    2894             :     const Word16 j,               /* i  : subband index                           Q0*/
    2895             :     const Word16 masa_subframes   /* i  : number of tiles                         Q0*/
    2896             : )
    2897             : {
    2898             :     Word16 nr_NO_INDEX, nbits;
    2899             :     Word16 bit_pos;
    2900             :     UWord16 byteBuffer;
    2901             :     Word16 k, GR_ord_elevation;
    2902             :     UWord16 same_idx;
    2903             : 
    2904        7032 :     nr_NO_INDEX = 0;
    2905        7032 :     move16();
    2906        7032 :     nbits = 0;
    2907        7032 :     move16();
    2908        7032 :     bit_pos = *pbit_pos;
    2909        7032 :     move16();
    2910             : 
    2911       35019 :     FOR( k = 0; k < masa_subframes; k++ )
    2912             :     {
    2913       27987 :         q_direction->band_data[j].elevation_index[k] = 0;
    2914       27987 :         move16();
    2915       27987 :         q_direction->band_data[j].elevation_fx[k] = 0;
    2916       27987 :         move32();
    2917             : 
    2918       27987 :         IF( q_direction->band_data[j].bits_sph_idx[k] > 0 )
    2919             :         {
    2920       27987 :             IF( LE_32( q_direction->band_data[j].bits_sph_idx[k], 2 ) )
    2921             :             {
    2922           2 :                 q_direction->band_data[j].elevation_index[k] = MASA_NO_INDEX; /*Q0*/
    2923           2 :                 move16();
    2924           2 :                 nr_NO_INDEX = add( nr_NO_INDEX, 1 );
    2925           2 :                 q_direction->band_data[j].elevation_fx[k] = 0;
    2926           2 :                 move32();
    2927           2 :                 q_direction->band_data[j].elevation_m_alphabet[k] = 1;
    2928           2 :                 move16();
    2929             :             }
    2930             :             ELSE
    2931             :             {
    2932       27985 :                 IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
    2933             :                 {
    2934        2098 :                     q_direction->band_data[j].elevation_m_alphabet[k] = no_theta_masa[q_direction->band_data[j].bits_sph_idx[k] - 3]; /*Q0*/
    2935        2098 :                     move16();
    2936             :                 }
    2937             :                 ELSE
    2938             :                 {
    2939       25887 :                     q_direction->band_data[j].elevation_m_alphabet[k] = shl( no_theta_masa[q_direction->band_data[j].bits_sph_idx[k] - 3], 1 ) - 1; /*Q0*/
    2940       25887 :                     move16();
    2941             :                 }
    2942             :             }
    2943             :         }
    2944             :         ELSE
    2945             :         {
    2946           0 :             nr_NO_INDEX = add( nr_NO_INDEX, 1 );
    2947             :         }
    2948             :     }
    2949             : 
    2950        7032 :     IF( LT_16( nr_NO_INDEX, masa_subframes ) )
    2951             :     {
    2952             :         {
    2953             :             /* read if same or not */
    2954        7032 :             byteBuffer = bitstream[bit_pos];
    2955        7032 :             move16();
    2956        7032 :             bit_pos = sub( bit_pos, 1 );
    2957        7032 :             IF( EQ_32( byteBuffer, 1 ) ) /* same value */
    2958             :             {
    2959             :                 /* read value */
    2960        5440 :                 byteBuffer = bitstream[bit_pos]; /*Q0*/
    2961        5440 :                 move16();
    2962        5440 :                 bit_pos = sub( bit_pos, 1 );
    2963        5440 :                 byteBuffer = (UWord16) L_add( L_shl( byteBuffer, 1 ), bitstream[bit_pos] );
    2964        5440 :                 move16();
    2965        5440 :                 bit_pos = sub( bit_pos, 1 );
    2966        5440 :                 same_idx = byteBuffer;
    2967        5440 :                 move16();
    2968             : 
    2969       27059 :                 FOR( k = 0; k < masa_subframes; k++ )
    2970             :                 {
    2971       21619 :                     IF( LT_32( q_direction->band_data[j].elevation_index[k], MASA_NO_INDEX ) )
    2972             :                     {
    2973       21619 :                         q_direction->band_data[j].elevation_index[k] = same_idx; /*Q0*/
    2974       21619 :                         move16();
    2975       21619 :                         q_direction->band_data[j].elevation_fx[k] = deindex_elevation_fx( &q_direction->band_data[j].elevation_index[k], q_direction->band_data[j].bits_sph_idx[k], q_direction->cfg.mc_ls_setup ); /*Q22*/
    2976       21619 :                         move32();
    2977             :                     }
    2978             :                 }
    2979             :             }
    2980             :             ELSE
    2981             :             {
    2982             :                 /* not same; decode mean removed GR */
    2983        1592 :                 byteBuffer = bitstream[bit_pos]; /*Q0*/
    2984        1592 :                 bit_pos = sub( bit_pos, 1 );
    2985        1592 :                 move16();
    2986        1592 :                 GR_ord_elevation = extract_l( L_sub( MASA_GR_ORD_EL, byteBuffer ) ); /*Q0*/
    2987             : 
    2988        7960 :                 FOR( k = 0; k < masa_subframes; k++ )
    2989             :                 {
    2990        6368 :                     IF( LT_32( q_direction->band_data[j].elevation_index[k], MASA_NO_INDEX ) )
    2991             :                     {
    2992        6366 :                         q_direction->band_data[j].elevation_index[k] = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, q_direction->band_data[j].elevation_m_alphabet[k], GR_ord_elevation ); /*Q0*/
    2993        6366 :                         move16();
    2994        6366 :                         q_direction->band_data[j].elevation_fx[k] = deindex_elevation_fx( &q_direction->band_data[j].elevation_index[k], q_direction->band_data[j].bits_sph_idx[k], q_direction->cfg.mc_ls_setup ); /*Q22*/
    2995        6366 :                         move32();
    2996             :                     }
    2997             :                 }
    2998             :             }
    2999             :         }
    3000             :     }
    3001             : 
    3002       35019 :     FOR( k = 0; k < masa_subframes; k++ )
    3003             :     {
    3004       27987 :         test();
    3005       27987 :         IF( LT_32( q_direction->band_data[j].elevation_index[k], MASA_NO_INDEX ) &&
    3006             :             LE_16( no_phi_masa[sub( q_direction->band_data[j].bits_sph_idx[k], 1 )][q_direction->band_data[j].elevation_index[k]], 1 ) )
    3007             :         {
    3008           2 :             q_direction->band_data[j].azimuth_index[k] = MASA_NO_INDEX; /*Q0*/
    3009           2 :             move16();
    3010           2 :             q_direction->band_data[j].azimuth_m_alphabet[k] = 1; /*Q0*/
    3011           2 :             move16();
    3012             :         }
    3013             :         ELSE
    3014             :         {
    3015       27985 :             q_direction->band_data[j].azimuth_index[k] = 0;
    3016       27985 :             move16();
    3017       27985 :             IF( LT_32( q_direction->band_data[j].elevation_index[k], MASA_NO_INDEX ) )
    3018             :             {
    3019       27983 :                 q_direction->band_data[j].azimuth_m_alphabet[k] = no_phi_masa[sub( q_direction->band_data[j].bits_sph_idx[k], 1 )][q_direction->band_data[j].elevation_index[k]]; /*Q0*/
    3020       27983 :                 move16();
    3021             :             }
    3022             :             ELSE
    3023             :             {
    3024           2 :                 q_direction->band_data[j].azimuth_m_alphabet[k] = no_phi_masa[sub( q_direction->band_data[j].bits_sph_idx[k], 1 )][0]; /*Q0*/
    3025           2 :                 move16();
    3026           2 :                 q_direction->band_data[j].elevation_index[k] = 0;
    3027           2 :                 move16();
    3028             :             }
    3029             :         }
    3030             :     }
    3031             : 
    3032        7032 :     nbits = sub( *pbit_pos, bit_pos );
    3033        7032 :     *pbit_pos = bit_pos;
    3034        7032 :     move16();
    3035             : 
    3036        7032 :     return nbits;
    3037             : }
    3038             : 
    3039             : 
    3040      507035 : static Word16 decode_fixed_rate_fx(
    3041             :     IVAS_QDIRECTION *q_direction, /* i/o: quantized metadata          */
    3042             :     const UWord16 *bitstream,     /* i  : bitstream to be read        Q0*/
    3043             :     Word16 *pbit_pos,             /* i/o: position in bitstream       Q0*/
    3044             :     const Word16 b,               /* i  : subband index               Q0*/
    3045             :     const Word16 nblocks          /* i  : number of tiles in subband  Q0*/
    3046             : )
    3047             : {
    3048             :     Word16 nbits, m, i;
    3049             :     UWord16 value;
    3050             : 
    3051      507035 :     nbits = 0;
    3052      507035 :     move16();
    3053             : 
    3054     2249473 :     FOR( m = 0; m < nblocks; m++ )
    3055             :     {
    3056     1742438 :         value = 0;
    3057     1742438 :         move16();
    3058     9072865 :         FOR( i = 0; i < q_direction->band_data[b].bits_sph_idx[m]; i++ )
    3059             :         {
    3060     7330427 :             value = (UWord16) L_add( L_shl( value, 1 ), bitstream[( *pbit_pos )--] ); /*Q0*/
    3061     7330427 :             move16();
    3062             :         }
    3063             : 
    3064     1742438 :         q_direction->band_data[b].spherical_index[m] = value; /*Q0*/
    3065     1742438 :         move16();
    3066     1742438 :         nbits = extract_l( L_add( nbits, q_direction->band_data[b].bits_sph_idx[m] ) ); /*Q0*/
    3067             : 
    3068     1742438 :         deindex_spherical_component_fx( q_direction->band_data[b].spherical_index[m], &q_direction->band_data[b].azimuth_fx[m], &q_direction->band_data[b].elevation_fx[m], &q_direction->band_data[b].azimuth_index[m], &q_direction->band_data[b].elevation_index[m], q_direction->band_data[b].bits_sph_idx[m], q_direction->cfg.mc_ls_setup );
    3069             :     }
    3070             : 
    3071      507035 :     return nbits;
    3072             : }
    3073             : 
    3074             : /*-------------------------------------------------------------------*
    3075             :  * decode_azimuth2D()
    3076             :  *
    3077             :  * Azimuth bitstream reading and decoding in 2D case
    3078             :  *-------------------------------------------------------------------*/
    3079             : 
    3080             : /*! r: number of bits read */
    3081         306 : static Word16 decode_azimuth2D_fx(
    3082             :     IVAS_QDIRECTION *q_direction, /* i/o: quantized metadata structure    */
    3083             :     UWord16 *bitstream,           /* i  : bitstream to be read            Q0*/
    3084             :     const Word16 coding_subbands, /* i  : number of subbands              Q0*/
    3085             :     Word16 *pbit_pos,             /*Q0*/
    3086             :     const Word16 no_frames /*Q0*/ )
    3087             : {
    3088             :     Word16 i, j, k;
    3089             :     Word16 allowed_bits, nbits;
    3090             :     Word16 use_vq;
    3091             :     UWord16 Buffer;
    3092             :     Word16 bit_pos;
    3093             :     Word16 *bits_dir0;
    3094             : 
    3095         306 :     bit_pos = *pbit_pos;
    3096         306 :     move16();
    3097         306 :     nbits = 0;
    3098         306 :     move16();
    3099        1490 :     FOR( j = 0; j < coding_subbands; j++ )
    3100             :     {
    3101        1184 :         bits_dir0 = (Word16 *) q_direction->band_data[j].bits_sph_idx; /*Q0*/
    3102        1184 :         allowed_bits = sum16_fx( bits_dir0, no_frames );
    3103             : 
    3104        1184 :         IF( allowed_bits > 0 )
    3105             :         {
    3106        1184 :             use_vq = 0;
    3107        1184 :             move16();
    3108        4309 :             FOR( k = 0; k < no_frames; k++ )
    3109             :             {
    3110        3125 :                 q_direction->band_data[j].elevation_fx[k] = 0;
    3111        3125 :                 move32();
    3112        3125 :                 q_direction->band_data[j].elevation_index[k] = 0;
    3113        3125 :                 move16();
    3114             : 
    3115        3125 :                 IF( GT_16( bits_dir0[k], use_vq ) )
    3116             :                 {
    3117        1341 :                     use_vq = bits_dir0[k];
    3118        1341 :                     move16();
    3119             :                 }
    3120             :             }
    3121             : 
    3122        1184 :             test();
    3123        1184 :             IF( LE_16( use_vq, 3 ) && LE_16( allowed_bits, 11 ) )
    3124             :             {
    3125         229 :                 IF( LE_16( allowed_bits, add( no_frames, 1 ) ) )
    3126             :                 {
    3127          77 :                     set32_fx( q_direction->band_data[j].azimuth_fx, 0, no_frames );
    3128         358 :                     FOR( k = 0; k < s_min( allowed_bits, no_frames ); k++ )
    3129             :                     {
    3130         281 :                         q_direction->band_data[j].azimuth_fx[k] = L_shl( L_mult0( -180, bitstream[bit_pos] ), Q22 ); /*Q22*/
    3131         281 :                         move32();
    3132         281 :                         bit_pos = sub( bit_pos, 1 );
    3133         281 :                         nbits = add( nbits, 1 );
    3134             :                     }
    3135             :                 }
    3136             :                 ELSE
    3137             :                 {
    3138         152 :                     nbits = add( nbits, read_truncGR_azimuth_fx( bitstream, q_direction, j, no_frames, &bit_pos ) ); /*Q0*/
    3139             :                 }
    3140             :             }
    3141             :             ELSE
    3142             :             {
    3143        3398 :                 FOR( k = 0; k < no_frames; k++ )
    3144             :                 {
    3145        2443 :                     Buffer = 0;
    3146        2443 :                     move16();
    3147       13883 :                     FOR( i = 0; i < bits_dir0[k]; i++ )
    3148             :                     {
    3149       11440 :                         Buffer = (UWord16) L_add( L_shl( Buffer, 1 ), bitstream[bit_pos] ); /*Q0*/
    3150       11440 :                         bit_pos = sub( bit_pos, 1 );
    3151             :                     }
    3152             : 
    3153        2443 :                     nbits = add( nbits, bits_dir0[k] );
    3154             : 
    3155        2443 :                     IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
    3156             :                     {
    3157        1286 :                         q_direction->band_data[j].azimuth_fx[k] = L_sub( W_extract_l( W_mult0_32_32( L_shl( 360, sub( Q22, bits_dir0[k] ) ), Buffer ) ), L_shl( 180, Q22 ) ); /*Q22*/
    3158        1286 :                         move32();
    3159        2572 :                         q_direction->band_data[j].azimuth_fx[k] = companding_azimuth_fx( q_direction->band_data[j].azimuth_fx[k], q_direction->cfg.mc_ls_setup,
    3160        1286 :                                                                                          (Word16) GT_32( q_direction->band_data[j].elevation_fx[k], L_shl( MC_MASA_THR_ELEVATION, 22 ) ), -1 ); /*Q22*/
    3161        1286 :                         move32();
    3162             :                     }
    3163             :                     ELSE
    3164             :                     {
    3165        1157 :                         q_direction->band_data[j].azimuth_fx[k] = L_sub( W_extract_l( W_mult0_32_32( L_shl( 360, sub( Q22, bits_dir0[k] ) ), Buffer ) ), L_shl( 180, Q22 ) ); /*Q22*/
    3166        1157 :                         move32();
    3167             :                     }
    3168             :                 }
    3169             :             }
    3170             :         }
    3171             :         ELSE
    3172             :         {
    3173           0 :             set_zero_direction_fx( q_direction, j, no_frames );
    3174             :         }
    3175             :     }
    3176         306 :     *pbit_pos = bit_pos;
    3177         306 :     move16();
    3178             : 
    3179         306 :     return nbits;
    3180             : }
    3181             : 
    3182             : /*-------------------------------------------------------------------*
    3183             :  * set_zero_direction()
    3184             :  *
    3185             :  *
    3186             :  *-------------------------------------------------------------------*/
    3187             : 
    3188        3186 : static void set_zero_direction_fx(
    3189             :     IVAS_QDIRECTION *q_direction,
    3190             :     const Word16 idx_band, /*Q0*/
    3191             :     const Word16 len /*Q0*/ )
    3192             : {
    3193             :     Word16 k;
    3194             : 
    3195       15930 :     FOR( k = 0; k < len; k++ )
    3196             :     {
    3197       12744 :         q_direction->band_data[idx_band].azimuth_fx[k] = 0;
    3198       12744 :         move32();
    3199       12744 :         q_direction->band_data[idx_band].azimuth_index[k] = 0;
    3200       12744 :         move16();
    3201       12744 :         q_direction->band_data[idx_band].elevation_fx[k] = 0;
    3202       12744 :         move32();
    3203       12744 :         q_direction->band_data[idx_band].elevation_index[k] = 0;
    3204       12744 :         move16();
    3205       12744 :         q_direction->band_data[idx_band].spherical_index[k] = 0;
    3206       12744 :         move16();
    3207             :     }
    3208             : 
    3209        3186 :     return;
    3210             : }
    3211             : 
    3212             : 
    3213             : /*-------------------------------------------------------------------*
    3214             :  * read_truncGR_azimuth()
    3215             :  *
    3216             :  *
    3217             :  *-------------------------------------------------------------------*/
    3218             : 
    3219        3248 : static Word16 read_truncGR_azimuth_fx(
    3220             :     UWord16 *bitstream,           /* i  : bitstream to be read            Q0*/
    3221             :     IVAS_QDIRECTION *q_direction, /* i/o: quantized metadata structure    */
    3222             :     const Word16 j,               /* i  : subband index                   Q0*/
    3223             :     const Word16 no_subframes,    /* i  : number of tiles                 Q0*/
    3224             :     Word16 *pbit_pos              /* i/o: position in bitstream           Q0*/
    3225             : )
    3226             : {
    3227             :     Word16 i;
    3228             :     Word16 nbits;
    3229             :     UWord16 idx;
    3230             :     Word16 no_symb, allowed_bits;
    3231             : 
    3232        3248 :     allowed_bits = sum16_fx( (Word16 *) q_direction->band_data[j].bits_sph_idx, no_subframes ); /*Q0*/
    3233        3248 :     nbits = 0;
    3234        3248 :     move16();
    3235        3248 :     IF( LE_16( allowed_bits, add( no_subframes, 1 ) ) )
    3236             :     {
    3237           0 :         Word16 len = s_min( allowed_bits, no_subframes );
    3238           0 :         FOR( i = 0; i < len; i++ )
    3239             :         {
    3240           0 :             IF( bitstream[( *pbit_pos )--] == 0 )
    3241             :             {
    3242           0 :                 q_direction->band_data[j].azimuth_fx[i] = 0;
    3243           0 :                 move32();
    3244             :             }
    3245             :             ELSE
    3246             :             {
    3247           0 :                 q_direction->band_data[j].azimuth_fx[i] = ( -180 * ONE_IN_Q22 ); /*Q22*/
    3248           0 :                 move32();
    3249             :             }
    3250           0 :             nbits = add( nbits, 1 );
    3251             :         }
    3252             : 
    3253           0 :         return nbits;
    3254             :     }
    3255             : 
    3256        3248 :     IF( NE_16( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
    3257             :     {
    3258         443 :         no_symb = 9;
    3259         443 :         move16();
    3260             :     }
    3261             :     ELSE
    3262             :     {
    3263        2805 :         no_symb = 8;
    3264        2805 :         move16();
    3265             :     }
    3266        3248 :     nbits = 0;
    3267        3248 :     move16();
    3268             : 
    3269        3248 :     nbits = *pbit_pos;
    3270        3248 :     move16();
    3271             : 
    3272       16033 :     FOR( i = 0; i < no_subframes; i++ )
    3273             :     {
    3274       12785 :         idx = ivas_qmetadata_DecodeExtendedGR( bitstream, pbit_pos, no_symb, 0 );
    3275       12785 :         q_direction->band_data[j].azimuth_index[i] = idx; /*Q0*/
    3276       12785 :         move16();
    3277       12785 :         IF( NE_16( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) )
    3278             :         {
    3279        1760 :             q_direction->band_data[j].azimuth_fx[i] = cb_azi_chan_fx[(UWord16) ( (UWord16) ( idx + 1 ) / 2 )]; /*Q22*/
    3280        1760 :             move32();
    3281        1760 :             IF( L_and( idx, 1 ) > 0 )
    3282             :             {
    3283         695 :                 q_direction->band_data[j].azimuth_fx[i] = L_negate( q_direction->band_data[j].azimuth_fx[i] ); /*Q22*/
    3284         695 :                 move32();
    3285             :             }
    3286             :         }
    3287             :         ELSE
    3288             :         {
    3289       11025 :             q_direction->band_data[j].azimuth_fx[i] = azimuth_cb_fx[idx]; /*Q22*/
    3290       11025 :             move32();
    3291             :         }
    3292             :     }
    3293             : 
    3294        3248 :     nbits = sub( nbits, *pbit_pos );
    3295             : 
    3296        3248 :     return nbits;
    3297             : }
    3298             : 
    3299             : /*-------------------------------------------------------------------*
    3300             :  * read_common_direction()
    3301             :  *
    3302             :  *
    3303             :  *-------------------------------------------------------------------*/
    3304             : 
    3305             : /*! r: number of bits read */
    3306        3186 : static Word16 read_common_direction_fx(
    3307             :     UWord16 *bitstream,           /* i  : bitstream to be read                        Q0*/
    3308             :     IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure               */
    3309             :     const Word16 j,               /* i  : subband index                               Q0*/
    3310             :     const Word16 no_subframes,    /* i  : number of tiles                             Q0*/
    3311             :     const Word16 bits_total,      /* i  : number of bits for subband directional data Q0*/
    3312             :     Word16 *pbit_pos              /* i/o: position in bitstream                       Q0*/
    3313             : )
    3314             : {
    3315             :     Word16 nbits;
    3316             :     Word16 bit_pos;
    3317             :     Word16 i;
    3318             :     UWord16 byteBuffer;
    3319             :     Word16 bits_el;
    3320             : 
    3321        3186 :     bit_pos = *pbit_pos;
    3322        3186 :     move16();
    3323        3186 :     nbits = 0;
    3324        3186 :     move16();
    3325             : 
    3326        3186 :     set_zero_direction_fx( q_direction, j, no_subframes );
    3327        3186 :     IF( !bits_total )
    3328             :     {
    3329           0 :         return nbits;
    3330             :     }
    3331             : 
    3332        3186 :     IF( LE_16( bits_total, add( no_subframes, 1 ) ) )
    3333             :     {
    3334         330 :         FOR( i = 0; i < s_min( no_subframes, bits_total ); i++ )
    3335             :         {
    3336         264 :             byteBuffer = bitstream[bit_pos--]; /*Q0*/
    3337         264 :             move16();
    3338             :             /*qdirection->azimuth_index[j][i] = (uint16_t)byteBuffer; */
    3339         264 :             q_direction->band_data[j].azimuth_fx[i] = azimuth_cb_fx[byteBuffer]; /*Q22*/
    3340         264 :             move32();
    3341         264 :             nbits = add( nbits, 1 );
    3342             :         }
    3343          66 :         *pbit_pos = bit_pos;
    3344          66 :         move16();
    3345             : 
    3346             :         /*nbits += read_truncGR_azimuth(bitstream, qdirection, j, no_subframes, pbit_pos); */
    3347          66 :         return nbits;
    3348             :     }
    3349             : 
    3350             : 
    3351        3120 :     byteBuffer = bitstream[bit_pos]; /*Q0*/
    3352        3120 :     move16();
    3353        3120 :     bit_pos = sub( bit_pos, 1 );
    3354        3120 :     bits_el = 1;
    3355        3120 :     move16();
    3356        3120 :     nbits = add( nbits, 1 );
    3357             :     /* elevation is already set to 0*/
    3358        3120 :     IF( EQ_32( byteBuffer, 1 ) )
    3359             :     {
    3360         938 :         byteBuffer = bitstream[bit_pos--]; /*Q0*/
    3361         938 :         move16();
    3362         938 :         bits_el = add( bits_el, 1 );
    3363         938 :         nbits = add( nbits, 1 );
    3364         938 :         IF( byteBuffer == 0 )
    3365             :         {
    3366        2795 :             FOR( i = 0; i < no_subframes; i++ )
    3367             :             {
    3368        2236 :                 q_direction->band_data[j].elevation_fx[i] = delta_theta_masa_fx[2]; /*Q22*/
    3369        2236 :                 move32();
    3370             :             }
    3371             :         }
    3372             :         ELSE
    3373             :         {
    3374         379 :             byteBuffer = bitstream[bit_pos--];
    3375         379 :             move16();
    3376         379 :             bits_el = add( bits_el, 1 );
    3377         379 :             nbits = add( nbits, 1 );
    3378         379 :             IF( byteBuffer == 0 )
    3379             :             {
    3380        1860 :                 FOR( i = 0; i < no_subframes; i++ )
    3381             :                 {
    3382        1488 :                     q_direction->band_data[j].elevation_fx[i] = L_negate( delta_theta_masa_fx[2] ); /*Q22*/
    3383        1488 :                     move32();
    3384             :                 }
    3385             :             }
    3386             :             ELSE
    3387             :             {
    3388             :                 /* theta is +/- 90; no azimuth is read */
    3389           7 :                 byteBuffer = bitstream[bit_pos--];
    3390           7 :                 move16();
    3391           7 :                 nbits = add( nbits, 1 );
    3392           7 :                 IF( byteBuffer == 0 )
    3393             :                 {
    3394           6 :                     set32_fx( q_direction->band_data[j].elevation_fx, ( 90 * ONE_IN_Q22 ), no_subframes ); /*Q22*/
    3395           6 :                     set32_fx( q_direction->band_data[j].azimuth_fx, 0, no_subframes );                     /*Q22*/
    3396             :                 }
    3397             :                 ELSE
    3398             :                 {
    3399           1 :                     set32_fx( q_direction->band_data[j].elevation_fx, ( -90 * ONE_IN_Q22 ), no_subframes ); /*Q22*/
    3400           1 :                     set32_fx( q_direction->band_data[j].azimuth_fx, 0, no_subframes );                      /*Q22*/
    3401             :                 }
    3402           7 :                 *pbit_pos = bit_pos;
    3403           7 :                 move16();
    3404             : 
    3405           7 :                 return nbits;
    3406             :             }
    3407             :         }
    3408             :     }
    3409             : 
    3410        3113 :     bits_el = sub( sum16_fx( (Word16 *) q_direction->band_data[j].bits_sph_idx, no_subframes ), bits_el ); /*Q0*/
    3411             : 
    3412        3113 :     IF( LE_16( bits_el, add( no_subframes, 1 ) ) )
    3413             :     {
    3414          17 :         nbits = add( nbits, s_min( no_subframes, bits_el ) );
    3415          84 :         FOR( i = 0; i < s_min( no_subframes, bits_el ); i++ )
    3416             :         {
    3417          67 :             byteBuffer = bitstream[bit_pos]; /*Q0*/
    3418          67 :             move16();
    3419          67 :             bit_pos = sub( bit_pos, 1 );
    3420             :             /*qdirection->azimuth_index[j][i] = (uint16_t) byteBuffer; */
    3421          67 :             q_direction->band_data[j].azimuth_fx[i] = azimuth_cb_fx[byteBuffer]; /*Q22*/
    3422          67 :             move32();
    3423             :         }
    3424             :     }
    3425             :     ELSE
    3426             :     {
    3427        3096 :         nbits = add( nbits, read_truncGR_azimuth_fx( bitstream, q_direction, j, no_subframes, &bit_pos ) );
    3428             :     }
    3429             : 
    3430        3113 :     *pbit_pos = bit_pos;
    3431        3113 :     move16();
    3432             : 
    3433        3113 :     return nbits;
    3434             : }
    3435             : 
    3436             : /*-----------------------------------------------------------------------*
    3437             :  * Local functions: coherence
    3438             :  *-----------------------------------------------------------------------*/
    3439             : 
    3440       20277 : static void decode_spread_coherence_fx(
    3441             :     IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: quantized metadata structure              */
    3442             :     Word16 idx_d,                     /* i  : direction index                           Q0*/
    3443             :     const Word16 no_frames,           /* i  : number of time subframes                  Q0*/
    3444             :     const Word16 hrmasa_flag          /* i  : flag indicating high-rate MASA MD coding  Q0*/
    3445             : )
    3446             : {
    3447             :     Word16 i, j;
    3448             :     Word64 var_azi_fx;
    3449             :     Word16 idx_sub_cb;
    3450             :     Word32 dct_coh_fx[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES];
    3451             :     Word16 MASA_grouping[MASA_MAXIMUM_CODING_SUBBANDS];
    3452             :     IVAS_QDIRECTION *q_direction;
    3453             :     Word16 coding_subbands, coding_subbands_0, d, two_dir_band[MASA_MAXIMUM_CODING_SUBBANDS];
    3454             :     Word16 min_index;
    3455             : 
    3456       20277 :     coding_subbands_0 = hQMetaData->q_direction[0].cfg.nbands;
    3457       20277 :     move16();
    3458       20277 :     coding_subbands = hQMetaData->q_direction[idx_d].cfg.nbands;
    3459       20277 :     move16();
    3460       20277 :     IF( LE_16( coding_subbands_0, 5 ) )
    3461             :     {
    3462       87090 :         FOR( j = 0; j < 5; j++ )
    3463             :         {
    3464       72575 :             MASA_grouping[j] = j;
    3465       72575 :             move16();
    3466             :         }
    3467             :     }
    3468             :     ELSE
    3469             :     {
    3470        5762 :         IF( LE_16( coding_subbands_0, 8 ) )
    3471             :         {
    3472        2497 :             Copy( MASA_grouping_8_to_5, MASA_grouping, 8 ); /*Q0*/
    3473             :         }
    3474        3265 :         ELSE IF( LE_16( coding_subbands_0, 12 ) )
    3475             :         {
    3476        1481 :             Copy( MASA_grouping_12_to_5, MASA_grouping, 12 ); /*Q0*/
    3477             :         }
    3478        1784 :         ELSE IF( LE_16( coding_subbands_0, 18 ) )
    3479             :         {
    3480         913 :             Copy( MASA_grouping_18_to_5, MASA_grouping, 18 ); /*Q0*/
    3481             :         }
    3482             :         ELSE
    3483             :         {
    3484         871 :             IF( LE_16( coding_subbands_0, 24 ) )
    3485             :             {
    3486         871 :                 Copy( MASA_grouping_24_to_5, MASA_grouping, 24 ); /*Q0*/
    3487             :             }
    3488             :         }
    3489             :     }
    3490             : 
    3491       20277 :     IF( LT_16( coding_subbands, coding_subbands_0 ) )
    3492             :     {
    3493        3177 :         d = 0;
    3494        3177 :         move16();
    3495       25710 :         FOR( j = 0; j < coding_subbands_0; j++ )
    3496             :         {
    3497       22533 :             IF( EQ_16( hQMetaData->twoDirBands[j], 1 ) )
    3498             :             {
    3499        9117 :                 two_dir_band[d] = j;
    3500        9117 :                 move16();
    3501        9117 :                 d = add( d, 1 );
    3502             :             }
    3503             :         }
    3504             :     }
    3505             :     ELSE
    3506             :     {
    3507       17100 :         set16_fx( two_dir_band, 0, coding_subbands );
    3508             :     }
    3509             : 
    3510       20277 :     q_direction = &hQMetaData->q_direction[idx_d];
    3511             : 
    3512      149498 :     FOR( i = 0; i < coding_subbands; i++ )
    3513             :     {
    3514      129221 :         var_azi_fx = var_32_fx( q_direction->band_data[i].azimuth_fx, no_frames, 22 ); /*Q22*/
    3515      129221 :         IF( hrmasa_flag )
    3516             :         {
    3517           0 :             minimum_s( (Word16 *) ( q_direction->band_data[i].energy_ratio_index ), q_direction->cfg.nblocks, &min_index );
    3518           0 :             min_index = shr( min_index, 1 );
    3519             :         }
    3520             :         ELSE
    3521             :         {
    3522      129221 :             min_index = q_direction->band_data[i].energy_ratio_index[0]; /*Q0*/
    3523      129221 :             move16();
    3524             :         }
    3525             : 
    3526      129221 :         IF( LT_64( var_azi_fx, L_shl( MASA_DELTA_AZI_DCT0, 22 ) ) )
    3527             :         {
    3528       30599 :             idx_sub_cb = i_mult( MASA_NO_CV_COH, min_index ); /*Q0*/
    3529             :         }
    3530             :         ELSE
    3531             :         {
    3532       98622 :             idx_sub_cb = i_mult( MASA_NO_CV_COH, add( min_index, DIRAC_DIFFUSE_LEVELS ) ); /* NO_CV_COH = 8 */
    3533             :         }
    3534             : 
    3535      129221 :         dct_coh_fx[i][0] = coherence_cb0_masa_fx[idx_sub_cb + q_direction->coherence_band_data[i].spread_coherence_dct0_index];
    3536      129221 :         move32();
    3537             : 
    3538      129221 :         IF( LT_16( coding_subbands, coding_subbands_0 ) )
    3539             :         {
    3540        9117 :             assert( EQ_16( idx_d, 1 ) );
    3541        9117 :             dct_coh_fx[i][1] = coherence_cb1_masa_fx[( ( MASA_grouping[two_dir_band[i]] * MASA_NO_CV_COH1 ) + q_direction->coherence_band_data[i].spread_coherence_dct1_index )]; /*Q21*/
    3542        9117 :             move32();
    3543             :         }
    3544             :         ELSE
    3545             :         {
    3546      120104 :             dct_coh_fx[i][1] = coherence_cb1_masa_fx[( ( MASA_grouping[i] * MASA_NO_CV_COH1 ) + q_direction->coherence_band_data[i].spread_coherence_dct1_index )]; /*Q21*/
    3547      120104 :             move32();
    3548             :         }
    3549             : 
    3550      387663 :         FOR( j = 2; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
    3551             :         {
    3552      258442 :             dct_coh_fx[i][j] = 0;
    3553      258442 :             move32();
    3554             :         }
    3555             : 
    3556      129221 :         invdct4_transform_fx( dct_coh_fx[i], q_direction->coherence_band_data[i].spread_coherence, 21 );
    3557             :     }
    3558             : 
    3559       20277 :     return;
    3560             : }
    3561             : 
    3562             : /*-------------------------------------------------------------------*
    3563             :  * read_huf()
    3564             :  *
    3565             :  * Read Hufman code
    3566             :  *-------------------------------------------------------------------*/
    3567             : 
    3568             : /*! r: number of bits read */
    3569       20277 : static ivas_error read_huf(
    3570             :     Word16 *num_bits_read,    /*Q0*/
    3571             :     const UWord16 *bitstream, /* i  : bitstream to be read            Q0*/
    3572             :     UWord16 *out,             /* o  : decoded value                   Q0*/
    3573             :     const Word16 start_pos,   /* i  : starting position for reading   Q0*/
    3574             :     const Word16 len,         /* i  : number of codewords             Q0*/
    3575             :     const Word16 *huff_code,  /* i  : Huffman table                   Q0*/
    3576             :     const Word16 max_len      /* i  : maximum codeword length         Q0*/
    3577             : )
    3578             : {
    3579       20277 :     Word16 done = 0, end_pos;
    3580       20277 :     move16();
    3581             :     UWord16 ByteBuffer;
    3582             :     Word16 nbits, val;
    3583             :     UWord16 i;
    3584             : 
    3585       20277 :     end_pos = start_pos;
    3586       20277 :     move16();
    3587       20277 :     nbits = 0;
    3588       20277 :     move16();
    3589       20277 :     val = 0;
    3590       20277 :     move16();
    3591      100079 :     WHILE( !done && LT_16( nbits, max_len ) )
    3592             :     {
    3593       79802 :         ByteBuffer = bitstream[end_pos--]; /*Q0*/
    3594       79802 :         move16();
    3595       79802 :         val = add( shl( val, 1 ), ByteBuffer & 1 ); /*Q0*/
    3596       79802 :         nbits = add( nbits, 1 );
    3597      378307 :         FOR( i = 0; i < len; i++ )
    3598             :         {
    3599      318782 :             IF( EQ_16( val, huff_code[i] ) )
    3600             :             {
    3601       20277 :                 *out = i;
    3602       20277 :                 move16();
    3603       20277 :                 done = 1;
    3604       20277 :                 move16();
    3605       20277 :                 BREAK;
    3606             :             }
    3607             :         }
    3608             :     }
    3609             : 
    3610       20277 :     *num_bits_read = end_pos;
    3611       20277 :     move16();
    3612             : 
    3613       20277 :     return IVAS_ERR_OK;
    3614             : }
    3615             : 
    3616             : 
    3617             : /*-------------------------------------------------------------------*
    3618             :  * read_GR_min_removed_data()
    3619             :  *
    3620             :  *
    3621             :  *-------------------------------------------------------------------*/
    3622        2360 : static Word16 read_GR_min_removed_data(
    3623             :     UWord16 *bitstream,      /* i  : bitstream                       Q0*/
    3624             :     Word16 *p_bit_pos,       /* i  : position in the bitstream       Q0*/
    3625             :     const Word16 *no_cv_vec, /*Q0*/
    3626             :     const Word16 no_data,    /*Q0*/
    3627             :     Word16 *decoded_idx,     /*Q0*/
    3628             :     const Word16 no_symb /*Q0*/ )
    3629             : {
    3630             :     Word16 j;
    3631             :     Word16 bit_pos;
    3632             :     Word16 nbits, bits_GR;
    3633             :     UWord16 byteBuffer;
    3634             :     Word16 min_index;
    3635             : 
    3636        2360 :     bit_pos = *p_bit_pos;
    3637        2360 :     move16();
    3638             : 
    3639             :     /* read GR order */
    3640        2360 :     byteBuffer = bitstream[bit_pos]; /*Q0*/
    3641        2360 :     move16();
    3642        2360 :     bit_pos = sub( bit_pos, 1 );
    3643        2360 :     nbits = 1;
    3644        2360 :     move16();
    3645             : 
    3646             :     /* read min index */
    3647        2360 :     bits_GR = bit_pos;
    3648        2360 :     move16();
    3649        2360 :     min_index = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, no_symb, 0 ); /*Q0*/
    3650        2360 :     nbits = add( nbits, sub( bits_GR, bit_pos ) );
    3651             : 
    3652             :     /* read GR data */
    3653       33563 :     FOR( j = 0; j < no_data; j++ )
    3654             :     {
    3655       31203 :         bits_GR = bit_pos;
    3656       31203 :         move16();
    3657       31203 :         IF( GT_16( no_cv_vec[j], 1 ) )
    3658             :         {
    3659       30897 :             decoded_idx[j] = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, sub( no_cv_vec[j], min_index ), extract_l( L_and( byteBuffer, 1 ) ) ); /*Q0*/
    3660       30897 :             move16();
    3661       30897 :             nbits = add( nbits, sub( bits_GR, bit_pos ) );
    3662             :         }
    3663             :         ELSE
    3664             :         {
    3665         306 :             decoded_idx[j] = 0;
    3666         306 :             move16();
    3667             :         }
    3668             :     }
    3669             : 
    3670       33563 :     FOR( j = 0; j < no_data; j++ ){
    3671       31203 :         IF( GT_16( no_cv_vec[j], 1 ) ){
    3672       30897 :             decoded_idx[j] = add( decoded_idx[j], min_index );
    3673       30897 :     move16();
    3674             : }
    3675             : }
    3676             : 
    3677        2360 : *p_bit_pos = bit_pos;
    3678        2360 : move16();
    3679             : 
    3680        2360 : return nbits;
    3681             : }
    3682             : 
    3683             : 
    3684             : /*-------------------------------------------------------------------*
    3685             :  * decode_fixed_rate_composed_index_coherence()
    3686             :  *
    3687             :  *
    3688             :  *-------------------------------------------------------------------*/
    3689             : 
    3690        9971 : static Word16 decode_fixed_rate_composed_index_coherence_fx(
    3691             :     UWord16 *bitstream,     /* i  : bitstream                       Q0*/
    3692             :     Word16 *p_bit_pos,      /* i  : position in the bitstream       Q0*/
    3693             :     const Word16 no_bands,  /*Q0*/
    3694             :     Word16 *no_cv_vec,      /*Q0*/
    3695             :     UWord16 *decoded_index, /*Q0*/
    3696             :     const Word16 no_symb /*Q0*/ )
    3697             : {
    3698             :     /* fixed rate */
    3699             :     UWord64 no_cb;
    3700             :     UWord16 temp_index[MASA_MAXIMUM_CODING_SUBBANDS];
    3701             :     UWord64 idx_fr;
    3702             :     Word16 no_bits_vec1, half_no_bands;
    3703             :     Word16 bit_pos;
    3704             :     Word16 nbits, bits_GR;
    3705             :     Word16 j;
    3706             :     Word16 no_vals_local;
    3707             :     Word16 no_bits_vec;
    3708             : 
    3709        9971 :     bit_pos = *p_bit_pos;
    3710        9971 :     move16();
    3711        9971 :     set16_fx( (Word16 *) temp_index, 0, MASA_MAXIMUM_CODING_SUBBANDS );
    3712             : 
    3713        9971 :     no_cb = 1;
    3714        9971 :     move64();
    3715        9971 :     nbits = 0;
    3716        9971 :     move16();
    3717        9971 :     IF( GT_16( no_bands, MASA_LIMIT_NO_BANDS_SUR_COH ) )
    3718             :     {
    3719             :         /* read 8-max_val with GR0 */
    3720         655 :         bits_GR = bit_pos;
    3721         655 :         move16();
    3722         655 :         no_vals_local = sub( no_symb, ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, no_symb, 0 ) );
    3723         655 :         nbits = add( nbits, sub( bits_GR, bit_pos ) );
    3724       12124 :         FOR( j = 0; j < no_bands; j++ )
    3725             :         {
    3726       11469 :             IF( GT_16( no_cv_vec[j], no_vals_local ) )
    3727             :             {
    3728       10293 :                 no_cv_vec[j] = no_vals_local; /*Q0*/
    3729       10293 :                 move16();
    3730             :             }
    3731             :         }
    3732             :     }
    3733             : 
    3734        9971 :     half_no_bands = shr( no_bands, 1 ); /* no_bands / 2 */
    3735        9971 :     IF( GT_16( sum16_fx( no_cv_vec, no_bands ), MASA_COH_LIMIT_2IDX ) )
    3736             :     {
    3737         124 :         no_cb = 1;
    3738         124 :         move64();
    3739             : 
    3740        1502 :         FOR( j = 0; j < half_no_bands; j++ )
    3741             :         {
    3742        1378 :             no_cb *= no_cv_vec[j]; /*Q0*/
    3743        1378 :             move16();
    3744             :         }
    3745         124 :         no_bits_vec = (Word16) ceil_log_2( no_cb );
    3746         124 :         no_cb = 1;
    3747         124 :         move64();
    3748        1522 :         FOR( j = half_no_bands; j < no_bands; j++ )
    3749             :         {
    3750        1398 :             no_cb *= no_cv_vec[j]; /*Q0*/
    3751        1398 :             move16();
    3752             :         }
    3753         124 :         no_bits_vec1 = (Word16) ceil_log_2( no_cb );
    3754             :     }
    3755             :     ELSE
    3756             :     {
    3757        9847 :         no_cb = 1;
    3758        9847 :         move64();
    3759       59580 :         FOR( j = 0; j < no_bands; j++ )
    3760             :         {
    3761       49733 :             no_cb *= no_cv_vec[j]; /*Q0*/
    3762       49733 :             move16();
    3763             :         }
    3764        9847 :         no_bits_vec = (Word16) ceil_log_2( no_cb );
    3765        9847 :         no_bits_vec1 = 0;
    3766        9847 :         move16();
    3767             :     }
    3768        9971 :     IF( no_bits_vec1 > 0 )
    3769             :     {
    3770         124 :         idx_fr = 0;
    3771         124 :         move64();
    3772        3796 :         FOR( j = 0; j < no_bits_vec; j++ )
    3773             :         {
    3774        3672 :             idx_fr = ( idx_fr << 1 ) + bitstream[bit_pos]; /*Q0*/
    3775        3672 :             bit_pos = sub( bit_pos, 1 );
    3776        3672 :             move64();
    3777             :         }
    3778             : 
    3779         124 :         nbits = add( nbits, no_bits_vec );
    3780             : 
    3781         124 :         decode_combined_index_fx( idx_fr, no_cv_vec, temp_index, half_no_bands );
    3782             : 
    3783         124 :         idx_fr = 0;
    3784         124 :         move64();
    3785        3944 :         FOR( j = 0; j < no_bits_vec1; j++ )
    3786             :         {
    3787        3820 :             idx_fr = ( idx_fr << 1 ) + bitstream[bit_pos]; /*Q0*/
    3788        3820 :             bit_pos = sub( bit_pos, 1 );
    3789        3820 :             move64();
    3790             :         }
    3791         124 :         nbits = add( nbits, no_bits_vec1 );
    3792         124 :         decode_combined_index_fx( idx_fr, &no_cv_vec[half_no_bands], &temp_index[half_no_bands], half_no_bands );
    3793             :     }
    3794             :     ELSE
    3795             :     {
    3796        9847 :         idx_fr = 0;
    3797        9847 :         move64();
    3798       88665 :         FOR( j = 0; j < no_bits_vec; j++ )
    3799             :         {
    3800       78818 :             idx_fr = ( idx_fr << 1 ) + bitstream[bit_pos]; /*Q0*/
    3801       78818 :             bit_pos = sub( bit_pos, 1 );
    3802       78818 :             move64();
    3803             :         }
    3804        9847 :         nbits = add( nbits, no_bits_vec );
    3805        9847 :         decode_combined_index_fx( idx_fr, no_cv_vec, temp_index, no_bands );
    3806             :     }
    3807             : 
    3808       62480 :     FOR( j = 0; j < no_bands; j++ )
    3809             :     {
    3810       52509 :         decoded_index[j] = temp_index[j]; /*Q0*/
    3811       52509 :         move16();
    3812             :     }
    3813        9971 :     nbits = sub( *p_bit_pos, bit_pos );
    3814             : 
    3815        9971 :     *p_bit_pos = bit_pos; /*Q0*/
    3816        9971 :     move16();
    3817             : 
    3818        9971 :     return nbits;
    3819             : }
    3820             : 
    3821             : /*-------------------------------------------------------------------*
    3822             :  * read_coherence_data_hr_512()
    3823             :  *
    3824             :  * Read coherence data at HR
    3825             :  *-------------------------------------------------------------------*/
    3826             : 
    3827             : /*! r: number of bits read */
    3828        3485 : static Word16 read_coherence_data_hr_512_fx(
    3829             :     UWord16 *bitstream,         /* i  : bitstream                       Q0*/
    3830             :     Word16 *p_bit_pos,          /* i  : position in the bitstream       Q0*/
    3831             :     IVAS_QMETADATA *hQMetaData, /* i/o: quantized metadata structure    */
    3832             :     const Word16 idx_dir,       /* i  : direction index                 Q0*/
    3833             :     const Word16 nbits_coh /*Q0*/ )
    3834             : {
    3835             :     Word16 j, k, i;
    3836             :     Word16 nbands, nblocks;
    3837             :     Word16 min_index, GR_param;
    3838             :     Word16 cb_size, nbits;
    3839             :     Word16 decoded_idx;
    3840             :     Word32 delta_fx, decoded_idx_fx; // q = 22, q = 9
    3841             : 
    3842        3485 :     nbands = hQMetaData->q_direction[idx_dir].cfg.nbands;
    3843        3485 :     move16();
    3844        3485 :     nblocks = hQMetaData->q_direction[idx_dir].cfg.nblocks;
    3845        3485 :     move16();
    3846             : 
    3847        3485 :     cb_size = shl( 1, nbits_coh );
    3848        3485 :     delta_fx = L_shl( 256, sub( 22, nbits_coh ) );
    3849        3485 :     nbits = *p_bit_pos;
    3850        3485 :     move16();
    3851       16549 :     FOR( k = 0; k < nblocks; k++ )
    3852             :     {
    3853             :         /* read method */
    3854       13064 :         IF( EQ_32( bitstream[( *p_bit_pos )--], 1 ) )
    3855             :         {
    3856             :             /* average removed */
    3857             :             /* read average index */
    3858         141 :             min_index = 0;
    3859         141 :             move16();
    3860         586 :             FOR( i = 0; i < nbits_coh; i++ )
    3861             :             {
    3862         445 :                 min_index = add( shl( min_index, 1 ), bitstream[( *p_bit_pos )] ); /*Q0*/
    3863         445 :                 ( *p_bit_pos ) = sub( ( *p_bit_pos ), 1 );
    3864         445 :                 move16();
    3865             :             }
    3866             :             /* read GR param */
    3867         141 :             GR_param = bitstream[( *p_bit_pos )]; /*Q0*/
    3868         141 :             move16();
    3869         141 :             ( *p_bit_pos ) = sub( ( *p_bit_pos ), 1 );
    3870         141 :             move16();
    3871        1938 :             FOR( j = 0; j < nbands; j++ )
    3872             :             {
    3873        1797 :                 decoded_idx = ivas_qmetadata_DecodeExtendedGR( bitstream, p_bit_pos, shl( cb_size, 1 ), GR_param ); /*Q0*/
    3874        1797 :                 IF( EQ_16( s_and( decoded_idx, 1 ), 1 ) )
    3875             :                 {
    3876         763 :                     decoded_idx = add( shr( add( decoded_idx, 1 ), 1 ), min_index );
    3877             :                 }
    3878             :                 ELSE
    3879             :                 {
    3880        1034 :                     decoded_idx = add( negate( shr( decoded_idx, 1 ) ), min_index );
    3881             :                 }
    3882        1797 :                 decoded_idx_fx = L_shl( decoded_idx, 9 );
    3883        1797 :                 hQMetaData->q_direction[idx_dir].coherence_band_data[j].spread_coherence[k] = (UWord8) L_add( Mpy_32_32( decoded_idx_fx, delta_fx ), L_shr( delta_fx, 23 ) ); /*Q0*/
    3884        1797 :                 move16();
    3885             :             }
    3886             :         }
    3887             :         ELSE
    3888             :         {
    3889             :             /* read min_index */
    3890       12923 :             min_index = 0;
    3891       12923 :             move16();
    3892       56338 :             FOR( i = 0; i < nbits_coh; i++ )
    3893             :             {
    3894       43415 :                 min_index = add( shl( min_index, 1 ), bitstream[( *p_bit_pos )] ); /*Q0*/
    3895       43415 :                 ( *p_bit_pos ) = sub( ( *p_bit_pos ), 1 );
    3896       43415 :                 move16();
    3897             :             }
    3898             : 
    3899             :             /* read GR param */
    3900       12923 :             GR_param = bitstream[( *p_bit_pos )]; /*Q0*/
    3901       12923 :             move16();
    3902       12923 :             ( *p_bit_pos ) = sub( ( *p_bit_pos ), 1 );
    3903       12923 :             move16();
    3904      279108 :             FOR( j = 0; j < nbands; j++ )
    3905             :             {
    3906      266185 :                 decoded_idx = add( ivas_qmetadata_DecodeExtendedGR( bitstream, p_bit_pos, cb_size - min_index, GR_param ), min_index );                                       /*Q0*/
    3907      266185 :                 decoded_idx_fx = L_shl( decoded_idx, 9 );                                                                                                                     /*Q9*/
    3908      266185 :                 hQMetaData->q_direction[idx_dir].coherence_band_data[j].spread_coherence[k] = (UWord8) L_add( Mpy_32_32( decoded_idx_fx, delta_fx ), L_shr( delta_fx, 23 ) ); /*Q0*/
    3909      266185 :                 move16();
    3910             :             }
    3911             :         }
    3912             :     }
    3913             : 
    3914        3485 :     nbits = sub( nbits, *p_bit_pos );
    3915             : 
    3916        3485 :     return nbits;
    3917             : }
    3918             : 
    3919             : /*------------------------------------------------------------------- *
    3920             :  * read_coherence_data()
    3921             :  *
    3922             :  * Read coherence data
    3923             :  *------------------------------------------------------------------- */
    3924             : 
    3925             : /*! r: number of bits read */
    3926       28286 : static Word16 read_coherence_data_fx(
    3927             :     UWord16 *bitstream,         /* i  : bitstream                               Q0*/
    3928             :     Word16 *p_bit_pos,          /* i  : position in the bitstream               Q0*/
    3929             :     IVAS_QMETADATA *hQMetaData, /* i/o: quantized metadata structure            */
    3930             :     const Word16 idx_dir,       /* i  : direction index                         Q0*/
    3931             :     const Word16 hrmasa_flag    /* i  : flag indicating high-rate MASA MD coding Q0*/
    3932             : )
    3933             : {
    3934             :     Word16 j;
    3935             :     Word16 no_cv_vec[MASA_MAXIMUM_CODING_SUBBANDS];
    3936             :     UWord64 no_cb;
    3937             :     Word16 no_bits_vec, nbits;
    3938             :     Word16 bits_GR;
    3939             :     UWord16 idx_dct1[MASA_MAXIMUM_CODING_SUBBANDS];
    3940             :     UWord16 av_index;
    3941             :     Word16 no_bits_vec1;
    3942             :     Word16 bit_pos;
    3943             :     IVAS_QDIRECTION *q_direction;
    3944             :     Word16 coding_subbands;
    3945             :     UWord64 dct0_index;
    3946             :     Word16 decoded_idx[MASA_MAXIMUM_CODING_SUBBANDS];
    3947             :     UWord16 byteBuffer;
    3948             :     Word16 idx_ER;
    3949             :     Word16 min_index;
    3950             :     Word16 extra_cv;
    3951             :     Word16 num, den, q_num, q_den, q_res;
    3952             :     Word32 res;
    3953             : 
    3954       28286 :     coding_subbands = hQMetaData->q_direction[idx_dir].cfg.nbands;
    3955       28286 :     move16();
    3956       28286 :     extra_cv = idiv1616( coding_subbands, MASA_FACTOR_CV_COH ); /*Q0*/
    3957       28286 :     move16();
    3958       28286 :     q_direction = &( hQMetaData->q_direction[idx_dir] );
    3959       28286 :     bit_pos = *p_bit_pos;
    3960       28286 :     move16();
    3961       28286 :     nbits = 0;
    3962       28286 :     move16();
    3963             : 
    3964       28286 :     IF( EQ_16( q_direction->cfg.nblocks, 1 ) )
    3965             :     {
    3966       68424 :         FOR( j = 0; j < coding_subbands; j++ )
    3967             :         {
    3968       60415 :             IF( hrmasa_flag )
    3969             :             {
    3970           0 :                 idx_ER = extract_l( L_add( L_sub( 7, L_shr( q_direction->band_data[j].energy_ratio_index_mod[0], 1 ) ), extra_cv ) ); /*Q0*/
    3971             :             }
    3972             :             ELSE
    3973             :             {
    3974       60415 :                 idx_ER = extract_l( L_add( L_sub( 7, q_direction->band_data[j].energy_ratio_index_mod[0] ), extra_cv ) ); /*Q0*/
    3975             :             }
    3976       60415 :             no_cv_vec[j] = add( idx_ER, 1 );
    3977       60415 :             move16();
    3978             :         }
    3979             : 
    3980        8009 :         IF( EQ_16( sum16_fx( no_cv_vec, coding_subbands ), coding_subbands ) )
    3981             :         {
    3982        4845 :             FOR( j = 0; j < coding_subbands; j++ )
    3983             :             {
    3984        3988 :                 q_direction->coherence_band_data[j].spread_coherence[0] = 0;
    3985             :             }
    3986             : 
    3987         857 :             return 0;
    3988             :         }
    3989        7152 :         byteBuffer = bitstream[bit_pos]; /*Q0*/
    3990        7152 :         move16();
    3991        7152 :         bit_pos = sub( bit_pos, 1 );
    3992        7152 :         nbits = add( nbits, 1 );
    3993             : 
    3994        7152 :         IF( L_and( byteBuffer, 1 ) )
    3995             :         {
    3996             :             /* decode GR min removed */
    3997        2360 :             nbits = add( nbits, read_GR_min_removed_data( bitstream, &bit_pos, no_cv_vec, coding_subbands, decoded_idx, MASA_MAX_NO_CV_SUR_COH + extra_cv ) ); /*Q0*/
    3998       33563 :             FOR( j = 0; j < coding_subbands; j++ )
    3999             :             {
    4000       31203 :                 IF( GT_16( no_cv_vec[j], 1 ) )
    4001             :                 {
    4002       30897 :                     num = i_mult( decoded_idx[j], 255 ); /*Q0*/
    4003       30897 :                     move16();
    4004       30897 :                     den = extract_l( L_add( L_sub( 7, L_shr( q_direction->band_data[j].energy_ratio_index_mod[0], hrmasa_flag ) ), coding_subbands / MASA_FACTOR_CV_COH ) ); /*Q0*/
    4005       30897 :                     q_den = norm_s( den );
    4006       30897 :                     q_num = sub( norm_s( num ), 1 );
    4007       30897 :                     res = div_s( shl( num, q_num ), shl( den, q_den ) ); /*Q15*/
    4008       30897 :                     q_res = add( sub( 15, q_den ), q_num );
    4009       30897 :                     res = L_shl( res, sub( 16, q_res ) );                                                   /*Q16*/
    4010       30897 :                     q_direction->coherence_band_data[j].spread_coherence[0] = (UWord8) ( round_fx( res ) ); /*Q0*/
    4011       30897 :                     move16();
    4012             :                 }
    4013             :                 ELSE
    4014             :                 {
    4015         306 :                     q_direction->coherence_band_data[j].spread_coherence[0] = 0;
    4016         306 :                     move16();
    4017             :                 }
    4018             :             }
    4019             :         }
    4020             :         ELSE
    4021             :         {
    4022             :             UWord16 decoded_index[MASA_MAXIMUM_CODING_SUBBANDS];
    4023             :             /* decode joint index */
    4024        4792 :             nbits = add( nbits, decode_fixed_rate_composed_index_coherence_fx( bitstream, &bit_pos, coding_subbands, no_cv_vec, decoded_index, add( MASA_NO_CV_COH, coding_subbands / MASA_FACTOR_CV_COH ) ) ); /*Q0*/
    4025       30016 :             FOR( j = 0; j < coding_subbands; j++ )
    4026             :             {
    4027       25224 :                 IF( GT_16( no_cv_vec[j], 1 ) )
    4028             :                 {
    4029       14154 :                     num = i_mult( decoded_index[j], 255 ); /*Q0*/
    4030       14154 :                     move16();
    4031       14154 :                     den = extract_l( L_add( L_sub( 7, L_shr( q_direction->band_data[j].energy_ratio_index_mod[0], hrmasa_flag ) ), coding_subbands / MASA_FACTOR_CV_COH ) ); /*Q0*/
    4032       14154 :                     q_den = norm_s( den );
    4033       14154 :                     q_num = sub( norm_s( num ), 1 );
    4034       14154 :                     res = div_s( shl( num, q_num ), shl( den, q_den ) ); /*Q15*/
    4035       14154 :                     q_res = add( sub( 15, q_den ), q_num );
    4036       14154 :                     res = L_shl( res, sub( 16, q_res ) );                                                   /*Q16*/
    4037       14154 :                     q_direction->coherence_band_data[j].spread_coherence[0] = (UWord8) ( round_fx( res ) ); /*Q0*/
    4038       14154 :                     move16();
    4039             :                 }
    4040             :                 ELSE
    4041             :                 {
    4042       11070 :                     q_direction->coherence_band_data[j].spread_coherence[0] = 0;
    4043       11070 :                     move16();
    4044             :                 }
    4045             :             }
    4046             :         }
    4047             :     }
    4048             :     ELSE
    4049             :     {
    4050      149498 :         FOR( j = 0; j < coding_subbands; j++ )
    4051             :         {
    4052      129221 :             IF( hrmasa_flag )
    4053             :             {
    4054           0 :                 minimum_s( (Word16 *) ( q_direction->band_data[j].energy_ratio_index ), q_direction->cfg.nblocks, &min_index ); /*Q0*/
    4055           0 :                 no_cv_vec[j] = len_cb_dct0_masa[( min_index / 2 )];                                                             /*Q0*/
    4056           0 :                 move16();                                                                                                       /* spread coherence DCT0*/
    4057             :             }
    4058             :             ELSE
    4059             :             {
    4060      129221 :                 no_cv_vec[j] = len_cb_dct0_masa[q_direction->band_data[j].energy_ratio_index[0]]; /*Q0*/
    4061      129221 :                 move16();                                                                         /* spread coherence DCT0*/
    4062             :             }
    4063             :         }
    4064             : 
    4065       20277 :         IF( GT_16( sum16_fx( no_cv_vec, coding_subbands ), MASA_COH_LIMIT_2IDX ) )
    4066             :         {
    4067             :             UWord16 spr_coh_temp_index[MASA_MAXIMUM_CODING_SUBBANDS];
    4068             : 
    4069         118 :             no_cb = 1;
    4070         118 :             move64();
    4071        1534 :             FOR( j = 0; j < shr( coding_subbands, 1 ); j++ )
    4072             :             {
    4073        1416 :                 no_cb *= no_cv_vec[j];
    4074        1416 :                 move64();
    4075             :             }
    4076             : 
    4077         118 :             no_bits_vec = ceil_log_2( no_cb ); // (int16_t)ceilf(logf((float)no_cb) * INV_LOG_2); Q0
    4078         118 :             no_cb = 1;
    4079         118 :             move64();
    4080             : 
    4081        1534 :             FOR( j = coding_subbands / 2; j < coding_subbands; j++ )
    4082             :             {
    4083        1416 :                 no_cb *= no_cv_vec[j];
    4084        1416 :                 move64();
    4085             :             }
    4086             : 
    4087         118 :             no_bits_vec1 = ceil_log_2( no_cb ); // (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); Q0
    4088         118 :             dct0_index = 0;
    4089         118 :             move64();
    4090             : 
    4091        3200 :             FOR( j = 0; j < no_bits_vec; j++ )
    4092             :             {
    4093        3082 :                 dct0_index = ( dct0_index << 1 ) + bitstream[bit_pos]; /*Q0*/
    4094        3082 :                 bit_pos = sub( bit_pos, 1 );
    4095        3082 :                 move64();
    4096             :             }
    4097             : 
    4098         118 :             nbits = add( nbits, no_bits_vec );
    4099         118 :             set_s( (Word16 *) spr_coh_temp_index, 0, MASA_MAXIMUM_CODING_SUBBANDS );
    4100             : 
    4101         118 :             decode_combined_index_fx( dct0_index, no_cv_vec, spr_coh_temp_index, shr( coding_subbands, 1 ) );
    4102             : 
    4103         118 :             dct0_index = 0;
    4104         118 :             move64();
    4105        2912 :             FOR( j = 0; j < no_bits_vec1; j++ )
    4106             :             {
    4107        2794 :                 dct0_index = ( dct0_index << 1 ) + bitstream[bit_pos]; /*Q0*/
    4108        2794 :                 bit_pos = sub( bit_pos, 1 );
    4109        2794 :                 move64();
    4110             :             }
    4111             : 
    4112         118 :             nbits = add( nbits, no_bits_vec1 );
    4113             : 
    4114         118 :             decode_combined_index_fx( dct0_index, &no_cv_vec[shr( coding_subbands, 1 )], &spr_coh_temp_index[shr( coding_subbands, 1 )], shr( coding_subbands, 1 ) );
    4115             : 
    4116        2950 :             FOR( j = 0; j < coding_subbands; j++ )
    4117             :             {
    4118        2832 :                 q_direction->coherence_band_data[j].spread_coherence_dct0_index = spr_coh_temp_index[j]; /*Q0*/
    4119        2832 :                 move16();
    4120             :             }
    4121             :         }
    4122             :         ELSE
    4123             :         {
    4124             :             /* spread coherence */
    4125             :             UWord16 spr_coh_temp_index[MASA_MAXIMUM_CODING_SUBBANDS];
    4126             : 
    4127       20159 :             no_cb = 1;
    4128       20159 :             move64();
    4129             : 
    4130      146548 :             FOR( j = 0; j < coding_subbands; j++ )
    4131             :             {
    4132      126389 :                 no_cb *= no_cv_vec[j];
    4133      126389 :                 move64();
    4134             :             }
    4135             : 
    4136       20159 :             no_bits_vec = ceil_log_2( no_cb ); // (int16_t)ceilf(logf((float)no_cb) * INV_LOG_2); Q0
    4137             : 
    4138             :             /* read joint index for DCT0 */
    4139       20159 :             no_bits_vec = ceil_log_2( no_cb ); // (int16_t)ceilf(logf((float)no_cb) * INV_LOG_2); Q0
    4140       20159 :             dct0_index = 0;
    4141       20159 :             move64();
    4142             : 
    4143      234730 :             FOR( j = 0; j < no_bits_vec; j++ )
    4144             :             {
    4145      214571 :                 dct0_index = ( dct0_index << 1 ) + bitstream[bit_pos]; /*Q0*/
    4146      214571 :                 bit_pos = sub( bit_pos, 1 );
    4147      214571 :                 move64();
    4148             :             }
    4149             : 
    4150       20159 :             nbits = add( nbits, no_bits_vec );
    4151             : 
    4152       20159 :             set16_fx( (Word16 *) spr_coh_temp_index, 0, MASA_MAXIMUM_CODING_SUBBANDS );
    4153             : 
    4154       20159 :             decode_combined_index_fx( dct0_index, no_cv_vec, spr_coh_temp_index, coding_subbands );
    4155             : 
    4156      146548 :             FOR( j = 0; j < coding_subbands; j++ )
    4157             :             {
    4158      126389 :                 q_direction->coherence_band_data[j].spread_coherence_dct0_index = spr_coh_temp_index[j]; /*Q0*/
    4159      126389 :                 move16();
    4160             :             }
    4161             :         }
    4162             : 
    4163             :         /* read GR data for DCT1 */
    4164      149498 :         FOR( j = 0; j < coding_subbands; j++ )
    4165             :         {
    4166      129221 :             bits_GR = bit_pos;
    4167      129221 :             idx_dct1[j] = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, shl( MASA_NO_CV_COH1, 1 ), 0 ); /*Q0*/
    4168      129221 :             move16();
    4169      129221 :             nbits = add( nbits, sub( bits_GR, bit_pos ) );
    4170             :         }
    4171       20277 :         bits_GR = bit_pos;
    4172       20277 :         move16(); /* just to store the data */
    4173             : 
    4174             :         /* read average index */
    4175       20277 :         read_huf( &bit_pos, bitstream, &av_index, bit_pos, MASA_NO_CV_COH1, huff_code_av_masa, 10 ); /* 10 is MAX_LEN*/
    4176       20277 :         nbits = add( nbits, sub( bits_GR, bit_pos ) );
    4177             : 
    4178             :         /* write indexes in metadata structure  */
    4179      149498 :         FOR( j = 0; j < coding_subbands; j++ )
    4180             :         {
    4181      129221 :             IF( L_and( idx_dct1[j], 1 ) )
    4182             :             {
    4183        2480 :                 q_direction->coherence_band_data[j].spread_coherence_dct1_index = (UWord16) L_add( L_shr( L_add( idx_dct1[j], 1 ), 1 ), av_index ); /*Q0*/
    4184        2480 :                 move16();
    4185             :             }
    4186             :             ELSE
    4187             :             {
    4188      126741 :                 q_direction->coherence_band_data[j].spread_coherence_dct1_index = (UWord16) L_add( L_shr( L_negate( idx_dct1[j] ), 1 ), av_index ); /*Q0*/
    4189      126741 :                 move16();
    4190             :             }
    4191             :         }
    4192             :     }
    4193       27429 :     nbits = sub( *p_bit_pos, bit_pos );
    4194             : 
    4195       27429 :     *p_bit_pos = bit_pos;
    4196       27429 :     move16();
    4197             : 
    4198       27429 :     return nbits;
    4199             : }
    4200             : 
    4201             : /*-------------------------------------------------------------------*
    4202             :  * read_surround_coherence()
    4203             :  *
    4204             :  *
    4205             :  *-------------------------------------------------------------------*/
    4206             : 
    4207       24185 : static Word16 read_surround_coherence(
    4208             :     UWord16 *bitstream,        /* i  : bitstream                       Q0*/
    4209             :     Word16 *p_bit_pos,         /* i  : position in the bitstream       Q0*/
    4210             :     IVAS_QMETADATA *hQMetaData /* i/o: quantized metadata structure    */
    4211             : )
    4212             : {
    4213             :     Word16 coding_subbands;
    4214             :     Word16 no_cv_vec[MASA_MAXIMUM_CODING_SUBBANDS];
    4215             :     Word16 bit_pos;
    4216             :     Word32 error_ratio_surr;
    4217             :     Word16 idx_ER[MASA_MAXIMUM_CODING_SUBBANDS];
    4218             :     Word16 bits_sur_coherence, bits_GR;
    4219             :     Word16 j, d, k, idx;
    4220             :     UWord16 byteBuffer;
    4221             :     UWord16 idx_sur_coh[MASA_MAXIMUM_CODING_SUBBANDS];
    4222             :     IVAS_QDIRECTION *q_direction;
    4223             :     Word16 min_index;
    4224             : 
    4225       24185 :     coding_subbands = hQMetaData->q_direction[0].cfg.nbands;
    4226       24185 :     q_direction = hQMetaData->q_direction;
    4227             : 
    4228       24185 :     bits_sur_coherence = 0;
    4229       24185 :     move16();
    4230       24185 :     bit_pos = *p_bit_pos;
    4231       24185 :     move16();
    4232             : 
    4233       24185 :     d = 0;
    4234       24185 :     move16();
    4235      201241 :     FOR( j = 0; j < coding_subbands; j++ )
    4236             :     {
    4237      177056 :         error_ratio_surr = ONE_IN_Q30;
    4238      177056 :         move32();
    4239             : 
    4240      177056 :         IF( EQ_16( hQMetaData->no_directions, 2 ) )
    4241             :         {
    4242       36273 :             d = add( d, hQMetaData->twoDirBands[j] );
    4243       36273 :             idx = s_max( sub( d, 1 ), 0 );
    4244       36273 :             IF( EQ_16( hQMetaData->twoDirBands[j], 1 ) )
    4245             :             {
    4246       12120 :                 error_ratio_surr = L_sub( L_sub( ONE_IN_Q30, q_direction[0].band_data[j].energy_ratio_fx[0] ), q_direction[1].band_data[idx].energy_ratio_fx[0] ); /*Q30*/
    4247             :             }
    4248             :             ELSE
    4249             :             {
    4250       24153 :                 error_ratio_surr = L_sub( ONE_IN_Q30, q_direction[0].band_data[j].energy_ratio_fx[0] ); /*Q30*/
    4251             :             }
    4252             :         }
    4253             :         ELSE
    4254             :         {
    4255      140783 :             error_ratio_surr = L_sub( ONE_IN_Q30, q_direction[0].band_data[j].energy_ratio_fx[0] ); /*Q30*/
    4256             :         }
    4257             : 
    4258      177056 :         IF( error_ratio_surr <= 0 )
    4259             :         {
    4260         151 :             error_ratio_surr = 0;
    4261         151 :             move32();
    4262         151 :             no_cv_vec[j] = 1;
    4263         151 :             move16();
    4264         151 :             idx_ER[j] = masa_sq_fx( 0, diffuseness_thresholds_fx, DIRAC_DIFFUSE_LEVELS ); /*Q0*/
    4265         151 :             move16();
    4266             :         }
    4267             :         ELSE
    4268             :         {
    4269      176905 :             idx_ER[j] = masa_sq_fx( error_ratio_surr, diffuseness_thresholds_fx, DIRAC_DIFFUSE_LEVELS ); /*Q0*/
    4270      176905 :             move16();
    4271      176905 :             no_cv_vec[j] = add( idx_cb_sur_coh_masa[idx_ER[j]], 2 );
    4272      176905 :             move16();
    4273             :         }
    4274             :     }
    4275             : 
    4276       24185 :     IF( EQ_16( sum16_fx( no_cv_vec, coding_subbands ), coding_subbands ) )
    4277             :     {
    4278             :         /* surround coherence is zero */
    4279           0 :         FOR( j = 0; j < coding_subbands; j++ )
    4280             :         {
    4281           0 :             FOR( k = 0; k < MAX_PARAM_SPATIAL_SUBFRAMES; k++ )
    4282             :             {
    4283           0 :                 if ( hQMetaData->surcoh_band_data != NULL )
    4284             :                 {
    4285           0 :                     hQMetaData->surcoh_band_data[j].surround_coherence[k] = 0;
    4286           0 :                     move16();
    4287             :                 }
    4288             :             }
    4289             :         }
    4290             : 
    4291           0 :         return bits_sur_coherence;
    4292             :     }
    4293             : 
    4294             :     /* read how the surround coherence is encoded */
    4295       24185 :     byteBuffer = bitstream[bit_pos]; /*Q0*/
    4296       24185 :     bit_pos = sub( bit_pos, 1 );
    4297       24185 :     move16();
    4298       24185 :     bits_sur_coherence = add( bits_sur_coherence, 1 );
    4299             : 
    4300       24185 :     IF( L_and( byteBuffer, 1 ) )
    4301             :     {
    4302             :         /* GR decoding */
    4303             :         /* read GR order */
    4304       19180 :         byteBuffer = bitstream[bit_pos]; /*Q0*/
    4305       19180 :         bit_pos = sub( bit_pos, 1 );
    4306       19180 :         bits_sur_coherence = add( bits_sur_coherence, 1 );
    4307             : 
    4308             :         /* read min index */
    4309       19180 :         bits_GR = bit_pos;
    4310       19180 :         move16();
    4311       19180 :         min_index = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, MASA_MAX_NO_CV_SUR_COH, 0 ); /*Q0*/
    4312       19180 :         bits_sur_coherence = add( bits_sur_coherence, sub( bits_GR, bit_pos ) );
    4313             : 
    4314             :         /* read GR data */
    4315      173076 :         FOR( j = 0; j < coding_subbands; j++ )
    4316             :         {
    4317      153896 :             bits_GR = bit_pos;
    4318      153896 :             move16();
    4319             :             /* decoding for min removed */
    4320      153896 :             IF( GT_16( no_cv_vec[j], 1 ) )
    4321             :             {
    4322      153764 :                 idx_sur_coh[j] = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, sub( no_cv_vec[j], min_index ), ( byteBuffer & 1 ) ); /*Q30*/
    4323      153764 :                 move16();
    4324      153764 :                 bits_sur_coherence = add( bits_sur_coherence, sub( bits_GR, bit_pos ) );
    4325             :             }
    4326             :             ELSE
    4327             :             {
    4328         132 :                 idx_sur_coh[j] = 0;
    4329         132 :                 move16();
    4330             :             }
    4331             :         }
    4332             : 
    4333      173076 :         FOR( j = 0; j < coding_subbands; j++ )
    4334             :         {
    4335      153896 :             IF( GT_16( no_cv_vec[j], 1 ) )
    4336             :             {
    4337      153764 :                 hQMetaData->surcoh_band_data[j].sur_coherence_index = add( idx_sur_coh[j], min_index ); /*Q0*/
    4338      153764 :                 move16();
    4339             :             }
    4340             :             ELSE
    4341             :             {
    4342         132 :                 hQMetaData->surcoh_band_data[j].sur_coherence_index = idx_sur_coh[j]; /*Q0*/
    4343         132 :                 move16();
    4344             :             }
    4345             : 
    4346      153896 :             hQMetaData->surcoh_band_data[j].surround_coherence[0] = sur_coherence_cb_masa[( ( idx_cb_sur_coh_masa[idx_ER[j]] * 8 ) + hQMetaData->surcoh_band_data[j].sur_coherence_index )]; /*Q0*/
    4347      153896 :             move16();
    4348             :         }
    4349             :     }
    4350             :     ELSE
    4351             :     {
    4352             :         /* fixed rate */
    4353             :         UWord16 sur_coh_temp_index[MASA_MAXIMUM_CODING_SUBBANDS];
    4354        5005 :         set16_fx( (Word16 *) sur_coh_temp_index, 0, MASA_MAXIMUM_CODING_SUBBANDS );
    4355             : 
    4356        5005 :         decode_fixed_rate_composed_index_coherence_fx( bitstream, &bit_pos, coding_subbands, no_cv_vec, sur_coh_temp_index, MASA_MAX_NO_CV_SUR_COH );
    4357             : 
    4358       28165 :         FOR( j = 0; j < coding_subbands; j++ )
    4359             :         {
    4360       23160 :             hQMetaData->surcoh_band_data[j].sur_coherence_index = sur_coh_temp_index[j]; /*Q0*/
    4361       23160 :             move16();
    4362             :         }
    4363             : 
    4364             :         /* deindex surround coherence */
    4365       28165 :         FOR( j = 0; j < coding_subbands; j++ )
    4366             :         {
    4367       23160 :             IF( GT_16( no_cv_vec[j], 1 ) )
    4368             :             {
    4369       20462 :                 hQMetaData->surcoh_band_data[j].surround_coherence[0] = sur_coherence_cb_masa[( ( idx_cb_sur_coh_masa[idx_ER[j]] * 8 ) + hQMetaData->surcoh_band_data[j].sur_coherence_index )]; /*Q0*/
    4370       20462 :                 move16();
    4371             :             }
    4372             :             ELSE
    4373             :             {
    4374        2698 :                 hQMetaData->surcoh_band_data[j].surround_coherence[0] = 0;
    4375        2698 :                 move16();
    4376             :             }
    4377             :         }
    4378             :     }
    4379             : 
    4380      201241 :     FOR( j = 0; j < coding_subbands; j++ )
    4381             :     {
    4382      708224 :         FOR( k = 1; k < MAX_PARAM_SPATIAL_SUBFRAMES; k++ )
    4383             :         {
    4384      531168 :             hQMetaData->surcoh_band_data[j].surround_coherence[k] = hQMetaData->surcoh_band_data[j].surround_coherence[0]; /*Q0*/
    4385      531168 :             move16();
    4386             :         }
    4387             :     }
    4388             : 
    4389             :     /* Replace return value with the actual read bits. bits_sur_coherence might show wrong count at this point. */
    4390       24185 :     bits_sur_coherence = sub( *p_bit_pos, bit_pos );
    4391       24185 :     *p_bit_pos = bit_pos;
    4392       24185 :     move16();
    4393             : 
    4394       24185 :     return bits_sur_coherence;
    4395             : }
    4396             : 
    4397             : 
    4398             : /*-------------------------------------------------------------------*
    4399             :  * read_surround_coherence_hr()
    4400             :  *
    4401             :  *
    4402             :  *-------------------------------------------------------------------*/
    4403        2241 : static Word16 read_surround_coherence_hr_fx(
    4404             :     UWord16 *bitstream,         /* i  : bitstream                       Q0*/
    4405             :     Word16 *p_bit_pos,          /* i  : position in the bitstream       Q0*/
    4406             :     IVAS_QMETADATA *hQMetaData, /* i/o: quantized metadata structure    */
    4407             :     Word64 energy_ratio[][MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES] /*Q62*/ )
    4408             : {
    4409             :     Word16 coding_subbands;
    4410             :     Word16 no_cv_vec[MASA_MAXIMUM_CODING_SUBBANDS];
    4411             :     Word16 bit_pos;
    4412             :     Word64 error_ratio_surr_fx;
    4413             :     Word16 idx_ER[MASA_MAXIMUM_CODING_SUBBANDS];
    4414             :     Word16 bits_sur_coherence, bits_GR;
    4415             :     Word16 j, k, sf;
    4416             :     UWord16 byteBuffer;
    4417             :     UWord16 idx_sur_coh[MASA_MAXIMUM_CODING_SUBBANDS];
    4418             :     // IVAS_QDIRECTION *q_direction;
    4419             :     Word16 min_index;
    4420             :     Word16 d, idx;
    4421        2241 :     coding_subbands = hQMetaData->q_direction[0].cfg.nbands;
    4422             :     // q_direction = hQMetaData->q_direction;
    4423             : 
    4424        2241 :     bits_sur_coherence = 0;
    4425        2241 :     move16();
    4426        2241 :     bit_pos = *p_bit_pos;
    4427        2241 :     move16();
    4428             : 
    4429       10767 :     FOR( sf = 0; sf < hQMetaData->q_direction[0].cfg.nblocks; sf++ )
    4430             :     {
    4431        8526 :         d = 0;
    4432        8526 :         move16();
    4433             : 
    4434      212428 :         FOR( j = 0; j < coding_subbands; j++ )
    4435             :         {
    4436      203902 :             error_ratio_surr_fx = ONE_IN_Q62;
    4437      203902 :             IF( EQ_32( hQMetaData->no_directions, 2 ) )
    4438             :             {
    4439      108190 :                 d = add( d, hQMetaData->twoDirBands[j] ); /*Q0*/
    4440      108190 :                 idx = s_max( sub( d, 1 ), 0 );
    4441      108190 :                 error_ratio_surr_fx = W_sub(
    4442             :                     W_sub( ONE_IN_Q62, energy_ratio[0][j][sf] ),
    4443      108190 :                     energy_ratio[1][idx][sf] * hQMetaData->twoDirBands[j] ); /*Q62*/
    4444             :             }
    4445             :             ELSE
    4446             :             {
    4447       95712 :                 error_ratio_surr_fx = W_sub( ONE_IN_Q62, energy_ratio[0][j][sf] ); /*Q62*/
    4448             :             }
    4449             : 
    4450      203902 :             IF( LE_64( error_ratio_surr_fx, ( 461168601842 ) ) ) // 1e-7 in Q62
    4451             :             {
    4452        1640 :                 error_ratio_surr_fx = 0;
    4453        1640 :                 move64();
    4454        1640 :                 no_cv_vec[j] = 1;
    4455        1640 :                 move16();
    4456        1640 :                 idx_ER[j] = 0;
    4457        1640 :                 move16();
    4458             :             }
    4459             :             ELSE
    4460             :             {
    4461      202262 :                 idx_ER[j] = 7;                                           // masa_sq( error_ratio_surr, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS );
    4462      202262 :                 no_cv_vec[j] = add( idx_cb_sur_coh_masa[idx_ER[j]], 2 ); /*Q0*/
    4463      202262 :                 move16();
    4464      202262 :                 move16();
    4465             :             }
    4466             :         }
    4467             : 
    4468        8526 :         IF( EQ_16( sum_s( no_cv_vec, coding_subbands ), coding_subbands ) )
    4469             :         {
    4470             :             /* surround coherence is zero */
    4471           0 :             FOR( j = 0; j < coding_subbands; j++ )
    4472             :             {
    4473           0 :                 FOR( k = 0; k < MAX_PARAM_SPATIAL_SUBFRAMES; k++ )
    4474             :                 {
    4475           0 :                     IF( hQMetaData->surcoh_band_data != NULL )
    4476             :                     {
    4477           0 :                         hQMetaData->surcoh_band_data[j].surround_coherence[k] = 0;
    4478           0 :                         move16();
    4479             :                     }
    4480             :                 }
    4481             :             }
    4482             :         }
    4483             :         ELSE
    4484             :         {
    4485             :             /* read how the surround coherence is encoded */
    4486        8526 :             byteBuffer = bitstream[bit_pos]; /*Q0*/
    4487        8526 :             move16();
    4488        8526 :             bit_pos = sub( bit_pos, 1 );
    4489        8526 :             bits_sur_coherence = add( bits_sur_coherence, 1 );
    4490             : 
    4491        8526 :             IF( byteBuffer & 1 )
    4492             :             {
    4493             :                 /* GR decoding */
    4494             :                 /* read GR order */
    4495        8352 :                 byteBuffer = bitstream[bit_pos]; /*Q0*/
    4496        8352 :                 move16();
    4497        8352 :                 bit_pos = sub( bit_pos, 1 );
    4498        8352 :                 bits_sur_coherence = add( bits_sur_coherence, 1 );
    4499             : 
    4500             :                 /* read min index */
    4501        8352 :                 bits_GR = bit_pos;
    4502        8352 :                 min_index = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, MASA_MAX_NO_CV_SUR_COH, 0 ); /*Q0*/
    4503        8352 :                 bits_sur_coherence = add( bits_sur_coherence, sub( bits_GR, bit_pos ) );
    4504             : 
    4505             :                 /* read GR data */
    4506      208129 :                 FOR( j = 0; j < coding_subbands; j++ )
    4507             :                 {
    4508      199777 :                     bits_GR = bit_pos;
    4509      199777 :                     move16();
    4510             :                     /* decoding for min removed */
    4511      199777 :                     IF( GT_16( no_cv_vec[j], 1 ) )
    4512             :                     {
    4513      198161 :                         idx_sur_coh[j] = ivas_qmetadata_DecodeExtendedGR( bitstream, &bit_pos, sub( no_cv_vec[j], min_index ), ( byteBuffer & 1 ) ); /*Q0*/
    4514      198161 :                         move16();
    4515      198161 :                         bits_sur_coherence = add( bits_sur_coherence, sub( bits_GR, bit_pos ) );
    4516             :                     }
    4517             :                     ELSE
    4518             :                     {
    4519        1616 :                         idx_sur_coh[j] = 0;
    4520        1616 :                         move16();
    4521             :                     }
    4522             :                 }
    4523             : 
    4524      208129 :                 FOR( j = 0; j < coding_subbands; j++ )
    4525             :                 {
    4526      199777 :                     IF( GT_16( no_cv_vec[j], 1 ) )
    4527             :                     {
    4528      198161 :                         hQMetaData->surcoh_band_data[j].sur_coherence_index = (UWord16) L_add( (Word32) idx_sur_coh[j], L_deposit_l( min_index ) ); /*Q0*/
    4529      198161 :                         move16();
    4530      198161 :                         hQMetaData->surcoh_band_data[j].surround_coherence[sf] = sur_coherence_cb_masa[( ( idx_cb_sur_coh_masa[idx_ER[j]] * MASA_MAX_NO_CV_SUR_COH ) + hQMetaData->surcoh_band_data[j].sur_coherence_index )];
    4531      198161 :                         move16();
    4532             :                     }
    4533             :                     ELSE
    4534             :                     {
    4535        1616 :                         hQMetaData->surcoh_band_data[j].sur_coherence_index = idx_sur_coh[j]; /*Q0*/
    4536        1616 :                         move16();
    4537        1616 :                         hQMetaData->surcoh_band_data[j].surround_coherence[sf] = 0;
    4538        1616 :                         move16();
    4539             :                     }
    4540             :                 }
    4541             :             }
    4542             :             ELSE
    4543             :             {
    4544             :                 /* fixed rate */
    4545             :                 UWord16 sur_coh_temp_index[MASA_MAXIMUM_CODING_SUBBANDS];
    4546         174 :                 set16_fx( (Word16 *) sur_coh_temp_index, 0, MASA_MAXIMUM_CODING_SUBBANDS );
    4547             : 
    4548         174 :                 decode_fixed_rate_composed_index_coherence_fx( bitstream, &bit_pos, coding_subbands, no_cv_vec, sur_coh_temp_index, MASA_MAX_NO_CV_SUR_COH );
    4549             : 
    4550        4299 :                 FOR( j = 0; j < coding_subbands; j++ )
    4551             :                 {
    4552        4125 :                     hQMetaData->surcoh_band_data[j].sur_coherence_index = sur_coh_temp_index[j]; /*Q0*/
    4553        4125 :                     move16();
    4554             :                 }
    4555             : 
    4556             :                 /* deindex surround coherence */
    4557        4299 :                 FOR( j = 0; j < coding_subbands; j++ )
    4558             :                 {
    4559        4125 :                     IF( GT_16( no_cv_vec[j], 1 ) )
    4560             :                     {
    4561        4030 :                         hQMetaData->surcoh_band_data[j].surround_coherence[sf] = sur_coherence_cb_masa[( ( idx_cb_sur_coh_masa[idx_ER[j]] * MASA_MAX_NO_CV_SUR_COH ) + hQMetaData->surcoh_band_data[j].sur_coherence_index )]; /*Q0*/
    4562        4030 :                         move16();
    4563             :                     }
    4564             :                     ELSE
    4565             :                     {
    4566          95 :                         hQMetaData->surcoh_band_data[j].surround_coherence[sf] = 0;
    4567          95 :                         move16();
    4568             :                     }
    4569             :                 }
    4570             :             }
    4571             :         }
    4572             :     }
    4573             : 
    4574             :     /* Replace return value with the actual read bits. bits_sur_coherence might show wrong count at this point. */
    4575        2241 :     bits_sur_coherence = sub( *p_bit_pos, bit_pos );
    4576        2241 :     *p_bit_pos = bit_pos;
    4577        2241 :     move16();
    4578             : 
    4579        2241 :     return bits_sur_coherence;
    4580             : }
    4581             : 
    4582             : 
    4583             : /*-------------------------------------------------------------------*
    4584             :  * decode_combined_index()
    4585             :  *
    4586             :  * Decode combined index into several indexes
    4587             :  *-------------------------------------------------------------------*/
    4588             : 
    4589       30490 : static void decode_combined_index_fx(
    4590             :     UWord64 comb_index,      /* i  : index to be decoded                 Q0*/
    4591             :     const Word16 *no_cv_vec, /* i  : number of codewords for each element Q0*/
    4592             :     UWord16 *index,          /* o  : decoded indexes                     Q0*/
    4593             :     const Word16 len         /* i  : number of elements                  Q0*/
    4594             : )
    4595             : {
    4596             :     Word16 i;
    4597             :     UWord64 base[MASA_MAXIMUM_CODING_SUBBANDS + 1];
    4598             : 
    4599       30490 :     base[0] = 1;
    4600       30490 :     move64();
    4601      181710 :     FOR( i = 1; i < len; i++ )
    4602             :     {
    4603      151220 :         base[i] = base[i - 1] * no_cv_vec[i - 1];
    4604             :     }
    4605             : 
    4606      181710 :     FOR( i = len - 1; i > 0; i-- )
    4607             :     {
    4608      151220 :         index[i] = (UWord16) ( comb_index / base[i] );
    4609      151220 :         comb_index -= index[i] * base[i];
    4610             :     }
    4611             : 
    4612       30490 :     index[0] = (UWord16) comb_index;
    4613       30490 :     move16();
    4614             : 
    4615       30490 :     return;
    4616             : }
    4617             : 
    4618             : 
    4619        1597 : static void read_stream_dct_coeffs_omasa_fx(
    4620             :     Word16 *q_idx, /*Q0*/
    4621             :     Word32 *q_dct_data_fx,
    4622             :     const Word16 len_stream, /*Q0*/
    4623             :     UWord16 *bit_stream,     /*Q0*/
    4624             :     Word16 *index,           /*Q0*/
    4625             :     const Word16 first_line /*Q0*/ )
    4626             : {
    4627             :     Word16 sign, nbits;
    4628             :     Word16 i, j, i_min;
    4629             : 
    4630             :     Word32 step;
    4631             :     Word16 GR1, GR2;
    4632             : 
    4633        1597 :     step = STEP_M2T_FX;
    4634        1597 :     move32();
    4635        1597 :     nbits = 0;
    4636        1597 :     move16();
    4637        1597 :     sign = 1;
    4638        1597 :     move16();
    4639        1597 :     IF( !first_line )
    4640             :     {
    4641             :         /* read sign */
    4642           0 :         sign = bit_stream[( *index )--]; /*Q0*/
    4643           0 :         move16();
    4644           0 :         IF( !sign )
    4645             :         {
    4646           0 :             sign = -1;
    4647           0 :             move16();
    4648             :         }
    4649           0 :         nbits = add( nbits, 1 );
    4650             :     }
    4651             : 
    4652        1597 :     set16_fx( q_idx, 0, len_stream );
    4653             :     /* read DCT 0 component */
    4654       11179 :     FOR( i = 0; i < BITS_MASA2TOTTAL_DCT0; i++ )
    4655             :     {
    4656        9582 :         q_idx[0] = add( shl( q_idx[0], 1 ), bit_stream[( *index )--] ); /*Q0*/
    4657        9582 :         move16();
    4658             :     }
    4659        1597 :     q_idx[0] = i_mult( q_idx[0], sign ); /*Q0*/
    4660        1597 :     move16();
    4661             : 
    4662        1597 :     IF( q_idx[0] != 0 )
    4663             :     {
    4664        1597 :         IF( GE_16( len_stream, 8 ) )
    4665             :         {
    4666             :             /* read index of last index encoded with GR2 */
    4667        1403 :             i_min = 0;
    4668        1403 :             move16();
    4669        1403 :             j = 4;
    4670        1403 :             move16();
    4671        7015 :             FOR( i = 0; i < j; i++ )
    4672             :             {
    4673        5612 :                 i_min = extract_l( L_add( shl( i_min, 1 ), bit_stream[( *index )--] ) ); /*Q0*/
    4674             :             }
    4675        1403 :             nbits = add( nbits, j );
    4676             :             /* read GR orders */
    4677        1403 :             GR1 = extract_l( L_add( bit_stream[( *index )--], 1 ) ); /*Q0*/
    4678        1403 :             IF( EQ_16( GR1, 2 ) )
    4679             :             {
    4680        1071 :                 GR2 = bit_stream[( *index )--]; /*Q0*/
    4681        1071 :                 move16();
    4682             :             }
    4683             :             ELSE
    4684             :             {
    4685         332 :                 GR2 = 0;
    4686         332 :                 move16();
    4687             :             }
    4688             : 
    4689             :             /* read GR data */
    4690        8065 :             FOR( i = 1; i <= i_min; i++ )
    4691             :             {
    4692        6662 :                 q_idx[i] = ivas_qmetadata_DecodeExtendedGR( bit_stream, index, 100, GR1 ); /*Q0*/
    4693        6662 :                 move16();
    4694             :             }
    4695       18494 :             FOR( i = ( i_min + 1 ); i < len_stream; i++ )
    4696             :             {
    4697       17091 :                 q_idx[i] = ivas_qmetadata_DecodeExtendedGR( bit_stream, index, 100, GR2 ); /*Q0*/
    4698       17091 :                 move16();
    4699             :             }
    4700             :         }
    4701             :         ELSE
    4702             :         {
    4703             :             /* read GR order (only one)  */
    4704         194 :             GR1 = bit_stream[( *index )]; /*Q0*/
    4705         194 :             move16();
    4706         194 :             ( *index ) = sub( ( *index ), 1 );
    4707         194 :             move16();
    4708         950 :             FOR( i = 1; i < len_stream; i++ )
    4709             :             {
    4710         756 :                 q_idx[i] = ivas_qmetadata_DecodeExtendedGR( bit_stream, index, 100, GR1 ); /*Q0*/
    4711         756 :                 move16();
    4712             :             }
    4713             :         }
    4714             :     }
    4715             : 
    4716             :     /* deindex */
    4717        1597 :     q_dct_data_fx[0] = L_shl( Mpy_32_16_1( step, shl( q_idx[0], 7 ) ), 2 ); // q = 25
    4718        1597 :     move32();
    4719       26106 :     FOR( i = 1; i < len_stream; i++ )
    4720             :     {
    4721       24509 :         IF( s_and( q_idx[i], 1 ) == 0 )
    4722             :         {
    4723       17078 :             q_dct_data_fx[i] = L_shl( Mpy_32_16_1( step, negate( shl( q_idx[i], 6 ) ) ), 2 ); /*Q25*/
    4724       17078 :             move32();
    4725             :         }
    4726             :         ELSE
    4727             :         {
    4728        7431 :             q_dct_data_fx[i] = L_shl( Mpy_32_16_1( step, shl( q_idx[i] + 1, 6 ) ), 2 ); /*Q25*/
    4729        7431 :             move32();
    4730             :         }
    4731             :     }
    4732             : 
    4733        1597 :     return;
    4734             : }
    4735             : 
    4736             : 
    4737             : /*-------------------------------------------------------------------------
    4738             :  * ivas_omasa_decode_masa_to_total()
    4739             :  *
    4740             :  *------------------------------------------------------------------------*/
    4741             : 
    4742        1597 : void ivas_omasa_decode_masa_to_total_fx(
    4743             :     UWord16 *bit_stream,                                                                     /*Q0*/
    4744             :     Word16 *index,                                                                           /*Q0*/
    4745             :     Word32 masa_to_total_energy_ratio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /*Q30*/
    4746             :     const Word16 nbands,                                                                     /*Q0*/
    4747             :     const Word16 nblocks /*Q0*/ )
    4748             : {
    4749             :     Word16 i, j, k;
    4750             :     Word16 q_idx[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS];
    4751             :     Word32 q_dct_data_fx[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS], // q = 25
    4752             :         dct_data_tmp_fx[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS];  // q = 25
    4753             :     Word16 n_streams, len_stream;
    4754             : 
    4755             :     /* Setup coding parameters */
    4756        1597 :     n_streams = 1;
    4757        1597 :     move16();
    4758        1597 :     len_stream = i_mult( nbands, nblocks );
    4759        1597 :     IF( EQ_16( len_stream, 32 ) )
    4760             :     {
    4761           0 :         n_streams = 4;
    4762           0 :         move16();
    4763           0 :         len_stream = 8;
    4764           0 :         move16();
    4765             :     }
    4766             : 
    4767        1597 :     set16_fx( q_idx, 0, i_mult( nbands, nblocks ) );
    4768        3194 :     FOR( i = 0; i < n_streams; i++ )
    4769             :     {
    4770        1597 :         read_stream_dct_coeffs_omasa_fx( &q_idx[( i * len_stream )], &q_dct_data_fx[( i * len_stream )], len_stream, bit_stream, index, i == 0 );
    4771             :     }
    4772             : 
    4773             :     /* inverse DCT2 transform */
    4774        1597 :     SWITCH( len_stream )
    4775             :     {
    4776          20 :         case 4:
    4777          20 :             matrix_product_q30_fx( dct4_fx, nblocks, nblocks, 1, q_dct_data_fx, nblocks, 1, 0, dct_data_tmp_fx );
    4778          20 :             Copy32( dct_data_tmp_fx, q_dct_data_fx, nblocks ); /*Q30*/
    4779          20 :             BREAK;
    4780         174 :         case 5:
    4781         174 :             matrix_product_q30_fx( dct5_fx, nbands, nbands, 1, q_dct_data_fx, nbands, 1, 0, dct_data_tmp_fx );
    4782         174 :             Copy32( dct_data_tmp_fx, q_dct_data_fx, nbands ); /*Q30*/
    4783         174 :             BREAK;
    4784           0 :         case 8:
    4785           0 :             matrix_product_q30_fx( dct8_fx, nbands, nbands, 1, q_dct_data_fx, nbands, 1, 0, dct_data_tmp_fx );
    4786           0 :             Copy32( dct_data_tmp_fx, q_dct_data_fx, nbands ); /*Q30*/
    4787           0 :             BREAK;
    4788         363 :         case 12:
    4789         363 :             matrix_product_q30_fx( dct12_fx, nbands, nbands, 1, q_dct_data_fx, nbands, 1, 0, dct_data_tmp_fx );
    4790         363 :             Copy32( dct_data_tmp_fx, q_dct_data_fx, nbands ); /*Q30*/
    4791         363 :             BREAK;
    4792        1040 :         case 20:
    4793        1040 :             matrix_product_fx( dct5_fx, nbands, nbands, 1, q_dct_data_fx, nbands, nblocks, 0, dct_data_tmp_fx );
    4794        1040 :             matrix_product_q30_fx( dct_data_tmp_fx, nbands, nblocks, 0, dct4_fx, nblocks, nblocks, 0, q_dct_data_fx ); /* reuse of variable*/
    4795        1040 :             BREAK;
    4796           0 :         case 32:
    4797           0 :             matrix_product_fx( dct8_fx, nbands, nbands, 1, q_dct_data_fx, nbands, nblocks, 0, dct_data_tmp_fx );
    4798           0 :             matrix_product_q30_fx( dct_data_tmp_fx, nbands, nblocks, 0, dct4_fx, nblocks, nblocks, 0, q_dct_data_fx );
    4799           0 :             BREAK;
    4800           0 :         default:
    4801           0 :             printf( "Incorrect number of coefficients for OMASA.\n" );
    4802           0 :             BREAK;
    4803             :     }
    4804        1597 :     k = 0;
    4805        1597 :     move16();
    4806        6374 :     FOR( i = 0; i < nblocks; i++ )
    4807             :     {
    4808       30883 :         FOR( j = 0; j < nbands; j++ )
    4809             :         {
    4810       26106 :             masa_to_total_energy_ratio_fx[i][j] = L_max( 0, q_dct_data_fx[k] ); // Q30
    4811       26106 :             move32();
    4812       26106 :             masa_to_total_energy_ratio_fx[i][j] = L_min( ONE_IN_Q30, masa_to_total_energy_ratio_fx[i][j] ); /*Q30*/
    4813       26106 :             move32();
    4814       26106 :             k = add( k, 1 );
    4815             :         }
    4816             :     }
    4817             : 
    4818        1597 :     IF( EQ_16( nblocks, 1 ) )
    4819             :     {
    4820        2148 :         FOR( i = 1; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
    4821             :         {
    4822       17289 :             FOR( j = 0; j < nbands; j++ )
    4823             :             {
    4824       15678 :                 masa_to_total_energy_ratio_fx[i][j] = masa_to_total_energy_ratio_fx[0][j]; /*Q30*/
    4825       15678 :                 move32();
    4826             :             }
    4827             :         }
    4828             :     }
    4829             : 
    4830        1597 :     IF( EQ_16( nbands, 1 ) )
    4831             :     {
    4832         100 :         FOR( j = 1; j < 5; j++ )
    4833             :         {
    4834         400 :             FOR( i = 0; i < nblocks; i++ )
    4835             :             {
    4836         320 :                 masa_to_total_energy_ratio_fx[i][j] = masa_to_total_energy_ratio_fx[i][0]; /*Q30*/
    4837         320 :                 move32();
    4838             :             }
    4839             :         }
    4840             :     }
    4841             : 
    4842        1597 :     return;
    4843             : }

Generated by: LCOV version 1.14