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

Generated by: LCOV version 1.14