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

Generated by: LCOV version 1.14