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

Generated by: LCOV version 1.14