LCOV - code coverage report
Current view: top level - lib_dec - ivas_masa_dec_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 1527 1619 94.3 %
Date: 2025-05-03 01:55:50 Functions: 19 19 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 <stdint.h>
      34             : #include <math.h>
      35             : #include <assert.h>
      36             : #include "options.h"
      37             : #include "ivas_cnst.h"
      38             : #include "ivas_prot_rend_fx.h"
      39             : #include "rom_com.h"
      40             : #include "ivas_rom_com.h"
      41             : #include "ivas_stat_dec.h"
      42             : #include "prot_fx.h"
      43             : #include "wmc_auto.h"
      44             : #include "ivas_prot_fx.h"
      45             : #include "ivas_rom_com_fx.h"
      46             : 
      47             : 
      48             : /*-----------------------------------------------------------------------*
      49             :  * Local constants
      50             :  *-----------------------------------------------------------------------*/
      51             : 
      52             : #define SPAR_META_DELAY_SUBFRAMES 2                              /* Number of subframes to delay the SPAR metadata */
      53             : #define SPH_IDX_FRONT             ( MASA_NO_POINTS_EQUATOR / 2 ) /* Spherical index corresponding to front direction for setting as default value */
      54             : 
      55             : 
      56             : /*-----------------------------------------------------------------------*
      57             :  * Local function prototypes
      58             :  *-----------------------------------------------------------------------*/
      59             : 
      60             : static Word16 rint_fx( Word32 num );
      61             : 
      62             : static void index_16bits_fx( IVAS_QMETADATA_HANDLE hQMetaData, SPHERICAL_GRID_DATA *Sph_Grid16 );
      63             : 
      64             : static void create_masa_ext_out_meta_fx( MASA_DECODER *hMasa, IVAS_QMETADATA_HANDLE hQMetaData, const Word16 nchan_transport );
      65             : 
      66             : static void replicate_subframes_fx( IVAS_QMETADATA_HANDLE hQMetaData );
      67             : 
      68             : static void restore_lowbitrate_masa_fx( IVAS_QMETADATA_HANDLE hQMetaData, const Word16 low_bitrate_mode, const Word16 numCodingBands );
      69             : 
      70             : static ivas_error init_lfe_synth_data_fx( Decoder_Struct *st_ivas, MASA_DECODER_HANDLE hMasa );
      71             : 
      72             : static void compute_foa_cov_matrix_fx( Word32 foaCov_fx[FOA_CHANNELS][FOA_CHANNELS], Word32 inCov_fx[FOA_CHANNELS][FOA_CHANNELS], Word32 mixMtx_fx[FOA_CHANNELS][FOA_CHANNELS] );
      73             : 
      74             : static Word16 decode_lfe_to_total_energy_ratio_fx( MCMASA_LFE_SYNTH_DATA_HANDLE hMasaLfeSynth, UWord16 *bitstream, Word16 *index, const Word32 ivas_total_brate );
      75             : 
      76             : static ivas_error ivas_masa_dec_config_fx( Decoder_Struct *st_ivas );
      77             : 
      78             : static Word16 ivas_decode_masaism_metadata_fx( IVAS_QMETADATA_HANDLE hQMetaData, MASA_DECODER_HANDLE hMasa, MASA_ISM_DATA_HANDLE hMasaIsmData, const Word16 nchan_ism, UWord16 *bit_stream, Word16 *next_bit_pos, const Word16 idx_separated_object, const Word16 ism_imp, const Word16 dirac_bs_md_write_idx, const Word16 dirac_md_buffer_length );
      79             : 
      80             : static void decode_index_slice_fx( Word16 index, Word16 *ratio_idx_ism, const Word16 nchan_ism, const Word16 K );
      81             : 
      82             : static void decode_ism_ratios_fx( UWord16 *bit_stream, Word16 *next_bit_pos, Word32 masa_to_total_energy_ratio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], Word32 ratio_ism[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS], const Word16 nchan_ism, const Word16 nbands, const Word16 nblocks, const Word16 idx_separated_object );
      83             : 
      84             : static void read_ism_ratio_index_fx( Word16 ratio_ism_idx[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS], const Word16 nchan_ism, const Word16 numCodingBands, const Word16 sf, Word16 ratio_ism_idx_prev_sf[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS], UWord16 *bit_stream, Word16 *next_bit_pos, const Word32 *masa_to_total_energy_ratio_fx, const Word16 idx_sep_obj, Word16 *num_zeros );
      85             : 
      86             : 
      87             : /*-----------------------------------------------------------------------*
      88             :  * ivas_masa_decode_fx()
      89             :  *
      90             :  * MASA metadata decoder
      91             :  *-----------------------------------------------------------------------*/
      92             : 
      93       48716 : ivas_error ivas_masa_decode_fx(
      94             :     Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct                    */
      95             :     Decoder_State *st,       /* i/o: decoder state structure with bitstream */
      96             :     Word16 *nb_bits_read     /* o  : number of bits read                    Q0*/
      97             : )
      98             : {
      99             :     UWord16 byteBuffer;
     100             :     Word16 next_bit_pos_orig;
     101             :     Word32 masa_brate, ivas_total_brate;
     102             :     MASA_DECODER_HANDLE hMasa;
     103             :     IVAS_QMETADATA_HANDLE hQMetaData;
     104             :     IVAS_FORMAT ivas_format;
     105             :     Word16 low_bitrate_mode, tmp_elem_mode;
     106             :     ivas_error error;
     107             :     Word16 obj;
     108             :     Word16 i, ch, ism_imp;
     109             :     Word16 dirac_bs_md_write_idx, tmp;
     110             :     Word32 masa_total_brate;
     111             : 
     112       48716 :     dirac_bs_md_write_idx = 0;
     113       48716 :     move16();
     114       48716 :     ism_imp = 0;
     115       48716 :     move16();
     116             : 
     117       48716 :     error = IVAS_ERR_OK;
     118       48716 :     move16();
     119       48716 :     ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
     120       48716 :     move32();
     121             : 
     122       48716 :     low_bitrate_mode = -1; /* This means that LBR mode is not used. */
     123       48716 :     move16();
     124             : 
     125       48716 :     test();
     126       48716 :     test();
     127       48716 :     test();
     128       48716 :     IF( st_ivas->hOutSetup.separateChannelEnabled || EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) || EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
     129             :     {
     130        6968 :         masa_brate = st_ivas->hCPE[0]->element_brate;
     131        6968 :         move32();
     132             :     }
     133             :     ELSE
     134             :     {
     135       41748 :         masa_brate = ivas_total_brate;
     136       41748 :         move32();
     137             :     }
     138             : 
     139       48716 :     hMasa = st_ivas->hMasa;
     140       48716 :     hQMetaData = st_ivas->hQMetaData;
     141       48716 :     ivas_format = st_ivas->ivas_format;
     142       48716 :     move32();
     143             : 
     144       48716 :     hMasa->data.dir_decode_quality_fx = MAX16B; /* Set to default of max quality */ /* 1.0f in Q15 */
     145       48716 :     move16();
     146             : 
     147       48716 :     hQMetaData->is_masa_ivas_format = 1;
     148       48716 :     move16();
     149             : 
     150       48716 :     *nb_bits_read = 0;
     151       48716 :     move16();
     152             : 
     153       48716 :     next_bit_pos_orig = st->next_bit_pos;
     154       48716 :     move16();
     155             : 
     156             :     /* masa_brate / FRAMES_PER_SEC */
     157       48716 :     tmp = extract_l( Mpy_32_32( masa_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) ); // Q0
     158             : 
     159       48716 :     IF( EQ_32( masa_brate, IVAS_SID_5k2 ) )
     160             :     {
     161         205 :         st->next_bit_pos = sub( sub( tmp, 1 ), SID_FORMAT_NBITS );
     162             :     }
     163             :     ELSE
     164             :     {
     165       48511 :         st->next_bit_pos = sub( tmp, 1 );
     166             :     }
     167       48716 :     move16();
     168             : 
     169       48716 :     test();
     170       48716 :     test();
     171       48716 :     test();
     172       48716 :     test();
     173       48716 :     test();
     174       48716 :     IF( st->bfi == 0 && GT_32( ivas_total_brate, IVAS_SID_5k2 ) )
     175             :     {
     176       46656 :         test();
     177       46656 :         IF( NE_32( ivas_format, MC_FORMAT ) || NE_16( st_ivas->mc_mode, MC_MODE_MCMASA ) )
     178             :         {
     179       36617 :             IF( NE_32( ivas_format, MASA_ISM_FORMAT ) )
     180             :             {
     181             :                 /* number of transport channels is always 2 for MASA_ISM format */
     182             :                 /* the number of MASA transport channels was read in ivas_dec_setup() */
     183       30306 :                 st->next_bit_pos = sub( st->next_bit_pos, MASA_TRANSP_BITS );
     184       30306 :                 *nb_bits_read = add( *nb_bits_read, MASA_TRANSP_BITS );
     185       30306 :                 move16();
     186             :             }
     187             : 
     188       36617 :             test();
     189       36617 :             IF( EQ_32( ivas_format, MASA_ISM_FORMAT ) && NE_32( st_ivas->ism_mode, ISM_MODE_NONE ) )
     190             :             {
     191             :                 /* the number of objects  was read */
     192        6311 :                 st->next_bit_pos = sub( st->next_bit_pos, NO_BITS_MASA_ISM_NO_OBJ );
     193        6311 :                 *nb_bits_read = add( *nb_bits_read, NO_BITS_MASA_ISM_NO_OBJ );
     194        6311 :                 move16();
     195        6311 :                 move16();
     196             : 
     197        6311 :                 IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
     198             :                 {
     199             :                     /* read index of separated object */
     200             :                     /* nchan_ism should be > 1*/
     201        1597 :                     byteBuffer = st->bit_stream[( st->next_bit_pos )--];
     202        1597 :                     move16();
     203        1597 :                     *nb_bits_read = add( *nb_bits_read, 1 );
     204        1597 :                     move16();
     205        1597 :                     st_ivas->hMasaIsmData->idx_separated_ism = extract_l( L_add( L_shl( byteBuffer, 1 ), st->bit_stream[( st->next_bit_pos )--] ) );
     206        1597 :                     move16();
     207        1597 :                     *nb_bits_read = add( *nb_bits_read, 1 );
     208        1597 :                     move16();
     209             :                 }
     210             :                 ELSE
     211             :                 {
     212        4714 :                     st_ivas->hMasaIsmData->idx_separated_ism = -1;
     213        4714 :                     move16();
     214             :                 }
     215             : 
     216             :                 /* read ISM importance flag (one per object) */
     217        6311 :                 IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
     218             :                 {
     219        1597 :                     ism_imp = 0;
     220        1597 :                     move16();
     221             : 
     222        4791 :                     FOR( i = 0; i < ISM_METADATA_FLAG_BITS; i++ )
     223             :                     {
     224        3194 :                         byteBuffer = st->bit_stream[( st->next_bit_pos )--];
     225        3194 :                         move16();
     226        3194 :                         *nb_bits_read = add( *nb_bits_read, 1 );
     227        3194 :                         move16();
     228        3194 :                         ism_imp = add( shl( ism_imp, 1 ), (Word16) byteBuffer );
     229             :                     }
     230        1597 :                     st_ivas->hIsmMetaData[0]->ism_imp = ism_imp;
     231        1597 :                     move16();
     232             :                 }
     233             : 
     234        6311 :                 IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
     235             :                 {
     236        1989 :                     ism_imp = 0;
     237        1989 :                     move16();
     238        5967 :                     FOR( i = 0; i < ISM_METADATA_FLAG_BITS; i++ )
     239             :                     {
     240        3978 :                         byteBuffer = st->bit_stream[( st->next_bit_pos )--];
     241        3978 :                         move16();
     242        3978 :                         *nb_bits_read = add( *nb_bits_read, 1 );
     243        3978 :                         move16();
     244        3978 :                         ism_imp = add( shl( ism_imp, 1 ), (Word16) byteBuffer );
     245        3978 :                         move16();
     246             :                     }
     247        1989 :                     st_ivas->hIsmMetaData[0]->ism_imp = ism_imp;
     248        1989 :                     move16();
     249             : 
     250             :                     /* reset */
     251        1989 :                     st_ivas->hIsmMetaData[0]->ism_md_null_flag = 0;
     252        1989 :                     move16();
     253        1989 :                     st_ivas->hIsmMetaData[0]->ism_md_lowrate_flag = 0;
     254        1989 :                     move16();
     255        1989 :                     IF( EQ_16( st_ivas->hIsmMetaData[0]->ism_imp, ISM_NO_META ) )
     256             :                     {
     257             :                         /* read flags */
     258           0 :                         st_ivas->hIsmMetaData[0]->ism_md_null_flag = st->bit_stream[( st->next_bit_pos )--];
     259           0 :                         move16();
     260           0 :                         *nb_bits_read = add( *nb_bits_read, ISM_METADATA_MD_FLAG_BITS );
     261           0 :                         move16();
     262           0 :                         st_ivas->hIsmMetaData[0]->ism_md_lowrate_flag = st->bit_stream[( st->next_bit_pos )--];
     263           0 :                         move16();
     264           0 :                         *nb_bits_read = add( *nb_bits_read, ISM_METADATA_INACTIVE_FLAG_BITS );
     265           0 :                         move16();
     266             :                     }
     267             :                 }
     268        4322 :                 ELSE IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
     269             :                 {
     270        9957 :                     FOR( ch = 0; ch < st_ivas->nchan_ism; ch++ )
     271             :                     {
     272        7232 :                         ism_imp = 0;
     273        7232 :                         move16();
     274       21696 :                         FOR( i = 0; i < ISM_METADATA_FLAG_BITS; i++ )
     275             :                         {
     276       14464 :                             byteBuffer = st->bit_stream[( st->next_bit_pos )--];
     277       14464 :                             move16();
     278       14464 :                             *nb_bits_read = add( *nb_bits_read, 1 );
     279       14464 :                             move16();
     280       14464 :                             ism_imp = add( shl( ism_imp, 1 ), (Word16) byteBuffer );
     281             :                         }
     282        7232 :                         st_ivas->hIsmMetaData[ch]->ism_imp = ism_imp;
     283        7232 :                         move16();
     284             : 
     285             :                         /* reset */
     286        7232 :                         st_ivas->hIsmMetaData[ch]->ism_md_null_flag = 0;
     287        7232 :                         move16();
     288        7232 :                         st_ivas->hIsmMetaData[ch]->ism_md_lowrate_flag = 0;
     289        7232 :                         move16();
     290        7232 :                         IF( EQ_16( st_ivas->hIsmMetaData[ch]->ism_imp, ISM_NO_META ) )
     291             :                         {
     292             :                             /* read flags */
     293           0 :                             st_ivas->hIsmMetaData[ch]->ism_md_null_flag = st->bit_stream[( st->next_bit_pos )--];
     294           0 :                             move16();
     295           0 :                             *nb_bits_read = add( *nb_bits_read, ISM_METADATA_MD_FLAG_BITS );
     296           0 :                             move16();
     297           0 :                             st_ivas->hIsmMetaData[ch]->ism_md_lowrate_flag = st->bit_stream[( st->next_bit_pos )--];
     298           0 :                             move16();
     299           0 :                             *nb_bits_read = add( *nb_bits_read, ISM_METADATA_INACTIVE_FLAG_BITS );
     300           0 :                             move16();
     301             :                         }
     302             :                     }
     303        2725 :                     st_ivas->flag_omasa_brate = 0;
     304        2725 :                     move16();
     305        2725 :                     test();
     306        2725 :                     IF( GE_16( st_ivas->nchan_ism, 3 ) && EQ_32( ivas_total_brate, IVAS_128k ) )
     307             :                     {
     308         120 :                         st_ivas->flag_omasa_brate = st->bit_stream[( st->next_bit_pos )--];
     309         120 :                         move16();
     310         120 :                         *nb_bits_read = add( *nb_bits_read, 1 );
     311         120 :                         move16();
     312             :                     }
     313             :                 }
     314             :             }
     315             : 
     316             :             /* read the MASA_ISM_FORMAT bit */
     317       36617 :             byteBuffer = st->bit_stream[( st->next_bit_pos )--];
     318       36617 :             move16();
     319       36617 :             IF( EQ_32( byteBuffer, 1 ) )
     320             :             {
     321        1821 :                 hMasa->config.input_ivas_format = MASA_ISM_FORMAT;
     322             :             }
     323             :             ELSE
     324             :             {
     325       34796 :                 hMasa->config.input_ivas_format = MASA_FORMAT;
     326             :             }
     327       36617 :             move32();
     328             : 
     329             :             /* reserved bit */
     330       36617 :             byteBuffer = st->bit_stream[( st->next_bit_pos )--];
     331       36617 :             move16();
     332       36617 :             *nb_bits_read = add( *nb_bits_read, MASA_HEADER_BITS );
     333             : 
     334             :             /* read number of directions */
     335       36617 :             byteBuffer = st->bit_stream[( st->next_bit_pos )--];
     336       36617 :             move16();
     337       36617 :             *nb_bits_read = add( *nb_bits_read, 1 );
     338       36617 :             move16();
     339       36617 :             hMasa->config.numberOfDirections = (UWord8) L_add( byteBuffer, 1 );
     340       36617 :             move16();
     341             :         }
     342             :         ELSE
     343             :         {
     344       10039 :             hMasa->config.numberOfDirections = 1;
     345       10039 :             move16();
     346             :         }
     347             : 
     348       46656 :         test();
     349       46656 :         IF( NE_32( ivas_format, MC_FORMAT ) || NE_32( st_ivas->mc_mode, MC_MODE_MCMASA ) )
     350             :         {
     351             :             /* read subframe mode */
     352       36617 :             byteBuffer = st->bit_stream[( st->next_bit_pos )--];
     353       36617 :             move16();
     354       36617 :             *nb_bits_read = add( *nb_bits_read, 1 );
     355       36617 :             move16();
     356       36617 :             hMasa->config.joinedSubframes = (UWord8) byteBuffer;
     357       36617 :             move16();
     358             :         }
     359             :         ELSE
     360             :         {
     361       10039 :             hMasa->config.joinedSubframes = FALSE;
     362       10039 :             move16();
     363             :         }
     364             : 
     365       46656 :         IF( EQ_16( st_ivas->mc_mode, MC_MODE_MCMASA ) )
     366             :         {
     367       10039 :             *nb_bits_read = add( *nb_bits_read, decode_lfe_to_total_energy_ratio_fx( hMasa->hMasaLfeSynth, st->bit_stream, &st->next_bit_pos, ivas_total_brate ) );
     368       10039 :             move16();
     369             :         }
     370             : 
     371             :         /* Once we know incoming configuration, we can config decoder further based on bitrate etc. */
     372       46656 :         if ( NE_32( ( error = ivas_masa_dec_config_fx( st_ivas ) ), IVAS_ERR_OK ) )
     373             :         {
     374           0 :             return error;
     375             :         }
     376             : 
     377             :         /* If we are under metadata bit budget limit and joined subframes is not signalled, then read LBR mode. */
     378       46656 :         test();
     379       46656 :         IF( LT_32( hMasa->config.max_metadata_bits, MINIMUM_BIT_BUDGET_NORMAL_META ) && EQ_16( hMasa->config.joinedSubframes, FALSE ) )
     380             :         {
     381             :             /* read low bitrate mode */
     382       22854 :             byteBuffer = st->bit_stream[st->next_bit_pos];
     383       22854 :             move16();
     384       22854 :             st->next_bit_pos = sub( st->next_bit_pos, 1 );
     385       22854 :             move16();
     386       22854 :             *nb_bits_read = add( *nb_bits_read, 1 );
     387       22854 :             move16();
     388       22854 :             low_bitrate_mode = byteBuffer;
     389       22854 :             move16();
     390             : 
     391       22854 :             IF( EQ_16( low_bitrate_mode, 1 ) )
     392             :             {
     393       19077 :                 hQMetaData->q_direction[0].cfg.nblocks = 1;
     394       19077 :                 move16();
     395             :             }
     396             :             ELSE
     397             :             {
     398        3777 :                 hQMetaData->q_direction[0].cfg.nbands = 1;
     399        3777 :                 move16();
     400             :             }
     401             :         }
     402             : 
     403             :         /* Remove already read bits from the bit budget */
     404       46656 :         hQMetaData->metadata_max_bits = sub( hQMetaData->metadata_max_bits, *nb_bits_read );
     405       46656 :         move16();
     406             : 
     407       46656 :         IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
     408             :         {
     409        6311 :             IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
     410             :             {
     411        1597 :                 IF( st_ivas->hDirAC != NULL )
     412             :                 {
     413        1225 :                     *nb_bits_read = add( *nb_bits_read, ivas_decode_masaism_metadata_fx( hQMetaData, st_ivas->hMasa, st_ivas->hMasaIsmData, st_ivas->nchan_ism, st->bit_stream, &st->next_bit_pos,
     414        1225 :                                                                                          st_ivas->hMasaIsmData->idx_separated_ism, ism_imp, st_ivas->hSpatParamRendCom->dirac_bs_md_write_idx, st_ivas->hSpatParamRendCom->dirac_md_buffer_length ) );
     415        1225 :                     move16();
     416        6380 :                     FOR( obj = 0; obj <= st_ivas->nchan_ism; obj++ )
     417             :                     {
     418        5155 :                         IF( EQ_16( st_ivas->hMasaIsmData->idx_separated_ism, obj ) )
     419             :                         {
     420             :                             Word16 sf;
     421             :                             Word16 meta_write_index;
     422             : 
     423        6125 :                             FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
     424             :                             {
     425        4900 :                                 meta_write_index = add( st_ivas->hSpatParamRendCom->dirac_bs_md_write_idx, sf ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length;
     426        4900 :                                 st_ivas->hMasaIsmData->azimuth_separated_ism[meta_write_index] = st_ivas->hMasaIsmData->azimuth_ism[obj][meta_write_index];
     427        4900 :                                 move16();
     428        4900 :                                 st_ivas->hMasaIsmData->elevation_separated_ism[meta_write_index] = st_ivas->hMasaIsmData->elevation_ism[obj][meta_write_index];
     429        4900 :                                 move16();
     430             :                             }
     431             :                         }
     432             :                     }
     433             :                 }
     434             :                 ELSE
     435             :                 {
     436         372 :                     *nb_bits_read = add( *nb_bits_read, ivas_decode_masaism_metadata_fx( hQMetaData, st_ivas->hMasa, st_ivas->hMasaIsmData, st_ivas->nchan_ism, st->bit_stream, &st->next_bit_pos,
     437         372 :                                                                                          st_ivas->hMasaIsmData->idx_separated_ism, ism_imp, 0, MAX_PARAM_SPATIAL_SUBFRAMES ) );
     438         372 :                     move16();
     439             :                 }
     440             :             }
     441             :         }
     442             : 
     443       46656 :         masa_total_brate = ivas_total_brate;
     444       46656 :         move32();
     445       46656 :         test();
     446       46656 :         IF( EQ_32( ivas_format, MASA_ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
     447             :         {
     448        2725 :             masa_total_brate = calculate_cpe_brate_MASA_ISM_fx( st_ivas->ism_mode, ivas_total_brate, st_ivas->nchan_ism );
     449             :         }
     450             : 
     451       46656 :         IF( GE_32( masa_total_brate, IVAS_384k ) )
     452             :         {
     453        2241 :             IF( GE_32( masa_total_brate, IVAS_512k ) )
     454             :             {
     455         787 :                 *nb_bits_read = add( *nb_bits_read,
     456         787 :                                      ivas_qmetadata_dec_decode_hr_384_512( hQMetaData, st->bit_stream, &st->next_bit_pos, hMasa->data.sph_grid16, 16, 4, hMasa->config.numCodingBands ) );
     457         787 :                 move16();
     458             :             }
     459             :             ELSE
     460             :             {
     461        1454 :                 *nb_bits_read = add( *nb_bits_read,
     462        1454 :                                      ivas_qmetadata_dec_decode_hr_384_512( hQMetaData, st->bit_stream, &st->next_bit_pos, hMasa->data.sph_grid16, 11, 3, hMasa->config.numCodingBands ) );
     463        1454 :                 move16();
     464             :             }
     465             :         }
     466             :         ELSE
     467             :         {
     468       44415 :             *nb_bits_read = add( *nb_bits_read,
     469       44415 :                                  ivas_qmetadata_dec_decode( hQMetaData, st->bit_stream, &st->next_bit_pos, 0 ) );
     470       44415 :             move16();
     471             :         }
     472             : 
     473       46656 :         test();
     474       46656 :         test();
     475       46656 :         IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) && NE_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) && NE_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
     476             :         {
     477             :             /* Modify spatial metadata based on the MASA-to-total energy ratios */
     478        1597 :             ivas_omasa_modify_masa_energy_ratios_fx( hQMetaData, st_ivas->hMasaIsmData->masa_to_total_energy_ratio_fx );
     479             :         }
     480             : 
     481             :         /* Get direction decoding quality. EC 1 and 2 are handled by the default value. */
     482       46656 :         if ( EQ_16( hQMetaData->ec_flag, 2 ) )
     483             :         {
     484        4548 :             hMasa->data.dir_decode_quality_fx = hQMetaData->dir_comp_ratio_fx; /* Q15 */
     485        4548 :             move16();
     486             :         }
     487             : 
     488       46656 :         hMasa->config.coherencePresent = !hQMetaData->all_coherence_zero;
     489       46656 :         move16();
     490             : 
     491       46656 :         IF( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
     492             :         {
     493        5137 :             index_16bits_fx( hQMetaData, hMasa->data.sph_grid16 );
     494             :         }
     495             : 
     496             :         /* If LBR mode is not disabled, then we restore metadata to 5 bands and 4 subframes based on the LBR mode. */
     497       46656 :         IF( NE_16( low_bitrate_mode, -1 ) )
     498             :         {
     499       22854 :             restore_lowbitrate_masa_fx( hQMetaData, low_bitrate_mode, hMasa->config.numCodingBands );
     500             :         }
     501       23802 :         ELSE IF( EQ_16( hMasa->config.joinedSubframes, TRUE ) )
     502             :         {
     503        5480 :             replicate_subframes_fx( hQMetaData );
     504             :         }
     505             :     }
     506        2060 :     ELSE IF( st->bfi == 0 && EQ_32( ivas_format, MASA_FORMAT ) && EQ_32( ivas_total_brate, IVAS_SID_5k2 ) )
     507             :     {
     508         205 :         IF( hQMetaData->q_direction == NULL )
     509             :         {
     510             :             /* replicate ivas_masa_dec_config() in case that first good received frame is SID frame */
     511           0 :             if ( NE_32( ( error = ivas_masa_dec_config_fx( st_ivas ) ), IVAS_ERR_OK ) )
     512             :             {
     513           0 :                 return error;
     514             :             }
     515             : 
     516           0 :             ivas_masa_set_elements_fx( ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, hQMetaData, &st_ivas->element_mode_init, &st_ivas->nSCE, &st_ivas->nCPE, st_ivas->ivas_format, st_ivas->ism_mode, 0 );
     517             : 
     518           0 :             hQMetaData->metadata_max_bits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC;
     519           0 :             move16();
     520             : 
     521           0 :             if ( NE_32( ( error = ivas_qmetadata_allocate_memory_fx( hQMetaData, 5, 1, 0 ) ), IVAS_ERR_OK ) )
     522             :             {
     523           0 :                 return error;
     524             :             }
     525             : 
     526           0 :             hQMetaData->numTwoDirBands = hMasa->config.numTwoDirBands;
     527           0 :             move16();
     528           0 :             hQMetaData->useLowerRes = 0;
     529           0 :             move16();
     530             : 
     531           0 :             hQMetaData->q_direction->cfg.nbands = 5;
     532           0 :             move16();
     533           0 :             hQMetaData->q_direction->cfg.nblocks = 4;
     534           0 :             move16();
     535             : 
     536           0 :             test();
     537           0 :             IF( EQ_32( ivas_format, MC_FORMAT ) && EQ_32( st_ivas->mc_mode, MC_MODE_MCMASA ) )
     538             :             {
     539           0 :                 hQMetaData->q_direction->cfg.mc_ls_setup = ivas_mc_map_output_config_to_mc_ls_setup_fx( st_ivas->transport_config );
     540             :             }
     541             :             ELSE
     542             :             {
     543           0 :                 hQMetaData->q_direction->cfg.mc_ls_setup = MC_LS_SETUP_INVALID;
     544             :             }
     545           0 :             move16();
     546             :         }
     547             : 
     548         205 :         tmp_elem_mode = -1;
     549         205 :         move16();
     550             : 
     551         205 :         *nb_bits_read = add( *nb_bits_read,
     552         205 :                              ivas_qmetadata_dec_sid_decode( hQMetaData, st->bit_stream, &( st->next_bit_pos ), st_ivas->nchan_transport, &tmp_elem_mode, ivas_format ) );
     553         205 :         move16();
     554             : 
     555         205 :         IF( EQ_16( st_ivas->nchan_transport, 2 ) )
     556             :         {
     557          74 :             assert( st_ivas->nCPE > 0 );
     558          74 :             st_ivas->hCPE[0]->element_mode = tmp_elem_mode;
     559          74 :             move16();
     560             :         }
     561         205 :         *nb_bits_read = add( *nb_bits_read, SID_FORMAT_NBITS );
     562         205 :         move16();
     563             :     }
     564        1855 :     ELSE IF( st->bfi == 0 && EQ_32( ivas_format, MASA_FORMAT ) && EQ_32( ivas_total_brate, FRAME_NO_DATA ) )
     565             :     {
     566        1244 :         IF( hQMetaData->q_direction == NULL )
     567             :         {
     568           0 :             IF( ( error = ivas_masa_dec_config_fx( st_ivas ) ) != IVAS_ERR_OK )
     569             :             {
     570           0 :                 return error;
     571             :             }
     572             :         }
     573             :     }
     574             : 
     575       48716 :     IF( st_ivas->hDirAC != NULL )
     576             :     {
     577       38772 :         dirac_bs_md_write_idx = st_ivas->hSpatParamRendCom->dirac_bs_md_write_idx; /* Store the write-index for this frame */
     578       38772 :         move16();
     579             : 
     580       38772 :         ivas_qmetadata_to_dirac_fx( hQMetaData, st_ivas->hDirAC, hMasa, st_ivas->hSpatParamRendCom, ivas_total_brate, ivas_format, 0, 0 );
     581             :     }
     582             : 
     583       48716 :     IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
     584             :     {
     585        6418 :         IF( hQMetaData->q_direction == NULL )
     586             :         {
     587           0 :             if ( NE_32( ( error = ivas_masa_dec_config_fx( st_ivas ) ), IVAS_ERR_OK ) )
     588             :             {
     589           0 :                 return error;
     590             :             }
     591             :         }
     592             : 
     593        6418 :         IF( st_ivas->hDirAC != NULL )
     594             :         {
     595             :             Word16 b;
     596             :             Word16 block;
     597             :             Word16 meta_write_index;
     598             : 
     599        8834 :             FOR( i = 0; i < st_ivas->hSpatParamRendCom->numIsmDirections; i++ )
     600             :             {
     601       19970 :                 FOR( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
     602             :                 {
     603       15976 :                     meta_write_index = add( dirac_bs_md_write_idx, block ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length;
     604             : 
     605      808936 :                     FOR( b = 0; b < st_ivas->hSpatParamRendCom->num_freq_bands; b++ )
     606             :                     {
     607     1585920 :                         st_ivas->hSpatParamRendCom->diffuseness_vector_fx[meta_write_index][b] = L_sub( st_ivas->hSpatParamRendCom->diffuseness_vector_fx[meta_write_index][b],
     608      792960 :                                                                                                         st_ivas->hMasaIsmData->energy_ratio_ism_fx[i][meta_write_index][b] ); // Q30
     609      792960 :                         move32();
     610             :                     }
     611             :                 }
     612             :             }
     613             : 
     614       24200 :             FOR( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
     615             :             {
     616       19360 :                 meta_write_index = add( dirac_bs_md_write_idx, block ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length;
     617             : 
     618      995120 :                 FOR( b = 0; b < st_ivas->hSpatParamRendCom->num_freq_bands; b++ )
     619             :                 {
     620      975760 :                     st_ivas->hSpatParamRendCom->diffuseness_vector_fx[meta_write_index][b] = L_max( 0, st_ivas->hSpatParamRendCom->diffuseness_vector_fx[meta_write_index][b] ); // Q30
     621      975760 :                     move32();
     622             :                 }
     623             :             }
     624             :         }
     625             :     }
     626             : 
     627       48716 :     st->next_bit_pos = next_bit_pos_orig;
     628       48716 :     move16();
     629             : 
     630       48716 :     IF( EQ_32( ivas_format, MASA_ISM_FORMAT ) )
     631             :     {
     632             :         Word32 cpe_brate;
     633        6418 :         cpe_brate = calculate_cpe_brate_MASA_ISM_fx( st_ivas->ism_mode, ivas_total_brate, st_ivas->nchan_ism );
     634             : 
     635        6418 :         test();
     636        6418 :         test();
     637        6418 :         IF( EQ_16( st_ivas->nCPE, 1 ) && st_ivas->hCPE[0]->hStereoDft != NULL && st_ivas->hCPE[0]->hStereoDft->hConfig != NULL )
     638             :         {
     639        2936 :             IF( LT_32( cpe_brate, MASA_STEREO_MIN_BITRATE ) )
     640             :             {
     641        1207 :                 st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = 1;
     642        1207 :                 move16();
     643             :             }
     644             :             ELSE
     645             :             {
     646        1729 :                 st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = 0;
     647        1729 :                 move16();
     648             :             }
     649             : 
     650        2936 :             if ( LE_32( ivas_total_brate, IVAS_SID_5k2 ) )
     651             :             {
     652           0 :                 st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = 0;
     653           0 :                 move32();
     654             :             }
     655             :         }
     656             :     }
     657             :     ELSE
     658             :     {
     659       42298 :         test();
     660       42298 :         test();
     661       42298 :         test();
     662       42298 :         IF( EQ_32( ivas_format, MASA_FORMAT ) && EQ_16( st_ivas->nCPE, 1 ) && st_ivas->hCPE[0]->hStereoDft != NULL && st_ivas->hCPE[0]->hStereoDft->hConfig != NULL )
     663             :         {
     664        8835 :             IF( LT_32( ivas_total_brate, MASA_STEREO_MIN_BITRATE ) )
     665             :             {
     666        4463 :                 st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = 1;
     667        4463 :                 move16();
     668             :             }
     669             :             ELSE
     670             :             {
     671        4372 :                 st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = 0;
     672        4372 :                 move16();
     673             :             }
     674             : 
     675        8835 :             if ( LE_32( ivas_total_brate, IVAS_SID_5k2 ) )
     676             :             {
     677         530 :                 st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = 0;
     678         530 :                 move16();
     679             :             }
     680             :         }
     681             :     }
     682             : 
     683       48716 :     test();
     684       48716 :     IF( EQ_32( ivas_format, MASA_FORMAT ) && EQ_16( st_ivas->nCPE, 1 ) )
     685             :     {
     686       18408 :         st_ivas->hCPE[0]->hCoreCoder[0]->masa_sid_format = 0;
     687       18408 :         move16();
     688             : 
     689       18408 :         IF( LE_32( st_ivas->hDecoderConfig->last_ivas_total_brate, IVAS_SID_5k2 ) )
     690             :         {
     691         530 :             st_ivas->hCPE[0]->hCoreCoder[0]->masa_sid_format = 1;
     692         530 :             move16();
     693             : 
     694         530 :             if ( GE_32( ivas_total_brate, IVAS_SID_5k2 ) )
     695             :             {
     696          74 :                 st_ivas->hCPE[0]->element_brate = ivas_total_brate;
     697          74 :                 move32();
     698             :             }
     699             :         }
     700             :     }
     701             : 
     702       48716 :     test();
     703       48716 :     test();
     704       48716 :     IF( ( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) || EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) ) && EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
     705             :     {
     706        5462 :         create_masa_ext_out_meta_fx( hMasa, hQMetaData, st_ivas->nchan_transport );
     707             :     }
     708             : 
     709       48716 :     return error /* *nb_bits_read*/;
     710             : }
     711             : 
     712             : 
     713             : /*-------------------------------------------------------------------*
     714             :  * ivas_masa_dec_open()
     715             :  *
     716             :  *
     717             :  *-------------------------------------------------------------------*/
     718             : 
     719         343 : ivas_error ivas_masa_dec_open_fx(
     720             :     Decoder_Struct *st_ivas /* i/o: IVAS decoder handle  */
     721             : )
     722             : {
     723             :     MASA_DECODER_HANDLE hMasa;
     724             :     ivas_error error;
     725             :     Word16 i;
     726             :     Word32 ism_total_brate;
     727             : 
     728         343 :     error = IVAS_ERR_OK;
     729         343 :     move16();
     730             : 
     731         343 :     IF( ( hMasa = (MASA_DECODER_HANDLE) malloc( sizeof( MASA_DECODER ) ) ) == NULL )
     732             :     {
     733           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
     734             :     }
     735             : 
     736         343 :     ism_total_brate = 0;
     737         343 :     move32();
     738             : 
     739         343 :     test();
     740         343 :     test();
     741         343 :     test();
     742         343 :     test();
     743         343 :     IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) && GT_16( st_ivas->nSCE, 0 ) && ( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) || EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) || EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) ) )
     744             :     {
     745          89 :         FOR( i = 0; i < st_ivas->nSCE; i++ )
     746             :         {
     747          57 :             ism_total_brate = L_add( ism_total_brate, st_ivas->hSCE[i]->element_brate );
     748             :         }
     749             :     }
     750             : 
     751         343 :     ivas_masa_set_elements_fx( st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, st_ivas->hQMetaData, &st_ivas->element_mode_init, &st_ivas->nSCE, &st_ivas->nCPE, st_ivas->ivas_format, st_ivas->ism_mode, ism_total_brate );
     752             : 
     753         343 :     Copy( DirAC_block_grouping, hMasa->config.block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 );
     754         343 :     Copy( MASA_band_grouping_24, hMasa->config.band_grouping, MASA_FREQUENCY_BANDS + 1 );
     755         343 :     hMasa->config.numberOfDirections = 1;
     756         343 :     move16();
     757         343 :     hMasa->config.joinedSubframes = FALSE;
     758         343 :     move16();
     759             : 
     760             :     /* Create spherical grid only for external output */
     761         343 :     IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
     762             :     {
     763          20 :         IF( ( hMasa->data.sph_grid16 = (SPHERICAL_GRID_DATA *) malloc( sizeof( SPHERICAL_GRID_DATA ) ) ) == NULL )
     764             :         {
     765           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
     766             :         }
     767             : 
     768          20 :         generate_gridEq_fx( hMasa->data.sph_grid16 );
     769             : 
     770          20 :         IF( ( hMasa->data.extOutMeta = (MASA_DECODER_EXT_OUT_META *) malloc( sizeof( MASA_DECODER_EXT_OUT_META ) ) ) == NULL )
     771             :         {
     772           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
     773             :         }
     774             :     }
     775             :     ELSE
     776             :     {
     777         323 :         hMasa->data.sph_grid16 = NULL;
     778         323 :         hMasa->data.extOutMeta = NULL;
     779             :     }
     780             : 
     781         343 :     IF( EQ_16( st_ivas->mc_mode, MC_MODE_MCMASA ) )
     782             :     {
     783         231 :         error = init_lfe_synth_data_fx( st_ivas, hMasa );
     784             :     }
     785             :     ELSE
     786             :     {
     787         112 :         hMasa->hMasaLfeSynth = NULL;
     788             :     }
     789             : 
     790         343 :     st_ivas->hMasa = hMasa;
     791             : 
     792             :     /* allocate transport channels*/
     793         343 :     test();
     794         343 :     test();
     795         343 :     test();
     796         343 :     test();
     797         343 :     IF( st_ivas->hTcBuffer == NULL && NE_16( st_ivas->renderer_type, RENDERER_DISABLE ) && NE_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) && NE_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) && NE_16( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) )
     798             :     {
     799             :         Word16 nchan_to_allocate, nchan_transport;
     800             :         TC_BUFFER_MODE buffer_mode;
     801             : 
     802          47 :         buffer_mode = TC_BUFFER_MODE_RENDERER;
     803          47 :         move16();
     804          47 :         test();
     805          47 :         test();
     806          47 :         test();
     807          47 :         IF( EQ_16( st_ivas->mc_mode, MC_MODE_MCMASA ) && ( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_STEREO ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_MONO ) ) )
     808             :         {
     809           3 :             buffer_mode = TC_BUFFER_MODE_BUFFER;
     810           3 :             move16();
     811             :         }
     812          44 :         ELSE IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) && EQ_32( st_ivas->renderer_type, RENDERER_MONO_DOWNMIX ) )
     813             :         {
     814           5 :             buffer_mode = TC_BUFFER_MODE_BUFFER;
     815           5 :             move16();
     816             :         }
     817             : 
     818          47 :         nchan_transport = ivas_jbm_dec_get_num_tc_channels_fx( st_ivas );
     819          47 :         nchan_to_allocate = nchan_transport;
     820          47 :         move16();
     821             : 
     822          47 :         test();
     823          47 :         test();
     824          47 :         IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) && EQ_32( st_ivas->renderer_type, RENDERER_MONO_DOWNMIX ) )
     825             :         {
     826           5 :             nchan_transport = 1;
     827           5 :             move16();
     828           5 :             nchan_to_allocate = 1;
     829           5 :             move16();
     830             :         }
     831          42 :         ELSE IF( EQ_16( st_ivas->nchan_transport, 1 ) && EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) )
     832             :         {
     833             :             /* addtl channel for CNG */
     834           9 :             nchan_to_allocate = add( nchan_to_allocate, 1 );
     835             :         }
     836             : 
     837          47 :         IF( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, buffer_mode, nchan_transport, nchan_to_allocate, nchan_to_allocate, NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK )
     838             :         {
     839           0 :             return error;
     840             :         }
     841             :     }
     842             : 
     843         343 :     return error;
     844             : }
     845             : 
     846             : 
     847             : /*-----------------------------------------------------------------------*
     848             :  * ivas_masa_dec_close()
     849             :  *
     850             :  * close MASA decoder
     851             :  *-----------------------------------------------------------------------*/
     852             : 
     853        1367 : void ivas_masa_dec_close_fx(
     854             :     MASA_DECODER_HANDLE *hMasa_out /* i/o: MASA metadata structure      */
     855             : )
     856             : {
     857             :     MASA_DECODER_HANDLE hMasa;
     858             : 
     859        1367 :     test();
     860        1367 :     IF( hMasa_out == NULL || *hMasa_out == NULL )
     861             :     {
     862        1024 :         return;
     863             :     }
     864             : 
     865         343 :     hMasa = *hMasa_out;
     866             : 
     867             :     /* Free spherical grid memory if in use */
     868         343 :     IF( hMasa->data.sph_grid16 != NULL )
     869             :     {
     870          45 :         free( hMasa->data.sph_grid16 );
     871          45 :         hMasa->data.sph_grid16 = NULL;
     872             :     }
     873             : 
     874         343 :     IF( hMasa->data.extOutMeta != NULL )
     875             :     {
     876          20 :         free( hMasa->data.extOutMeta );
     877          20 :         hMasa->data.extOutMeta = NULL;
     878             :     }
     879             : 
     880         343 :     IF( hMasa->hMasaLfeSynth != NULL )
     881             :     {
     882         231 :         IF( hMasa->hMasaLfeSynth->lfeSynthRingBuffer_fx != NULL )
     883             :         {
     884           6 :             free( hMasa->hMasaLfeSynth->lfeSynthRingBuffer_fx );
     885           6 :             hMasa->hMasaLfeSynth->lfeSynthRingBuffer_fx = NULL;
     886             :         }
     887         231 :         IF( hMasa->hMasaLfeSynth->lfeSynthRingBuffer2_fx != NULL )
     888             :         {
     889           6 :             free( hMasa->hMasaLfeSynth->lfeSynthRingBuffer2_fx );
     890           6 :             hMasa->hMasaLfeSynth->lfeSynthRingBuffer2_fx = NULL;
     891             :         }
     892         231 :         IF( hMasa->hMasaLfeSynth->delayBuffer_syncLp_fx != NULL )
     893             :         {
     894           6 :             free( hMasa->hMasaLfeSynth->delayBuffer_syncLp_fx );
     895           6 :             hMasa->hMasaLfeSynth->delayBuffer_syncLp_fx = NULL;
     896             :         }
     897         231 :         IF( hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_fx != NULL )
     898             :         {
     899           6 :             free( hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_fx );
     900           6 :             hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_fx = NULL;
     901             :         }
     902         231 :         free( hMasa->hMasaLfeSynth );
     903         231 :         hMasa->hMasaLfeSynth = NULL;
     904             :     }
     905             : 
     906         343 :     free( *hMasa_out );
     907         343 :     *hMasa_out = NULL;
     908             : 
     909         343 :     return;
     910             : }
     911             : 
     912             : 
     913             : /*-------------------------------------------------------------------*
     914             :  * ivas_masa_dec_config()
     915             :  *
     916             :  * Frame-by-frame configuration of MASA decoder
     917             :  *-------------------------------------------------------------------*/
     918             : 
     919       46656 : static ivas_error ivas_masa_dec_config_fx(
     920             :     Decoder_Struct *st_ivas /* i/o: IVAS decoder handle  */
     921             : )
     922             : {
     923             :     Word16 i;
     924             :     MASA_DECODER_HANDLE hMasa;
     925             :     UWord8 maxBand;
     926             :     Word16 maxBin;
     927             :     ivas_error error;
     928             :     Word32 ivas_total_brate;
     929             :     Word32 ism_total_brate;
     930       46656 :     error = IVAS_ERR_OK;
     931       46656 :     move32();
     932       46656 :     hMasa = st_ivas->hMasa;
     933             : 
     934       46656 :     ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
     935       46656 :     move32();
     936       46656 :     ism_total_brate = 0;
     937       46656 :     move32();
     938             : 
     939       46656 :     test();
     940       46656 :     test();
     941       46656 :     test();
     942       46656 :     test();
     943       46656 :     IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) && st_ivas->nSCE > 0 && ( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) ) )
     944             :     {
     945       17129 :         FOR( i = 0; i < st_ivas->nSCE; i++ )
     946             :         {
     947       10818 :             ism_total_brate = L_add( ism_total_brate, st_ivas->hSCE[i]->element_brate );
     948             :         }
     949             :     }
     950             : 
     951       46656 :     ivas_masa_set_elements_fx( ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, st_ivas->hQMetaData, &st_ivas->element_mode_init, &st_ivas->nSCE, &st_ivas->nCPE, st_ivas->ivas_format, st_ivas->ism_mode, ism_total_brate );
     952             : 
     953       46656 :     IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
     954             :     {
     955        6311 :         ivas_masa_set_coding_config_fx( &( hMasa->config ), hMasa->data.band_mapping, st_ivas->hCPE[0]->element_brate, st_ivas->nchan_transport, MC_MODE_NONE );
     956             :     }
     957             :     ELSE
     958             :     {
     959       40345 :         ivas_masa_set_coding_config_fx( &( hMasa->config ), hMasa->data.band_mapping, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, ( EQ_32( st_ivas->ivas_format, MC_FORMAT ) && EQ_32( st_ivas->mc_mode, MC_MODE_MCMASA ) ) );
     960             :     }
     961             : 
     962       46656 :     test();
     963       46656 :     test();
     964       46656 :     IF( ( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) || EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) ) && EQ_32( st_ivas->hDecoderConfig->ivas_total_brate, IVAS_512k ) )
     965             :     {
     966        1166 :         hMasa->config.mergeRatiosOverSubframes = 0;
     967        1166 :         move16();
     968             : 
     969             :         /* initialize spherical grid */
     970        1166 :         IF( hMasa->data.sph_grid16 == NULL )
     971             :         {
     972          25 :             IF( ( hMasa->data.sph_grid16 = (SPHERICAL_GRID_DATA *) malloc( sizeof( SPHERICAL_GRID_DATA ) ) ) == NULL )
     973             :             {
     974           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA data handle\n" ) );
     975             :             }
     976          25 :             generate_gridEq_fx( hMasa->data.sph_grid16 );
     977             :         }
     978             :     }
     979       46656 :     st_ivas->hQMetaData->metadata_max_bits = hMasa->config.max_metadata_bits;
     980       46656 :     move16();
     981       46656 :     st_ivas->hQMetaData->bandMap = hMasa->data.band_mapping;
     982       46656 :     move16();
     983       46656 :     st_ivas->hQMetaData->nchan_transport = st_ivas->nchan_transport;
     984       46656 :     move16();
     985             : 
     986       46656 :     IF( NE_32( ( error = ivas_qmetadata_allocate_memory_fx( st_ivas->hQMetaData, hMasa->config.numCodingBands, hMasa->config.numberOfDirections, hMasa->config.useCoherence ) ), IVAS_ERR_OK ) )
     987             :     {
     988           0 :         return error;
     989             :     }
     990             : 
     991       46656 :     st_ivas->hQMetaData->numTwoDirBands = st_ivas->hMasa->config.numTwoDirBands;
     992       46656 :     move16();
     993       46656 :     st_ivas->hQMetaData->useLowerRes = 0;
     994       46656 :     move16();
     995             : 
     996       98565 :     FOR( i = 0; i < st_ivas->hQMetaData->no_directions; i++ )
     997             :     {
     998       51909 :         st_ivas->hQMetaData->q_direction[i].cfg.nbands = hMasa->config.numCodingBands;
     999       51909 :         move16();
    1000       51909 :         IF( EQ_16( hMasa->config.joinedSubframes, TRUE ) )
    1001             :         {
    1002        6458 :             st_ivas->hQMetaData->q_direction[i].cfg.nblocks = 1;
    1003             :         }
    1004             :         ELSE
    1005             :         {
    1006       45451 :             st_ivas->hQMetaData->q_direction[i].cfg.nblocks = 4;
    1007             :         }
    1008       51909 :         move16();
    1009             : 
    1010       51909 :         test();
    1011       51909 :         IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) && EQ_16( st_ivas->mc_mode, MC_MODE_MCMASA ) )
    1012             :         {
    1013       10039 :             st_ivas->hQMetaData->q_direction[i].cfg.mc_ls_setup = ivas_mc_map_output_config_to_mc_ls_setup_fx( st_ivas->transport_config );
    1014       10039 :             move32();
    1015             :         }
    1016             :         ELSE
    1017             :         {
    1018       41870 :             st_ivas->hQMetaData->q_direction[i].cfg.mc_ls_setup = MC_LS_SETUP_INVALID;
    1019       41870 :             move32();
    1020             :         }
    1021             :     }
    1022             : 
    1023       46656 :     ivas_set_qmetadata_maxbit_req_fx( st_ivas->hQMetaData, st_ivas->ivas_format );
    1024             : 
    1025             :     /* Find maximum band usable */
    1026       46656 :     maxBin = extract_l( Mpy_32_32( st_ivas->hDecoderConfig->output_Fs, INV_CLDFB_BANDWIDTH_Q31 ) );
    1027       46656 :     maxBand = 0;
    1028       46656 :     move16();
    1029     1198595 :     WHILE( LE_16( maxBand, MASA_FREQUENCY_BANDS ) && LE_16( MASA_band_grouping_24[maxBand], maxBin ) )
    1030             :     {
    1031     1151939 :         maxBand = (UWord8) add( maxBand, 1 );
    1032             :     }
    1033       46656 :     maxBand = (UWord8) sub( maxBand, 1 );
    1034             : 
    1035       46656 :     IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
    1036             :     {
    1037             :         /* need to apply the sampling rate correction also for the EXT output MASA meta buffer */
    1038        5137 :         masa_sample_rate_band_correction_fx( &( hMasa->config ), hMasa->data.band_mapping, st_ivas->hQMetaData, maxBand, 0, hMasa->data.extOutMeta );
    1039             :     }
    1040             :     ELSE
    1041             :     {
    1042       41519 :         masa_sample_rate_band_correction_fx( &( hMasa->config ), hMasa->data.band_mapping, st_ivas->hQMetaData, maxBand, 0, NULL );
    1043             :     }
    1044             : 
    1045       46656 :     return error;
    1046             : }
    1047             : 
    1048             : 
    1049             : /*-------------------------------------------------------------------*
    1050             :  * ivas_masa_prerender_fx()
    1051             :  *
    1052             :  * Apply gaining and copying of transport signals when needed
    1053             :  *-------------------------------------------------------------------*/
    1054             : 
    1055       32208 : void ivas_masa_prerender_fx(
    1056             :     Decoder_Struct *st_ivas,    /* i/o: IVAS decoder handle                                         */
    1057             :     Word32 *output_fx[],        /* i/o: synthesized core-coder transport channels                   */
    1058             :     Word16 *q_shift,            /* o  : specifies how much the Q-factor of output has changed by.   */
    1059             :     const Word16 output_frame,  /* i  : output frame length per channel                             */
    1060             :     const Word16 nchan_remapped /* i  : number of transports used in core                           */
    1061             : )
    1062             : {
    1063       32208 :     *q_shift = 0;
    1064       32208 :     move16();
    1065             : 
    1066       32208 :     test();
    1067       32208 :     test();
    1068       32208 :     IF( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) && EQ_16( st_ivas->nchan_transport, 2 ) && EQ_16( nchan_remapped, 1 ) )
    1069             :     {
    1070        4479 :         IF( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
    1071             :         {
    1072         340 :             Copy32( output_fx[0], output_fx[1], output_frame ); /* Copy mono signal to stereo output channels */
    1073             :         }
    1074             :         ELSE
    1075             :         {
    1076        4139 :             test();
    1077        4139 :             IF( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) || EQ_32( st_ivas->renderer_type, RENDERER_DISABLE ) )
    1078             :             {
    1079        2928 :                 v_multc_fixed( output_fx[0], SQRT2_FIXED, output_fx[0], output_frame ); /* q + 30 - 31 = q - 1*/ /* Gain transport signal when transmitting mono with cpe in order to match loudness */
    1080        2928 :                 *q_shift = -1;                                                                                   /* Q has decreased by 1. */
    1081        2928 :                 move16();
    1082             :             }
    1083             :         }
    1084             :     }
    1085             : 
    1086       32208 :     return;
    1087             : }
    1088             : 
    1089             : 
    1090             : /*-------------------------------------------------------------------*
    1091             :  * Local functions
    1092             :  *-------------------------------------------------------------------*/
    1093             : 
    1094        5137 : static void index_16bits_fx(
    1095             :     IVAS_QMETADATA_HANDLE hQMetaData,
    1096             :     SPHERICAL_GRID_DATA *Sph_Grid16 )
    1097             : {
    1098             :     Word16 d, band, block;
    1099             : 
    1100       11994 :     FOR( d = 0; d < hQMetaData->no_directions; d++ )
    1101             :     {
    1102             :         /* Note: The band information is read from the first direction as it contains the full information.  */
    1103       70828 :         FOR( band = 0; band < hQMetaData->q_direction[0].cfg.nbands; band++ )
    1104             :         {
    1105      273865 :             FOR( block = 0; block < hQMetaData->q_direction[0].cfg.nblocks; block++ )
    1106             :             {
    1107      419788 :                 hQMetaData->q_direction[d].band_data[band].spherical_index[block] = index_theta_phi_16_fx( &( hQMetaData->q_direction[d].band_data[band].elevation_fx[block] ),
    1108      209894 :                                                                                                            &( hQMetaData->q_direction[d].band_data[band].azimuth_fx[block] ), Sph_Grid16 );
    1109      209894 :                 move16();
    1110             :             }
    1111             :         }
    1112             :     }
    1113             : 
    1114        5137 :     return;
    1115             : }
    1116             : 
    1117             : 
    1118             : /* Replicate subframe data when there is only one subframe sent */
    1119        5480 : static void replicate_subframes_fx(
    1120             :     IVAS_QMETADATA_HANDLE hQMetaData )
    1121             : {
    1122             :     Word16 sf, band, dir, nbands, ndirs;
    1123             : 
    1124        5480 :     nbands = hQMetaData->q_direction->cfg.nbands;
    1125        5480 :     move16();
    1126        5480 :     ndirs = hQMetaData->no_directions;
    1127        5480 :     move16();
    1128             : 
    1129       21920 :     FOR( sf = 1; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
    1130             :     {
    1131      203676 :         FOR( band = 0; band < nbands; band++ )
    1132             :         {
    1133      426204 :             FOR( dir = 0; dir < ndirs; dir++ )
    1134             :             {
    1135      238968 :                 hQMetaData->q_direction[dir].band_data[band].spherical_index[sf] = hQMetaData->q_direction[dir].band_data[band].spherical_index[0];
    1136      238968 :                 move16();
    1137      238968 :                 hQMetaData->q_direction[dir].band_data[band].azimuth_fx[sf] = hQMetaData->q_direction[dir].band_data[band].azimuth_fx[0]; // Q22
    1138      238968 :                 move32();
    1139      238968 :                 hQMetaData->q_direction[dir].band_data[band].elevation_fx[sf] = hQMetaData->q_direction[dir].band_data[band].elevation_fx[0]; // Q22
    1140      238968 :                 move32();
    1141      238968 :                 hQMetaData->q_direction[dir].band_data[band].energy_ratio_fx[sf] = hQMetaData->q_direction[dir].band_data[band].energy_ratio_fx[0]; // Q30
    1142      238968 :                 move32();
    1143             : 
    1144      238968 :                 if ( hQMetaData->q_direction[dir].coherence_band_data != NULL )
    1145             :                 {
    1146      189036 :                     hQMetaData->q_direction[dir].coherence_band_data[band].spread_coherence[sf] = hQMetaData->q_direction[dir].coherence_band_data[band].spread_coherence[0];
    1147      189036 :                     move16();
    1148             :                 }
    1149             :             }
    1150             : 
    1151      187236 :             if ( hQMetaData->surcoh_band_data != NULL )
    1152             :             {
    1153      137304 :                 hQMetaData->surcoh_band_data[band].surround_coherence[sf] = hQMetaData->surcoh_band_data[band].surround_coherence[0];
    1154      137304 :                 move16();
    1155             :             }
    1156             :         }
    1157             :     }
    1158             : 
    1159        5480 :     return;
    1160             : }
    1161             : 
    1162             : 
    1163       22854 : static void restore_lowbitrate_masa_fx(
    1164             :     IVAS_QMETADATA_HANDLE hQMetaData,
    1165             :     const Word16 low_bitrate_mode,
    1166             :     const Word16 numCodingBands )
    1167             : {
    1168             :     Word16 sf, band;
    1169             : 
    1170       22854 :     IF( EQ_16( low_bitrate_mode, 1 ) )
    1171             :     {
    1172             :         /* With signal 1, we are in 5 frequency bands, 1 subframe mode. */
    1173             :         /* Replicate data to all subframes */
    1174       76308 :         FOR( sf = 1; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
    1175             :         {
    1176      343386 :             FOR( band = 0; band < numCodingBands; band++ )
    1177             :             {
    1178             : 
    1179      286155 :                 hQMetaData->q_direction[0].band_data[band].spherical_index[sf] = hQMetaData->q_direction[0].band_data[band].spherical_index[0];
    1180      286155 :                 move16();
    1181      286155 :                 hQMetaData->q_direction[0].band_data[band].azimuth_fx[sf] = hQMetaData->q_direction[0].band_data[band].azimuth_fx[0]; // Q22
    1182      286155 :                 move32();
    1183      286155 :                 hQMetaData->q_direction[0].band_data[band].elevation_fx[sf] = hQMetaData->q_direction[0].band_data[band].elevation_fx[0]; // Q22
    1184      286155 :                 move32();
    1185      286155 :                 hQMetaData->q_direction[0].band_data[band].energy_ratio_fx[sf] = hQMetaData->q_direction[0].band_data[band].energy_ratio_fx[0]; // Q30
    1186      286155 :                 move32();
    1187             : 
    1188      286155 :                 if ( hQMetaData->q_direction[0].coherence_band_data != NULL )
    1189             :                 {
    1190       78735 :                     hQMetaData->q_direction[0].coherence_band_data[band].spread_coherence[sf] = hQMetaData->q_direction[0].coherence_band_data[band].spread_coherence[0];
    1191       78735 :                     move16();
    1192             :                 }
    1193      286155 :                 if ( hQMetaData->surcoh_band_data != NULL )
    1194             :                 {
    1195       78735 :                     hQMetaData->surcoh_band_data[band].surround_coherence[sf] = hQMetaData->surcoh_band_data[band].surround_coherence[0];
    1196       78735 :                     move16();
    1197             :                 }
    1198             :             }
    1199             :         }
    1200       19077 :         hQMetaData->q_direction->cfg.nblocks = 4;
    1201       19077 :         move16();
    1202             :     }
    1203             :     ELSE
    1204             :     {
    1205             :         /* With signal 0, we are in 1 frequency bands, 4 subframes mode. */
    1206             :         /* Replicate data to all bands */
    1207       18885 :         FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
    1208             :         {
    1209       75540 :             FOR( band = 1; band < numCodingBands; band++ )
    1210             :             {
    1211       60432 :                 hQMetaData->q_direction[0].band_data[band].spherical_index[sf] = hQMetaData->q_direction[0].band_data[0].spherical_index[sf];
    1212       60432 :                 move16();
    1213       60432 :                 hQMetaData->q_direction[0].band_data[band].azimuth_fx[sf] = hQMetaData->q_direction[0].band_data[0].azimuth_fx[sf]; // Q22
    1214       60432 :                 move32();
    1215       60432 :                 hQMetaData->q_direction[0].band_data[band].elevation_fx[sf] = hQMetaData->q_direction[0].band_data[0].elevation_fx[sf]; // Q22
    1216       60432 :                 move32();
    1217       60432 :                 hQMetaData->q_direction[0].band_data[band].energy_ratio_fx[sf] = hQMetaData->q_direction[0].band_data[0].energy_ratio_fx[sf]; // Q30
    1218       60432 :                 move32();
    1219             : 
    1220       60432 :                 if ( hQMetaData->q_direction[0].coherence_band_data != NULL )
    1221             :                 {
    1222       20160 :                     hQMetaData->q_direction[0].coherence_band_data[band].spread_coherence[sf] = hQMetaData->q_direction[0].coherence_band_data[0].spread_coherence[sf];
    1223       20160 :                     move16();
    1224             :                 }
    1225       60432 :                 if ( hQMetaData->surcoh_band_data != NULL )
    1226             :                 {
    1227       20160 :                     hQMetaData->surcoh_band_data[band].surround_coherence[sf] = hQMetaData->surcoh_band_data[0].surround_coherence[sf];
    1228       20160 :                     move16();
    1229             :                 }
    1230             :             }
    1231             :         }
    1232        3777 :         hQMetaData->q_direction->cfg.nbands = numCodingBands;
    1233        3777 :         move16();
    1234             :     }
    1235             : 
    1236       22854 :     return;
    1237             : }
    1238             : 
    1239             : 
    1240         231 : static ivas_error init_lfe_synth_data_fx(
    1241             :     Decoder_Struct *st_ivas,  /* i  : IVAS decoder struct     */
    1242             :     MASA_DECODER_HANDLE hMasa /* i/o: MASA decoder structure  */
    1243             : )
    1244             : {
    1245             :     Word32 output_Fs;
    1246             :     AUDIO_CONFIG output_config;
    1247             : 
    1248         231 :     output_Fs = st_ivas->hDecoderConfig->output_Fs;
    1249         231 :     move16();
    1250         231 :     output_config = st_ivas->hDecoderConfig->output_config;
    1251         231 :     move32();
    1252             : 
    1253         231 :     IF( ( hMasa->hMasaLfeSynth = (MCMASA_LFE_SYNTH_DATA_HANDLE) malloc( sizeof( MCMASA_LFE_SYNTH_DATA ) ) ) == NULL )
    1254             :     {
    1255           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
    1256             :     }
    1257             : 
    1258         231 :     hMasa->hMasaLfeSynth->transportEneSmooth_fx = 0;
    1259         231 :     move32();
    1260         231 :     hMasa->hMasaLfeSynth->transportEneSmooth_q = Q31;
    1261         231 :     move16();
    1262         231 :     hMasa->hMasaLfeSynth->protoLfeEneSmooth_fx = 0;
    1263         231 :     move32();
    1264         231 :     hMasa->hMasaLfeSynth->protoLfeEneSmooth_q = Q31;
    1265         231 :     move16();
    1266         231 :     hMasa->hMasaLfeSynth->targetEneLfeSmooth_fx = 0;
    1267         231 :     move32();
    1268         231 :     hMasa->hMasaLfeSynth->targetEneLfeSmooth_q = Q31;
    1269         231 :     move16();
    1270         231 :     hMasa->hMasaLfeSynth->targetEneTransSmooth_fx = 0;
    1271         231 :     move32();
    1272         231 :     hMasa->hMasaLfeSynth->targetEneTransSmooth_q = Q31;
    1273         231 :     move16();
    1274             : 
    1275         231 :     set16_fx( hMasa->hMasaLfeSynth->lfeToTotalEnergyRatio_fx, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
    1276         231 :     hMasa->hMasaLfeSynth->lfeGainPrevIndex = 0;
    1277         231 :     move16();
    1278             : 
    1279         231 :     test();
    1280         231 :     test();
    1281         231 :     test();
    1282         231 :     test();
    1283         231 :     test();
    1284         231 :     test();
    1285         231 :     test();
    1286         231 :     test();
    1287         231 :     test();
    1288         231 :     test();
    1289         231 :     test();
    1290         231 :     IF( st_ivas->hOutSetup.separateChannelEnabled &&
    1291             :         ( EQ_16( output_config, IVAS_AUDIO_CONFIG_5_1 ) || EQ_16( output_config, IVAS_AUDIO_CONFIG_7_1 ) ||
    1292             :           EQ_16( output_config, IVAS_AUDIO_CONFIG_5_1_2 ) ||
    1293             :           EQ_16( output_config, IVAS_AUDIO_CONFIG_5_1_4 ) || EQ_16( output_config, IVAS_AUDIO_CONFIG_7_1_4 ) ||
    1294             :           EQ_16( output_config, IVAS_AUDIO_CONFIG_FOA ) || EQ_16( output_config, IVAS_AUDIO_CONFIG_HOA2 ) ||
    1295             :           EQ_16( output_config, IVAS_AUDIO_CONFIG_HOA3 ) ||
    1296             :           ( EQ_16( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) && ( st_ivas->hOutSetup.num_lfe > 0 ) ) ) )
    1297           6 :     {
    1298             :         Word16 bufferSize;
    1299             :         Word16 i;
    1300             :         Word16 slot_size;
    1301             : 
    1302             :         /* Ring buffer for the filterbank of the LFE synthesis.
    1303             :          * The filterbank is using moving average lowpass filter with the crossover of 120 Hz. */
    1304             :         /* bufferSize = (int16_t) ( ( output_Fs / FRAMES_PER_SEC ) / MAX_PARAM_SPATIAL_SUBFRAMES ); */
    1305           6 :         bufferSize = extract_l( Mpy_32_32_r( output_Fs, 10737418 /* 1 / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) in Q31 */ ) );
    1306             : 
    1307           6 :         IF( ( hMasa->hMasaLfeSynth->lfeSynthRingBuffer_fx = (Word32 *) malloc( bufferSize * sizeof( Word32 ) ) ) == NULL )
    1308             :         {
    1309           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
    1310             :         }
    1311           6 :         set32_fx( hMasa->hMasaLfeSynth->lfeSynthRingBuffer_fx, 0, bufferSize ); // Q11
    1312             : 
    1313           6 :         hMasa->hMasaLfeSynth->ringBufferLoPointer = 0;
    1314           6 :         move16();
    1315           6 :         hMasa->hMasaLfeSynth->ringBufferHiPointer = shr( bufferSize, 1 );
    1316           6 :         move16();
    1317           6 :         hMasa->hMasaLfeSynth->lowpassSum_fx = 0; // Q11
    1318           6 :         move16();
    1319           6 :         hMasa->hMasaLfeSynth->ringBufferSize = bufferSize;
    1320           6 :         move16();
    1321             : 
    1322             :         /* Ring buffer for additional lowpass filter for the LFE signal.
    1323             :          * Moving average lowpass filter with the crossover of 240 Hz. */
    1324           6 :         bufferSize = shr( bufferSize, 1 );
    1325             : 
    1326           6 :         IF( ( hMasa->hMasaLfeSynth->lfeSynthRingBuffer2_fx = (Word32 *) malloc( bufferSize * sizeof( Word32 ) ) ) == NULL )
    1327             :         {
    1328           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
    1329             :         }
    1330           6 :         set32_fx( hMasa->hMasaLfeSynth->lfeSynthRingBuffer2_fx, 0, bufferSize ); // Q11
    1331             : 
    1332           6 :         hMasa->hMasaLfeSynth->ringBufferLoPointer2 = 0;
    1333           6 :         move16();
    1334           6 :         hMasa->hMasaLfeSynth->lowpassSum2_fx = 0; // Q11
    1335           6 :         move32();
    1336           6 :         hMasa->hMasaLfeSynth->ringBufferSize2 = bufferSize;
    1337           6 :         move16();
    1338             : 
    1339             :         /* Delay buffer for matching the delay of the lowpass filter */
    1340           6 :         bufferSize = shr( bufferSize, 1 ); /* The delay of the moving average lowpass filter is bufferSize / 2 */
    1341           6 :         IF( ( hMasa->hMasaLfeSynth->delayBuffer_syncLp_fx = (Word32 *) malloc( bufferSize * sizeof( Word32 ) ) ) == NULL )
    1342             :         {
    1343           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
    1344             :         }
    1345           6 :         set32_fx( hMasa->hMasaLfeSynth->delayBuffer_syncLp_fx, 0, bufferSize ); // Q11
    1346           6 :         hMasa->hMasaLfeSynth->delayBuffer_syncLp_size = bufferSize;
    1347           6 :         move16();
    1348             : 
    1349             :         /* Delay buffer for syncing with DirAC rendering */
    1350           6 :         bufferSize = sub( sub( NS2SA_FX2( output_Fs, IVAS_FB_DEC_DELAY_NS ), shr( hMasa->hMasaLfeSynth->ringBufferSize, 1 ) ), shr( hMasa->hMasaLfeSynth->ringBufferSize2, 1 ) );
    1351           6 :         IF( ( hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_fx = (Word32 *) malloc( bufferSize * sizeof( Word32 ) ) ) == NULL )
    1352             :         {
    1353           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
    1354             :         }
    1355           6 :         set32_fx( hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_fx, 0, bufferSize ); // Q11
    1356           6 :         hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_size = bufferSize;
    1357           6 :         move16();
    1358             : 
    1359             :         /* Interpolation between slots */
    1360           6 :         hMasa->hMasaLfeSynth->lfeGainPrev_fx = 0; // Q15
    1361           6 :         move16();
    1362           6 :         hMasa->hMasaLfeSynth->transportGainPrev_fx = MAX_WORD16; // Q15
    1363           6 :         move16();
    1364             : 
    1365             :         /* slot_size = (int16_t) ( ( output_Fs / FRAMES_PER_SEC ) / CLDFB_NO_COL_MAX ); */
    1366           6 :         slot_size = extract_l( Mpy_32_32( output_Fs, 2684355 /* 1 / ( FRAMES_PER_SEC * CLDFB_NO_COL_MAX ) in Q31*/ ) );
    1367             : 
    1368         366 :         FOR( i = 0; i < slot_size; i++ )
    1369             :         {
    1370         360 :             hMasa->hMasaLfeSynth->interpolator_fx[i] = div_s( add( i, 1 ), slot_size ); // Q15
    1371         360 :             move16();
    1372             :         }
    1373             :     }
    1374         225 :     ELSE IF( st_ivas->hOutSetup.separateChannelEnabled && EQ_16( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) && EQ_16( st_ivas->hOutSetup.num_lfe, 0 ) )
    1375           0 :     {
    1376             :         Word16 bufferSize;
    1377             : 
    1378             :         /* Delay buffer for syncing with DirAC rendering */
    1379           0 :         bufferSize = NS2SA_FX2( output_Fs, IVAS_FB_DEC_DELAY_NS );
    1380           0 :         IF( ( hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_fx = (Word32 *) malloc( bufferSize * sizeof( Word32 ) ) ) == NULL )
    1381             :         {
    1382           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
    1383             :         }
    1384           0 :         set32_fx( hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_fx, 0, bufferSize ); // Q11
    1385           0 :         hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_size = bufferSize;
    1386           0 :         move16();
    1387             : 
    1388           0 :         hMasa->hMasaLfeSynth->lfeSynthRingBuffer_fx = NULL;
    1389           0 :         hMasa->hMasaLfeSynth->lfeSynthRingBuffer2_fx = NULL;
    1390           0 :         hMasa->hMasaLfeSynth->delayBuffer_syncLp_fx = NULL;
    1391             :     }
    1392             :     ELSE
    1393             :     {
    1394         225 :         hMasa->hMasaLfeSynth->lfeSynthRingBuffer_fx = NULL;
    1395         225 :         hMasa->hMasaLfeSynth->lfeSynthRingBuffer2_fx = NULL;
    1396         225 :         hMasa->hMasaLfeSynth->delayBuffer_syncLp_fx = NULL;
    1397         225 :         hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_fx = NULL;
    1398             :     }
    1399             : 
    1400         231 :     return IVAS_ERR_OK;
    1401             : }
    1402             : 
    1403             : 
    1404             : /*! r: Number of bits read */
    1405       10039 : static Word16 decode_lfe_to_total_energy_ratio_fx(
    1406             :     MCMASA_LFE_SYNTH_DATA_HANDLE hMasaLfeSynth, /* i/o: McMASA LFE structure */
    1407             :     UWord16 *bitstream,                         /* i  : bitstream            */
    1408             :     Word16 *index,                              /* i/o: bitstream position   */
    1409             :     const Word32 ivas_total_brate               /* i  : total bitrate        */
    1410             : )
    1411             : {
    1412             :     Word16 i;
    1413             :     Word16 lfeToTotalEnergyRatioIndices[3];
    1414             :     Word16 VQBits;
    1415             :     Word16 log2LFEaverage_fx;
    1416             :     Word16 lfeToTotalEnergyRatioTemp_fx;
    1417             :     UWord16 byteBuffer;
    1418             :     Word16 lfeBitsRead;
    1419             : 
    1420       10039 :     lfeBitsRead = 0;
    1421       10039 :     move16();
    1422       10039 :     byteBuffer = bitstream[( *index )--];
    1423       10039 :     move16();
    1424       10039 :     lfeBitsRead = add( lfeBitsRead, 1 );
    1425       10039 :     lfeToTotalEnergyRatioIndices[0] = byteBuffer; /* First LFE index */
    1426       10039 :     move16();
    1427             : 
    1428       10039 :     IF( EQ_32( ivas_total_brate, IVAS_13k2 ) ) /* 1-bit adaptive LFE gain quantizer at 13.2 kbps */
    1429             :     {
    1430        1320 :         lfeToTotalEnergyRatioTemp_fx = hMasaLfeSynth->lfeToTotalEnergyRatio_fx[3]; // Q14 /* Take memory from the last subframe */
    1431        1320 :         move16();
    1432        1320 :         IF( EQ_16( lfeToTotalEnergyRatioIndices[0], 1 ) )
    1433             :         {
    1434         121 :             IF( EQ_16( hMasaLfeSynth->lfeGainPrevIndex, 1 ) )
    1435             :             {
    1436          83 :                 Word16 lfe_beta_theta = mult( MCMASA_LFE_THETA_Q14, MCMASA_LFE_BETA_Q15 );          // Q 14 + 15 - 15 = Q14
    1437          83 :                 lfeToTotalEnergyRatioTemp_fx = add( lfeToTotalEnergyRatioTemp_fx, lfe_beta_theta ); /* larger "bump-up" energy */
    1438             :             }
    1439             :             ELSE
    1440             :             {
    1441          38 :                 lfeToTotalEnergyRatioTemp_fx = add( lfeToTotalEnergyRatioTemp_fx, MCMASA_LFE_BETA_Q14 ); /* "bump-up" energy */
    1442             :             }
    1443             :         }
    1444             :         ELSE
    1445             :         {
    1446        1199 :             lfeToTotalEnergyRatioTemp_fx = mult( lfeToTotalEnergyRatioTemp_fx, MCMASA_LFE_ALPHA_Q15 ); // Q14
    1447             :         }
    1448        1320 :         if ( GT_16( lfeToTotalEnergyRatioTemp_fx, ONE_IN_Q14 ) )
    1449             :         {
    1450           0 :             lfeToTotalEnergyRatioTemp_fx = ONE_IN_Q14;
    1451           0 :             move16();
    1452             :         }
    1453        1320 :         hMasaLfeSynth->lfeGainPrevIndex = lfeToTotalEnergyRatioIndices[0];
    1454        1320 :         move16();
    1455        6600 :         FOR( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
    1456             :         {
    1457        5280 :             hMasaLfeSynth->lfeToTotalEnergyRatio_fx[i] = lfeToTotalEnergyRatioTemp_fx; /* will always be less than 16384 */
    1458        5280 :             move16();
    1459             :         }
    1460             :     }
    1461             :     ELSE /* Bitrates >= 16.4 kbps */
    1462             :     {
    1463        8719 :         IF( EQ_16( lfeToTotalEnergyRatioIndices[0], 0 ) )
    1464             :         {
    1465       35945 :             FOR( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
    1466             :             {
    1467       28756 :                 hMasaLfeSynth->lfeToTotalEnergyRatio_fx[i] = 0;
    1468       28756 :                 move16();
    1469             :             }
    1470             :         }
    1471             :         ELSE
    1472             :         {
    1473        1530 :             byteBuffer = (UWord16) L_shl( bitstream[( *index )--], 2 );
    1474        1530 :             byteBuffer = (UWord16) L_add( byteBuffer, L_shl( bitstream[( *index )--], 1 ) );
    1475        1530 :             byteBuffer = (UWord16) L_add( byteBuffer, bitstream[( *index )--] );
    1476        1530 :             move16();
    1477        1530 :             move16();
    1478        1530 :             move16();
    1479        1530 :             lfeBitsRead = add( lfeBitsRead, 3 );
    1480        1530 :             lfeToTotalEnergyRatioIndices[1] = byteBuffer; /* Scalar index */
    1481        1530 :             move16();
    1482        1530 :             log2LFEaverage_fx = usdequant_fx( lfeToTotalEnergyRatioIndices[1], MCMASA_LFE_QLOW_Q12, MCMASA_LFE_DELTA_Q11 ); // Q12
    1483             : 
    1484             :             /* 16.4 kbps sends only scalar gain, above it VQ is used */
    1485        1530 :             IF( GE_32( ivas_total_brate, IVAS_24k4 ) )
    1486             :             {
    1487             :                 /* Depending on average (scalar) gain more bits are sent for VQ LFE gain */
    1488        1440 :                 SWITCH( lfeToTotalEnergyRatioIndices[1] )
    1489             :                 {
    1490         271 :                     case 0:
    1491             :                     case 1:
    1492         271 :                         VQBits = 0;
    1493         271 :                         move16();
    1494         271 :                         BREAK;
    1495         118 :                     case 2:
    1496         118 :                         VQBits = 1;
    1497         118 :                         move16();
    1498         118 :                         BREAK;
    1499          74 :                     case 3:
    1500          74 :                         VQBits = 2;
    1501          74 :                         move16();
    1502          74 :                         BREAK;
    1503         186 :                     case 4:
    1504         186 :                         VQBits = 3;
    1505         186 :                         move16();
    1506         186 :                         BREAK;
    1507         791 :                     default:
    1508         791 :                         VQBits = 4;
    1509         791 :                         move16();
    1510             :                 }
    1511        1440 :                 byteBuffer = 0;
    1512        1440 :                 move16();
    1513        5428 :                 FOR( i = 0; i < VQBits; i++ )
    1514             :                 {
    1515        3988 :                     byteBuffer = (UWord16) L_add( byteBuffer, L_shl( bitstream[( *index )--], sub( sub( VQBits, 1 ), i ) ) );
    1516        3988 :                     move16();
    1517        3988 :                     lfeBitsRead = add( lfeBitsRead, 1 );
    1518             :                 }
    1519        1440 :                 lfeToTotalEnergyRatioIndices[2] = byteBuffer; /* VQ index */
    1520        1440 :                 move16();
    1521             :             }
    1522             : 
    1523        7650 :             FOR( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
    1524             :             {
    1525             :                 Word16 tmp16, exp;
    1526             :                 Word32 tmp32;
    1527        6120 :                 IF( EQ_32( ivas_total_brate, IVAS_16k4 ) )
    1528             :                 {
    1529         360 :                     tmp32 = BASOP_util_Pow2( L_deposit_h( log2LFEaverage_fx ), 15 - Q12, &exp );  /* Q(31 - exp)*/
    1530         360 :                     tmp16 = round_fx( tmp32 );                                                    /* Q(31-exp) -> Q(15 - exp) */
    1531         360 :                     hMasaLfeSynth->lfeToTotalEnergyRatio_fx[i] = shr_sat( tmp16, sub( 1, exp ) ); /* should saturate. Q(15 - exp) - (1 - exp)->Q14 */
    1532         360 :                     move16();
    1533             :                 }
    1534             :                 ELSE
    1535             :                 {
    1536        5760 :                     tmp16 = shr( McMASA_LFEGain_vectors_fx_q13[4 * lfeToTotalEnergyRatioIndices[2] + i], 1 ); /* Q12 */
    1537        5760 :                     tmp16 = add( log2LFEaverage_fx, tmp16 );                                                  /* Q12 */
    1538        5760 :                     tmp32 = BASOP_util_Pow2( L_deposit_h( tmp16 ), 15 - Q12, &exp );                          /* Q(31 - exp) */
    1539        5760 :                     tmp16 = round_fx( tmp32 );                                                                /* Q(31-exp) -> Q(15 - exp) */
    1540        5760 :                     hMasaLfeSynth->lfeToTotalEnergyRatio_fx[i] = shr_sat( tmp16, sub( 1, exp ) );             /* should saturate. Q(15 - exp) - (1 - exp) -> Q14 */
    1541        5760 :                     move16();
    1542             :                 }
    1543             : 
    1544        6120 :                 hMasaLfeSynth->lfeToTotalEnergyRatio_fx[i] = s_min( hMasaLfeSynth->lfeToTotalEnergyRatio_fx[i], ONE_IN_Q14 );
    1545        6120 :                 move16();
    1546        6120 :                 hMasaLfeSynth->lfeToTotalEnergyRatio_fx[i] = s_max( hMasaLfeSynth->lfeToTotalEnergyRatio_fx[i], 0 );
    1547        6120 :                 move16();
    1548             :             }
    1549             :         }
    1550             :     }
    1551             : 
    1552       10039 :     return lfeBitsRead;
    1553             : }
    1554             : 
    1555             : 
    1556             : /*-------------------------------------------------------------------*
    1557             :  * ivas_masa_dec_reconfigure()
    1558             :  *
    1559             :  * Reconfigure IVAS MASA decoder
    1560             :  *-------------------------------------------------------------------*/
    1561             : 
    1562             : /*-------------------------------------------------------------------*
    1563             :  * ivas_masa_dec_reconfigure_fx()
    1564             :  *
    1565             :  * Reconfigure IVAS MASA decoder
    1566             :  *-------------------------------------------------------------------*/
    1567             : 
    1568        2778 : ivas_error ivas_masa_dec_reconfigure_fx(
    1569             :     Decoder_Struct *st_ivas,   /* i/o: IVAS decoder structure                                     */
    1570             :     UWord16 *nSamplesRendered, /* o  : number of samples flushed from the previous frame (JBM)    */
    1571             :     Word16 *data               /* o  : output synthesis signal                 */
    1572             : )
    1573             : {
    1574             :     Word16 n, tmp, num_bits;
    1575             :     Word16 sce_id, cpe_id;
    1576             :     UWord16 *bit_stream;
    1577             :     Decoder_State **sts;
    1578             :     UWord32 ivas_total_brate, last_ivas_total_brate;
    1579             :     Word16 numCldfbAnalyses_old, numCldfbSyntheses_old;
    1580             :     ivas_error error;
    1581             :     Word32 ism_total_brate;
    1582             : 
    1583        2778 :     error = IVAS_ERR_OK;
    1584        2778 :     move16();
    1585             : 
    1586        2778 :     ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
    1587        2778 :     move32();
    1588        2778 :     last_ivas_total_brate = st_ivas->hDecoderConfig->last_ivas_total_brate;
    1589        2778 :     move32();
    1590             : 
    1591        2778 :     test();
    1592        2778 :     IF( st_ivas->hSpatParamRendCom != NULL && EQ_16( st_ivas->hSpatParamRendCom->slot_size, st_ivas->hTcBuffer->n_samples_granularity ) )
    1593             :     {
    1594        2521 :         Copy( st_ivas->hSpatParamRendCom->subframe_nbslots, st_ivas->hTcBuffer->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS );
    1595        2521 :         st_ivas->hTcBuffer->nb_subframes = st_ivas->hSpatParamRendCom->nb_subframes;
    1596        2521 :         move16();
    1597        2521 :         st_ivas->hTcBuffer->subframes_rendered = st_ivas->hSpatParamRendCom->subframes_rendered;
    1598        2521 :         move16();
    1599             :     }
    1600             : 
    1601        2778 :     ivas_init_dec_get_num_cldfb_instances( st_ivas, &numCldfbAnalyses_old, &numCldfbSyntheses_old );
    1602             : 
    1603             :     /* renderer might have changed, reselect */
    1604        2778 :     ivas_renderer_select( st_ivas );
    1605             : 
    1606        2778 :     test();
    1607        2778 :     test();
    1608        2778 :     test();
    1609        2778 :     test();
    1610        2778 :     test();
    1611        2778 :     test();
    1612        2778 :     IF( ( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) && st_ivas->hDirACRend == NULL ) ||
    1613             :         ( ( EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) && st_ivas->hDiracDecBin == NULL ) )
    1614             :     {
    1615             :         /* init a new DirAC dec */
    1616          54 :         if ( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_OPEN ) ) != IVAS_ERR_OK )
    1617             :         {
    1618           0 :             return error;
    1619             :         }
    1620             :     }
    1621        2724 :     ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_DISABLE ) || EQ_32( st_ivas->renderer_type, RENDERER_MONO_DOWNMIX ) )
    1622             :     {
    1623         201 :         IF( st_ivas->hDirAC != NULL )
    1624             :         {
    1625             :             /* close all unnecessary parametric decoding and rendering */
    1626          52 :             ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin );
    1627          52 :             ivas_dirac_rend_close_fx( &( st_ivas->hDirACRend ) );
    1628          52 :             ivas_spat_hSpatParamRendCom_close_fx( &( st_ivas->hSpatParamRendCom ) );
    1629          52 :             ivas_dirac_dec_close_fx( &( st_ivas->hDirAC ) );
    1630             :         }
    1631             :     }
    1632             :     /* possible reconfigure is done later */
    1633             : 
    1634             :     /*-----------------------------------------------------------------*
    1635             :      * Allocate and initialize SCE/CPE and other handles
    1636             :      *-----------------------------------------------------------------*/
    1637             : 
    1638        2778 :     IF( st_ivas->hSCE[0] != NULL )
    1639             :     {
    1640        1761 :         bit_stream = st_ivas->hSCE[0]->hCoreCoder[0]->bit_stream;
    1641        1761 :         move16();
    1642             :     }
    1643             :     ELSE
    1644             :     {
    1645        1017 :         bit_stream = st_ivas->hCPE[0]->hCoreCoder[0]->bit_stream;
    1646        1017 :         move16();
    1647             :     }
    1648             : 
    1649        2778 :     num_bits = 0;
    1650        2778 :     move16();
    1651             : 
    1652             :     Word16 tmp_e;
    1653             :     Word32 tmp32;
    1654             : 
    1655        5359 :     FOR( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
    1656             :     {
    1657             : 
    1658             :         // st_ivas->hSCE[sce_id]->element_brate = ivas_total_brate / st_ivas->nchan_transport;
    1659        2581 :         st_ivas->hSCE[sce_id]->element_brate = L_deposit_h( BASOP_Util_Divide3216_Scale( ivas_total_brate, st_ivas->nchan_transport, &tmp_e ) );
    1660        2581 :         st_ivas->hSCE[sce_id]->element_brate = L_shr( st_ivas->hSCE[sce_id]->element_brate, sub( 15, tmp_e ) ); // Q0
    1661        2581 :         move32();
    1662        2581 :         move32();
    1663             : 
    1664        2581 :         st_ivas->hSCE[sce_id]->hCoreCoder[0]->total_brate = st_ivas->hSCE[sce_id]->element_brate; /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */
    1665        2581 :         move32();
    1666             : 
    1667        2581 :         sts = st_ivas->hSCE[sce_id]->hCoreCoder;
    1668        2581 :         sts[0]->bit_stream = bit_stream + num_bits;
    1669             : 
    1670             :         // num_bits += (int16_t)(st_ivas->hSCE[sce_id]->element_brate / FRAMES_PER_SEC);
    1671        2581 :         tmp = extract_l( Mpy_32_32( st_ivas->hSCE[sce_id]->element_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) );
    1672        2581 :         num_bits = add( num_bits, tmp );
    1673             : 
    1674        2581 :         test();
    1675        2581 :         test();
    1676        2581 :         test();
    1677        2581 :         IF( ( EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) && st_ivas->hDiracDecBin != NULL )
    1678             :         {
    1679        1132 :             if ( NE_32( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_RECONFIGURE ) ), IVAS_ERR_OK ) )
    1680             :             {
    1681           0 :                 return error;
    1682             :             }
    1683             :         }
    1684             :     }
    1685             : 
    1686        4859 :     FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ )
    1687             :     {
    1688             :         // st_ivas->hCPE[cpe_id]->element_brate = ( ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS;
    1689        2081 :         tmp32 = L_deposit_h( BASOP_Util_Divide3216_Scale( ivas_total_brate, st_ivas->nchan_transport, &tmp_e ) );
    1690        2081 :         tmp32 = L_shr( tmp32, sub( 15, tmp_e ) ); // Q0
    1691        2081 :         st_ivas->hCPE[cpe_id]->element_brate = imult3216( tmp32, CPE_CHANNELS );
    1692        2081 :         move32();
    1693             : 
    1694             :         /* prepare bitstream buffers */
    1695        6243 :         FOR( n = 0; n < CPE_CHANNELS; n++ )
    1696             :         {
    1697        4162 :             tmp = CPE_CHANNELS;
    1698        4162 :             move16();
    1699        4162 :             if ( GT_16( st_ivas->nCPE, 1 ) )
    1700             :             {
    1701           0 :                 st_ivas->nCPE = 1;
    1702           0 :                 move16();
    1703             :             }
    1704             :             /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */
    1705             :             // st_ivas->hCPE[cpe_id]->hCoreCoder[n]->total_brate = st_ivas->hCPE[cpe_id]->element_brate / tmp;
    1706        4162 :             tmp32 = L_deposit_h( BASOP_Util_Divide3216_Scale( st_ivas->hCPE[cpe_id]->element_brate, tmp, &tmp_e ) );
    1707        4162 :             tmp32 = L_shr( tmp32, sub( 15, tmp_e ) );
    1708        4162 :             st_ivas->hCPE[cpe_id]->hCoreCoder[n]->total_brate = tmp32;
    1709        4162 :             move32();
    1710             :         }
    1711        2081 :         sts = st_ivas->hCPE[cpe_id]->hCoreCoder;
    1712        2081 :         sts[0]->bit_stream = bit_stream + num_bits;
    1713             : 
    1714             :         // num_bits += (int16_t) ( st_ivas->hCPE[cpe_id]->element_brate / FRAMES_PER_SEC );
    1715        2081 :         tmp = extract_l( Mpy_32_32( st_ivas->hCPE[cpe_id]->element_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) );
    1716        2081 :         num_bits = add( num_bits, tmp );
    1717             : 
    1718        2081 :         test();
    1719        2081 :         test();
    1720        2081 :         test();
    1721        2081 :         test();
    1722        2081 :         IF( ( LT_32( ivas_total_brate, MASA_STEREO_MIN_BITRATE ) && GE_32( last_ivas_total_brate, MASA_STEREO_MIN_BITRATE ) ) ||
    1723             :             ( LT_32( ivas_total_brate, MASA_STEREO_MIN_BITRATE ) && EQ_32( last_ivas_total_brate, FRAME_NO_DATA ) ) )
    1724             :         {
    1725         418 :             st_ivas->hCPE[cpe_id]->nchan_out = 1;
    1726         418 :             move16();
    1727             : 
    1728         418 :             test();
    1729         418 :             test();
    1730         418 :             test();
    1731         418 :             test();
    1732         418 :             test();
    1733         418 :             IF( ( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) && st_ivas->hDirACRend != NULL ) || ( ( EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) && st_ivas->hDiracDecBin != NULL ) )
    1734             :             {
    1735         349 :                 if ( NE_32( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_RECONFIGURE ) ), IVAS_ERR_OK ) )
    1736             :                 {
    1737           0 :                     return error;
    1738             :                 }
    1739             :             }
    1740             :         }
    1741        1663 :         ELSE IF( GE_32( ivas_total_brate, MASA_STEREO_MIN_BITRATE ) && LT_32( last_ivas_total_brate, MASA_STEREO_MIN_BITRATE ) )
    1742             :         {
    1743         432 :             st_ivas->hCPE[cpe_id]->nchan_out = CPE_CHANNELS;
    1744         432 :             move16();
    1745             : 
    1746         432 :             test();
    1747         432 :             test();
    1748         432 :             test();
    1749         432 :             test();
    1750         432 :             test();
    1751         432 :             IF( ( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) && st_ivas->hDirACRend != NULL ) || ( ( EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) && st_ivas->hDiracDecBin != NULL ) )
    1752             :             {
    1753         402 :                 if ( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_RECONFIGURE ) ) != IVAS_ERR_OK )
    1754             :                 {
    1755           0 :                     return error;
    1756             :                 }
    1757             :             }
    1758             :         }
    1759             :     }
    1760             : 
    1761        2778 :     IF( st_ivas->hDiracDecBin != NULL )
    1762             :     {
    1763             :         /* regularization factor is bitrate-dependent */
    1764        1256 :         st_ivas->hDiracDecBin->reqularizationFactor_fx = configure_reqularization_factor_fx( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate );
    1765        1256 :         move16();
    1766             :     }
    1767             : 
    1768        2778 :     test();
    1769        2778 :     IF( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) && EQ_32( st_ivas->last_ivas_format, MASA_FORMAT ) ) /* note: switching within OMASA is handled in ivas_omasa_dec_config() */
    1770             :     {
    1771             :         /*-----------------------------------------------------------------*
    1772             :          * TD Decorrelator
    1773             :          *-----------------------------------------------------------------*/
    1774        1318 :         IF( st_ivas->hDiracDecBin != NULL )
    1775             :         {
    1776         598 :             IF( NE_32( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin->hTdDecorr ), &( st_ivas->hDiracDecBin->useTdDecorr ) ) ), IVAS_ERR_OK ) )
    1777             :             {
    1778           0 :                 return error;
    1779             :             }
    1780             :         }
    1781             : 
    1782             :         /*-----------------------------------------------------------------*
    1783             :          * CLDFB instances
    1784             :          *-----------------------------------------------------------------*/
    1785        1318 :         IF( st_ivas->hSpar )
    1786             :         {
    1787           0 :             Word16 Q_tmp = getScaleFactor16( st_ivas->hSpar->hFbMixer->cldfb_cross_fade_fx, 16 );
    1788           0 :             Scale_sig( st_ivas->hSpar->hFbMixer->cldfb_cross_fade_fx, 16, Q_tmp - st_ivas->hSpar->hFbMixer->cldfb_cross_fade_q ); // st_ivas->hSpar->hFbMixer->cldfb_cross_fade_q -> Q_tmp
    1789           0 :             st_ivas->hSpar->hFbMixer->cldfb_cross_fade_q = Q_tmp;
    1790           0 :             move16();
    1791             :         }
    1792        1318 :         if ( NE_32( ( error = ivas_cldfb_dec_reconfig_fx( st_ivas, st_ivas->nchan_transport, numCldfbAnalyses_old, numCldfbSyntheses_old ) ), IVAS_ERR_OK ) )
    1793             :         {
    1794           0 :             return error;
    1795             :         }
    1796             :     }
    1797             : 
    1798             :     /*-----------------------------------------------------------------*
    1799             :      * Set-up MASA coding elements and bitrates
    1800             :      *-----------------------------------------------------------------*/
    1801             : 
    1802        2778 :     ism_total_brate = 0;
    1803        2778 :     move32();
    1804             : 
    1805        2778 :     test();
    1806        2778 :     test();
    1807        2778 :     test();
    1808        2778 :     test();
    1809        2778 :     IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) && GT_32( st_ivas->nSCE, 0 ) && ( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) ) )
    1810             :     {
    1811        1865 :         FOR( n = 0; n < st_ivas->nSCE; n++ )
    1812             :         {
    1813        1195 :             ism_total_brate = L_add( ism_total_brate, st_ivas->hSCE[n]->element_brate );
    1814             :         }
    1815             :     }
    1816             : 
    1817        2778 :     ivas_masa_set_elements_fx( ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, st_ivas->hQMetaData, &tmp, &tmp, &tmp, st_ivas->ivas_format, st_ivas->ism_mode, ism_total_brate );
    1818             : 
    1819        2778 :     IF( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) )
    1820             :     {
    1821        1712 :         st_ivas->nchan_ism = 0;
    1822        1712 :         move16();
    1823        1712 :         st_ivas->ism_mode = ISM_MODE_NONE;
    1824        1712 :         move16();
    1825             :     }
    1826             : 
    1827             :     {
    1828             :         Word16 tc_nchan_to_allocate;
    1829             :         Word16 tc_nchan_transport;
    1830             :         TC_BUFFER_MODE buffer_mode_new;
    1831             :         Word16 n_samples_granularity;
    1832             : 
    1833        2778 :         n_samples_granularity = NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS );
    1834        2778 :         move16();
    1835        2778 :         buffer_mode_new = ivas_jbm_dec_get_tc_buffer_mode( st_ivas );
    1836        2778 :         tc_nchan_transport = ivas_jbm_dec_get_num_tc_channels_fx( st_ivas );
    1837             : 
    1838        2778 :         tc_nchan_to_allocate = tc_nchan_transport;
    1839        2778 :         move16();
    1840             : 
    1841        2778 :         test();
    1842        2778 :         test();
    1843        2778 :         test();
    1844        2778 :         test();
    1845        2778 :         IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) || EQ_16( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) )
    1846             :         {
    1847        1256 :             IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
    1848             :             {
    1849         472 :                 tc_nchan_to_allocate = add( shl( BINAURAL_CHANNELS, 1 ), 2 );
    1850             :             }
    1851             :             ELSE
    1852             :             {
    1853         784 :                 tc_nchan_to_allocate = shl( BINAURAL_CHANNELS, 1 );
    1854             :             }
    1855        1256 :             test();
    1856        1256 :             test();
    1857        1256 :             test();
    1858        1256 :             IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) && EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) && EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
    1859             :             {
    1860          54 :                 n_samples_granularity = NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ); /* Use the same granularity as tdrend */
    1861          54 :                 IF( GT_16( n_samples_granularity, st_ivas->hTcBuffer->n_samples_granularity ) )
    1862             :                 {
    1863          54 :                     if ( NE_32( ( error = ivas_jbm_dec_set_discard_samples( st_ivas ) ), IVAS_ERR_OK ) )
    1864             :                     {
    1865           0 :                         return error;
    1866             :                     }
    1867             :                 }
    1868             :             }
    1869        1202 :             ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) && NE_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
    1870             :             {
    1871         574 :                 IF( LT_16( n_samples_granularity, st_ivas->hTcBuffer->n_samples_granularity ) )
    1872             :                 {
    1873          54 :                     if ( NE_32( ( error = ivas_jbm_dec_flush_renderer_fx( st_ivas, n_samples_granularity, st_ivas->renderer_type, st_ivas->intern_config, &st_ivas->hIntSetup, MC_MODE_NONE, ISM_MASA_MODE_DISC, nSamplesRendered, data ) ), IVAS_ERR_OK ) )
    1874             :                     {
    1875           0 :                         return error;
    1876             :                     }
    1877             :                 }
    1878             :             }
    1879             :         }
    1880        1522 :         ELSE IF( EQ_16( st_ivas->nchan_transport, 1 ) && ( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) && EQ_32( st_ivas->hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) )
    1881             :         {
    1882             :             /* addtl channel for CNG */
    1883         190 :             tc_nchan_to_allocate = add( tc_nchan_to_allocate, 1 );
    1884             :         }
    1885             : 
    1886        2778 :         test();
    1887        2778 :         test();
    1888        2778 :         IF( NE_16( tc_nchan_transport, st_ivas->hTcBuffer->nchan_transport_jbm ) || NE_16( tc_nchan_to_allocate, st_ivas->hTcBuffer->nchan_transport_internal ) || NE_16( buffer_mode_new, st_ivas->hTcBuffer->tc_buffer_mode ) )
    1889             :         {
    1890        1509 :             if ( NE_32( error = ivas_jbm_dec_tc_buffer_reconfigure_fx( st_ivas, buffer_mode_new, tc_nchan_transport, tc_nchan_to_allocate, tc_nchan_to_allocate, n_samples_granularity ), IVAS_ERR_OK ) )
    1891             :             {
    1892           0 :                 return error;
    1893             :             }
    1894             :         }
    1895             : 
    1896        2778 :         test();
    1897        2778 :         IF( st_ivas->hSpatParamRendCom != NULL && EQ_16( st_ivas->hSpatParamRendCom->slot_size, st_ivas->hTcBuffer->n_samples_granularity ) )
    1898             :         {
    1899        2523 :             Copy( st_ivas->hTcBuffer->subframe_nbslots, st_ivas->hSpatParamRendCom->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS );
    1900        2523 :             st_ivas->hSpatParamRendCom->nb_subframes = st_ivas->hTcBuffer->nb_subframes;
    1901        2523 :             move16();
    1902        2523 :             st_ivas->hSpatParamRendCom->subframes_rendered = st_ivas->hTcBuffer->subframes_rendered;
    1903        2523 :             move16();
    1904             :         }
    1905             : 
    1906        2778 :         test();
    1907        2778 :         test();
    1908        2778 :         IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) && EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) && EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
    1909             :         {
    1910          54 :             Word16 granularityMultiplier = idiv1616( st_ivas->hTcBuffer->n_samples_granularity, st_ivas->hSpatParamRendCom->slot_size );
    1911         486 :             FOR( n = 0; n < MAX_JBM_SUBFRAMES_5MS; n++ )
    1912             :             {
    1913         432 :                 st_ivas->hSpatParamRendCom->subframe_nbslots[n] = i_mult( st_ivas->hTcBuffer->subframe_nbslots[n], granularityMultiplier );
    1914         432 :                 move16();
    1915             :             }
    1916             :         }
    1917             :     }
    1918             : 
    1919        2778 :     return error;
    1920             : }
    1921             : 
    1922             : 
    1923             : /*-------------------------------------------------------------------*
    1924             :  * ivas_spar_param_to_masa_param_mapping()
    1925             :  *
    1926             :  * Determine MASA metadata from the SPAR metadata
    1927             :  *-------------------------------------------------------------------*/
    1928             : 
    1929      149650 : void ivas_spar_param_to_masa_param_mapping_fx(
    1930             :     Decoder_Struct *st_ivas,                                           /* i/o: IVAS decoder struct               */
    1931             :     Word32 inRe_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i  : Input audio in CLDFB domain, real */
    1932             :     Word32 inIm_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i  : Input audio in CLDFB domain, imag */
    1933             :     Word16 q_cldfb[6][CLDFB_SLOTS_PER_SUBFRAME],
    1934             :     const Word16 subframe /* i  : Subframe to map                   */
    1935             : )
    1936             : {
    1937             :     Word16 i, j, band, bin, slot, ch, nBins, nchan_transport;
    1938             :     Word16 mixer_mat_index;
    1939             :     Word16 dirac_write_idx;
    1940             :     DIRAC_DEC_HANDLE hDirAC;
    1941             :     DIFFUSE_DISTRIBUTION_HANDLE hDiffuseDist;
    1942             :     Word32 mixer_mat_sf_bands_real_fx[SPAR_DIRAC_SPLIT_START_BAND][FOA_CHANNELS][FOA_CHANNELS];
    1943             :     Word32 mixer_mat_sf_bins_real_fx[CLDFB_NO_CHANNELS_MAX][FOA_CHANNELS][FOA_CHANNELS];
    1944             :     Word16 *band_grouping;
    1945             :     Word16 band_start, band_end;
    1946             :     Word32 transportSignalEnergies_32[2][CLDFB_NO_CHANNELS_MAX];
    1947             :     Word64 transportSignalEnergies_64[2][CLDFB_NO_CHANNELS_MAX];
    1948             :     Word32 transportSignalCrossCorrelation_32[CLDFB_NO_CHANNELS_MAX];
    1949             :     Word64 transportSignalCrossCorrelation_64[CLDFB_NO_CHANNELS_MAX];
    1950             :     Word64 instEne_fx;
    1951             :     Word32 inCovarianceMtx_fx[FOA_CHANNELS][FOA_CHANNELS];
    1952      149650 :     Word16 q_inCovarianceMtx = 31;
    1953             :     Word32 foaCovarianceMtx_fx[FOA_CHANNELS][FOA_CHANNELS];
    1954             :     Word32 Iy_fx, Iz_fx, Ix_fx, E_fx, azi_fx, ele_fx, I_fx, ratio_float_fx;
    1955             :     Word32 diffuseGainX_fx, diffuseGainY_fx, diffuseGainZ_fx, diffuseGainSum_fx;
    1956             :     Word16 slot_idx, slot_idx_start, sf;
    1957             :     SPAR_DEC_HANDLE hSpar;
    1958             :     Word16 slot_fac_fx;
    1959      149650 :     Word16 q_slot_fac = 0;
    1960             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
    1961      149650 :     Word16 common_q = 31;
    1962             :     Word64 azi_val, ele_val;
    1963      149650 :     Word64 transportSignalEnergies_max = 0;
    1964      149650 :     Word64 transportSignalCrossCorrelation_max = 0;
    1965      149650 :     Word64 max_common_val = 0;
    1966      149650 :     Word16 azi_q = 0, ele_q = 0;
    1967             :     Word16 num_q, denom_q, res_q;
    1968      149650 :     Word16 headroom_left_max_common = 63; // 0 value
    1969      149650 :     Word16 q_max_common = 31;
    1970             :     Word32 ratio_fx; /* Q30 */
    1971      149650 :     move16();
    1972      149650 :     move16();
    1973      149650 :     move16();
    1974      149650 :     move16();
    1975      149650 :     move16();
    1976      149650 :     move16();
    1977      149650 :     move16();
    1978      149650 :     move64();
    1979      149650 :     move64();
    1980      149650 :     move64();
    1981             : 
    1982      448950 :     FOR( i = 0; i < 2; i++ )
    1983             :     {
    1984      299300 :         set64_fx( transportSignalEnergies_64[i], 0, CLDFB_NO_CHANNELS_MAX );
    1985      299300 :         set32_fx( transportSignalEnergies_32[i], 0, CLDFB_NO_CHANNELS_MAX );
    1986             :     }
    1987      149650 :     set32_fx( transportSignalCrossCorrelation_32, 0, CLDFB_NO_CHANNELS_MAX );
    1988      149650 :     set64_fx( transportSignalCrossCorrelation_64, 0, CLDFB_NO_CHANNELS_MAX );
    1989      748250 :     FOR( i = 0; i < FOA_CHANNELS; i++ )
    1990             :     {
    1991      598600 :         set32_fx( inCovarianceMtx_fx[i], 0, FOA_CHANNELS );
    1992      598600 :         set32_fx( foaCovarianceMtx_fx[i], 0, FOA_CHANNELS );
    1993             :     }
    1994             : 
    1995     1047550 :     FOR( Word16 ind = 0; ind < 6; ind++ )
    1996             :     {
    1997     4489500 :         FOR( Word16 ind2 = 0; ind2 < 4; ind2++ )
    1998             :         {
    1999     3591600 :             if ( GT_16( common_q, q_cldfb[ind][ind2] ) )
    2000             :             {
    2001      214056 :                 common_q = q_cldfb[ind][ind2];
    2002      214056 :                 move16();
    2003             :             }
    2004             :         }
    2005             :     }
    2006             :     /* Set values */
    2007      149650 :     hDirAC = st_ivas->hDirAC;
    2008      149650 :     hSpatParamRendCom = st_ivas->hSpatParamRendCom;
    2009      149650 :     hSpatParamRendCom->numParametricDirections = 1;
    2010      149650 :     move16();
    2011      149650 :     hSpatParamRendCom->numSimultaneousDirections = 1;
    2012      149650 :     move16();
    2013      149650 :     hDiffuseDist = st_ivas->hDiracDecBin->hDiffuseDist;
    2014      149650 :     nchan_transport = st_ivas->nchan_transport;
    2015      149650 :     move16();
    2016      149650 :     band_grouping = hDirAC->band_grouping;
    2017      149650 :     move16();
    2018      149650 :     hSpar = st_ivas->hSpar;
    2019      149650 :     dirac_write_idx = hSpatParamRendCom->render_to_md_map[subframe];
    2020      149650 :     move16();
    2021             : 
    2022             :     /* Init arrays */
    2023      748250 :     FOR( i = 0; i < FOA_CHANNELS; i++ )
    2024             :     {
    2025      598600 :         set32_fx( inCovarianceMtx_fx[i], 0, FOA_CHANNELS );
    2026             :     }
    2027             : 
    2028             :     /* Delay the SPAR mixing matrices to have them synced with the audio */
    2029      149650 :     slot_idx_start = hSpar->slots_rendered;
    2030      149650 :     move16();
    2031      149650 :     slot_fac_fx = BASOP_Util_Divide3232_Scale( 1, hSpar->subframe_nbslots[subframe], &q_slot_fac );
    2032      149650 :     IF( q_slot_fac < 0 )
    2033             :     {
    2034      146774 :         slot_fac_fx = shr( slot_fac_fx, -1 * q_slot_fac ); // Q15
    2035             :     }
    2036      742498 :     FOR( slot_idx = 0; slot_idx < hSpar->subframe_nbslots[subframe]; slot_idx++ )
    2037             :     {
    2038      592848 :         IF( hSpar->render_to_md_map[slot_idx + slot_idx_start] == 0 )
    2039             :         {
    2040       37069 :             sf = 0;
    2041       37069 :             move16();
    2042             :         }
    2043             :         ELSE
    2044             :         {
    2045      555779 :             sf = idiv1616( hSpar->render_to_md_map[slot_idx + slot_idx_start], JBM_CLDFB_SLOTS_IN_SUBFRAME );
    2046             :         }
    2047             : 
    2048      592848 :         IF( LT_16( sf, SPAR_META_DELAY_SUBFRAMES ) )
    2049             :         {
    2050      296437 :             mixer_mat_index = add( sf, add( sub( MAX_PARAM_SPATIAL_SUBFRAMES, SPAR_META_DELAY_SUBFRAMES ), 1 ) );
    2051     2667933 :             FOR( band = 0; band < SPAR_DIRAC_SPLIT_START_BAND; band++ )
    2052             :             {
    2053    11857480 :                 FOR( i = 0; i < FOA_CHANNELS; i++ )
    2054             :                 {
    2055    47429920 :                     FOR( j = 0; j < FOA_CHANNELS; j++ )
    2056             :                     {
    2057    37943936 :                         mixer_mat_sf_bands_real_fx[band][i][j] = L_shl( Mpy_32_16_1( st_ivas->hSpar->hMdDec->mixer_mat_prev_fx[mixer_mat_index][i][j][band], slot_fac_fx ), 1 ); // 30//making q to 31
    2058    37943936 :                         move32();
    2059             :                     }
    2060             :                 }
    2061             :             }
    2062             :         }
    2063             :         ELSE
    2064             :         {
    2065      296411 :             mixer_mat_index = ( ivas_get_spar_dec_md_num_subframes( st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->last_active_ivas_total_brate ) == 1 ) ? 0 : ( sf - SPAR_META_DELAY_SUBFRAMES );
    2066     2667699 :             FOR( band = 0; band < SPAR_DIRAC_SPLIT_START_BAND; band++ )
    2067             :             {
    2068    11856440 :                 FOR( i = 0; i < FOA_CHANNELS; i++ )
    2069             :                 {
    2070    47425760 :                     FOR( j = 0; j < FOA_CHANNELS; j++ )
    2071             :                     {
    2072    37940608 :                         mixer_mat_sf_bands_real_fx[band][i][j] = L_shl( Mpy_32_16_1( st_ivas->hSpar->hMdDec->mixer_mat_fx[i][j][band + mixer_mat_index * IVAS_MAX_NUM_BANDS], slot_fac_fx ), 1 ); // 30//making q to 31
    2073    37940608 :                         move32();
    2074             :                     }
    2075             :                 }
    2076             :             }
    2077             :         }
    2078             :     }
    2079             : 
    2080             :     /* Map the mixing matrices from the frequency bands to frequency bins */
    2081      149650 :     bin = 0;
    2082      149650 :     move16();
    2083     1346850 :     FOR( band = 0; band < SPAR_DIRAC_SPLIT_START_BAND; band++ )
    2084             :     {
    2085     1197200 :         band_start = band_grouping[band];
    2086     1197200 :         move16();
    2087     1197200 :         band_end = band_grouping[band + 1];
    2088     1197200 :         move16();
    2089     2843350 :         FOR( bin = band_start; bin < band_end; bin++ )
    2090             :         {
    2091     8230750 :             FOR( i = 0; i < FOA_CHANNELS; i++ )
    2092             :             {
    2093    32923000 :                 FOR( j = 0; j < FOA_CHANNELS; j++ )
    2094             :                 {
    2095    26338400 :                     mixer_mat_sf_bins_real_fx[bin][i][j] = mixer_mat_sf_bands_real_fx[band][i][j]; // 31
    2096    26338400 :                     move32();
    2097             :                 }
    2098             :             }
    2099             :         }
    2100             :     }
    2101             : 
    2102      149650 :     nBins = bin;
    2103      149650 :     move16();
    2104             : 
    2105             :     /* Determine MASA metadata */
    2106             :     /* Determine transport signal energies and cross correlations when more than 1 TC */
    2107      149650 :     IF( EQ_16( nchan_transport, 2 ) )
    2108             :     {
    2109      425232 :         FOR( slot = 0; slot < hSpatParamRendCom->subframe_nbslots[subframe]; slot++ )
    2110             :         {
    2111     4079856 :             FOR( bin = 0; bin < nBins; bin++ )
    2112             :             {
    2113    11219604 :                 FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
    2114             :                 {
    2115     7479736 :                     instEne_fx = W_mult0_32_32( L_shr_sat( inRe_fx[ch][slot][bin], sub( q_cldfb[ch][slot], common_q ) ), L_shr_sat( inRe_fx[ch][slot][bin], sub( q_cldfb[ch][slot], common_q ) ) );                               // Q(2 * common_q)
    2116     7479736 :                     instEne_fx = W_add( instEne_fx, W_mult0_32_32( (Word64) L_shr_sat( inIm_fx[ch][slot][bin], sub( q_cldfb[ch][slot], common_q ) ), L_shr_sat( inIm_fx[ch][slot][bin], sub( q_cldfb[ch][slot], common_q ) ) ) ); // Q(2 * common_q)
    2117     7479736 :                     transportSignalEnergies_64[ch][bin] = W_add( transportSignalEnergies_64[ch][bin], instEne_fx );                                                                                                               // Q(2 * common_q)
    2118     7479736 :                     move64();
    2119     7479736 :                     move64();
    2120             :                 }
    2121     3739868 :                 transportSignalCrossCorrelation_64[bin] = W_add( transportSignalCrossCorrelation_64[bin], W_mult0_32_32( L_shr_sat( inRe_fx[0][slot][bin], sub( q_cldfb[0][slot], common_q ) ), L_shr_sat( inRe_fx[1][slot][bin], sub( q_cldfb[0][slot], common_q ) ) ) ); // Q(2 * common_q)
    2122     3739868 :                 transportSignalCrossCorrelation_64[bin] = W_add( transportSignalCrossCorrelation_64[bin], W_mult0_32_32( L_shr_sat( inIm_fx[0][slot][bin], sub( q_cldfb[0][slot], common_q ) ), L_shr_sat( inIm_fx[1][slot][bin], sub( q_cldfb[0][slot], common_q ) ) ) ); // Q(2 * common_q)
    2123     3739868 :                 move64();
    2124     3739868 :                 move64();
    2125             :             }
    2126             :         }
    2127             : 
    2128             : 
    2129     1022928 :         FOR( bin = 0; bin < nBins; bin++ )
    2130             :         {
    2131     2813052 :             FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
    2132             :             {
    2133             :                 // transportSignalEnergies_max = GT_64( transportSignalEnergies_max, transportSignalEnergies_64[ch][bin] ) ? transportSignalEnergies_max : transportSignalEnergies_64[ch][bin];
    2134             : 
    2135     1875368 :                 if ( LE_64( transportSignalEnergies_max, transportSignalEnergies_64[ch][bin] ) )
    2136             :                 {
    2137      118023 :                     transportSignalEnergies_max = transportSignalEnergies_64[ch][bin]; // Q(2 * common_q)
    2138      118023 :                     move64();
    2139             :                 }
    2140             :             }
    2141             : 
    2142             :             // transportSignalCrossCorrelation_max = GT_64( transportSignalCrossCorrelation_max, transportSignalCrossCorrelation_64[bin] ) ? transportSignalCrossCorrelation_max : transportSignalCrossCorrelation_64[bin];
    2143             : 
    2144      937684 :             if ( LE_64( transportSignalCrossCorrelation_max, transportSignalCrossCorrelation_64[bin] ) )
    2145             :             {
    2146      115586 :                 transportSignalCrossCorrelation_max = transportSignalCrossCorrelation_64[bin]; // Q(2 * common_q)
    2147      115586 :                 move64();
    2148             :             }
    2149             :         }
    2150             : 
    2151             :         // max_common_val = GT_64( transportSignalEnergies_max, transportSignalCrossCorrelation_max ) ? transportSignalEnergies_max : transportSignalCrossCorrelation_max;
    2152             : 
    2153       85244 :         IF( GT_64( transportSignalEnergies_max, transportSignalCrossCorrelation_max ) )
    2154             :         {
    2155       85179 :             max_common_val = transportSignalEnergies_max; // Q(2 * common_q)
    2156             :         }
    2157             :         ELSE
    2158             :         {
    2159          65 :             max_common_val = transportSignalCrossCorrelation_max; // Q(2 * common_q)
    2160             :         }
    2161       85244 :         move64();
    2162             : 
    2163       85244 :         IF( max_common_val != 0 )
    2164             :         {
    2165       85179 :             headroom_left_max_common = W_norm( max_common_val );
    2166       85179 :             IF( GT_16( headroom_left_max_common, 32 ) )
    2167             :             {
    2168       39156 :                 FOR( bin = 0; bin < nBins; bin++ )
    2169             :                 {
    2170      107679 :                     FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
    2171             :                     {
    2172       71786 :                         transportSignalEnergies_32[ch][bin] = W_extract_l( transportSignalEnergies_64[ch][bin] ); // Q(q_max_common)
    2173       71786 :                         move32();
    2174             :                     }
    2175       35893 :                     transportSignalCrossCorrelation_32[bin] = W_extract_l( transportSignalCrossCorrelation_64[bin] ); // Q(q_max_common)
    2176       35893 :                     move32();
    2177             :                 }
    2178        3263 :                 q_max_common = shl( common_q, 1 );
    2179             :             }
    2180             :             ELSE
    2181             :             {
    2182      982992 :                 FOR( bin = 0; bin < nBins; bin++ )
    2183             :                 {
    2184     2703228 :                     FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
    2185             :                     {
    2186     1802152 :                         transportSignalEnergies_32[ch][bin] = W_extract_l( W_shr( transportSignalEnergies_64[ch][bin], sub( 32, headroom_left_max_common ) ) ); // Q(q_max_common)
    2187     1802152 :                         move32();
    2188             :                     }
    2189      901076 :                     transportSignalCrossCorrelation_32[bin] = W_extract_l( W_shr( transportSignalCrossCorrelation_64[bin], sub( 32, headroom_left_max_common ) ) ); // Q(q_max_common)
    2190      901076 :                     move32();
    2191             :                 }
    2192       81916 :                 q_max_common = sub( shl( common_q, 1 ), sub( 32, headroom_left_max_common ) );
    2193             :             }
    2194             :         }
    2195             :         ELSE
    2196             :         {
    2197         780 :             FOR( bin = 0; bin < nBins; bin++ )
    2198             :             {
    2199        2145 :                 FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
    2200             :                 {
    2201        1430 :                     transportSignalEnergies_32[ch][bin] = 0; // Q(q_max_common)
    2202        1430 :                     move32();
    2203             :                 }
    2204         715 :                 transportSignalCrossCorrelation_32[bin] = 0; // Q(q_max_common)
    2205         715 :                 move32();
    2206             :             }
    2207          65 :             q_max_common = 31;
    2208          65 :             move16();
    2209             :         }
    2210             :     }
    2211             : 
    2212             : 
    2213      149650 :     IF( hDiffuseDist != NULL )
    2214             :     {
    2215      149650 :         set32_fx( hDiffuseDist->diffuseRatioX_fx, 0, CLDFB_NO_CHANNELS_MAX );
    2216      149650 :         set32_fx( hDiffuseDist->diffuseRatioY_fx, 0, CLDFB_NO_CHANNELS_MAX );
    2217      149650 :         set32_fx( hDiffuseDist->diffuseRatioZ_fx, 0, CLDFB_NO_CHANNELS_MAX );
    2218             :     }
    2219             : 
    2220     1795800 :     FOR( bin = 0; bin < nBins; bin++ )
    2221             :     {
    2222             :         /* Set the energy of the first transport signal */
    2223     1646150 :         IF( EQ_16( nchan_transport, 1 ) )
    2224             :         {
    2225      708466 :             inCovarianceMtx_fx[0][0] = ONE_IN_Q31; /* In case of 1TC, fixed value can be used, Q(q_inCovarianceMtx)*/
    2226      708466 :             move32();
    2227      708466 :             q_inCovarianceMtx = 31; /* In case of 1TC, fixed value can be used */
    2228      708466 :             move16();
    2229             :         }
    2230             :         ELSE
    2231             :         {
    2232      937684 :             inCovarianceMtx_fx[0][0] = transportSignalEnergies_32[0][bin]; /* In case of 2TC, use actual energies */
    2233      937684 :             move32();
    2234      937684 :             q_inCovarianceMtx = q_max_common; /* In case of 1TC, fixed value can be used */
    2235      937684 :             move16();
    2236             :         }
    2237             : 
    2238             :         /* Decorrelated channels assumed to have the same energy as the source channel */
    2239     1646150 :         inCovarianceMtx_fx[1][1] = inCovarianceMtx_fx[0][0];
    2240     1646150 :         move32();
    2241     1646150 :         inCovarianceMtx_fx[2][2] = inCovarianceMtx_fx[0][0];
    2242     1646150 :         move32();
    2243     1646150 :         inCovarianceMtx_fx[3][3] = inCovarianceMtx_fx[0][0];
    2244     1646150 :         move32();
    2245             : 
    2246             :         /* In case residuals were transmitted, use their actual energies and cross correlations */
    2247     1646150 :         IF( EQ_16( nchan_transport, 2 ) )
    2248             :         {
    2249             : 
    2250      937684 :             inCovarianceMtx_fx[1][1] = transportSignalEnergies_32[1][bin];
    2251      937684 :             move32();
    2252      937684 :             inCovarianceMtx_fx[0][1] = transportSignalCrossCorrelation_32[bin];
    2253      937684 :             move32();
    2254      937684 :             inCovarianceMtx_fx[1][0] = inCovarianceMtx_fx[0][1];
    2255      937684 :             move32();
    2256      937684 :             q_inCovarianceMtx = q_max_common;
    2257      937684 :             move16();
    2258             :         }
    2259             : 
    2260     1646150 :         compute_foa_cov_matrix_fx( foaCovarianceMtx_fx, inCovarianceMtx_fx, mixer_mat_sf_bins_real_fx[bin] );
    2261             : 
    2262     1646150 :         Iy_fx = foaCovarianceMtx_fx[0][1]; /* Intensity in Y direction */ // Q(q_inCovarianceMtx) + 2 * Q(31) - 62
    2263     1646150 :         move32();
    2264     1646150 :         Iz_fx = foaCovarianceMtx_fx[0][2]; /* Intensity in Z direction */ // Q(q_inCovarianceMtx) + 2 * Q(31) - 62
    2265     1646150 :         move32();
    2266     1646150 :         Ix_fx = foaCovarianceMtx_fx[0][3]; /* Intensity in X direction */ // Q(q_inCovarianceMtx) + 2 * Q(31) - 62
    2267     1646150 :         move32();
    2268             : 
    2269     1646150 :         Word64 I1 = W_mult0_32_32( Ix_fx, Ix_fx );   // 2 * (Q(q_inCovarianceMtx) + 2 * Q(31) - 62)
    2270     1646150 :         Word64 I2 = W_mult0_32_32( Iy_fx, Iy_fx );   // 2 * (Q(q_inCovarianceMtx) + 2 * Q(31) - 62)
    2271     1646150 :         Word64 I3 = W_mult0_32_32( Iz_fx, Iz_fx );   // 2 * (Q(q_inCovarianceMtx) + 2 * Q(31) - 62)
    2272     1646150 :         Word64 I_res = W_add( W_add( I1, I2 ), I3 ); // 2 * (Q(q_inCovarianceMtx) + 2 * Q(31) - 62)
    2273             : 
    2274     1646150 :         Word64 E_fx_64 = W_add( W_add( W_add( foaCovarianceMtx_fx[0][0], foaCovarianceMtx_fx[1][1] ), foaCovarianceMtx_fx[2][2] ), foaCovarianceMtx_fx[3][3] ); // Q(q_inCovarianceMtx)
    2275     1646150 :         E_fx = L_shr_sat( L_add_sat( L_add_sat( L_add_sat( foaCovarianceMtx_fx[0][0], foaCovarianceMtx_fx[1][1] ), foaCovarianceMtx_fx[2][2] ), foaCovarianceMtx_fx[3][3] ), 1 );
    2276     1646150 :         E_fx_64 = W_shr( E_fx_64, 1 );
    2277             : 
    2278     1646150 :         Word16 headroom_left_I_res = W_norm( I_res );
    2279             :         Word16 q_I_res;
    2280     1646150 :         IF( LT_16( headroom_left_I_res, 32 ) )
    2281             :         {
    2282     1333344 :             I_res = W_shr( I_res, sub( 32, headroom_left_I_res ) ); // q_I_res
    2283     1333344 :             q_I_res = sub( 31, sub( shl( q_inCovarianceMtx, 1 ), sub( 32, headroom_left_I_res ) ) );
    2284             :         }
    2285             :         ELSE
    2286             :         {
    2287      312806 :             q_I_res = sub( 31, shl( q_inCovarianceMtx, 1 ) );
    2288             :         }
    2289     1646150 :         I_fx = Sqrt32( (Word32) I_res, &q_I_res );
    2290     1646150 :         IF( q_I_res < 0 )
    2291             :         {
    2292      665271 :             I_fx = L_shr( I_fx, -1 * q_I_res );
    2293      665271 :             q_I_res = 0;
    2294      665271 :             move16();
    2295             :         }
    2296     1646150 :         azi_q = 0;
    2297     1646150 :         move16();
    2298     1646150 :         azi_fx = BASOP_util_atan2( Iy_fx, Ix_fx, azi_q ); /* Azimuth Q13*/
    2299             : 
    2300     1646150 :         Word64 I_ele_x = W_mult0_32_32( Ix_fx, Ix_fx ); // Q(ele_q)
    2301     1646150 :         Word64 I_ele_y = W_mult0_32_32( Iy_fx, Iy_fx ); // Q(ele_q)
    2302     1646150 :         Word64 I_ele = W_add( I_ele_x, I_ele_y );       // Q(ele_q)
    2303     1646150 :         Word16 headroom_left_I_ele = W_norm( I_ele );
    2304     1646150 :         IF( LT_16( headroom_left_I_ele, 32 ) )
    2305             :         {
    2306     1324557 :             I_ele = W_shr( I_ele, sub( 32, headroom_left_I_ele ) );
    2307     1324557 :             ele_q = sub( 31, sub( shl( q_inCovarianceMtx, 1 ), sub( 32, headroom_left_I_ele ) ) );
    2308             :         }
    2309             :         ELSE
    2310             :         {
    2311      321593 :             ele_q = sub( 31, shl( q_inCovarianceMtx, 1 ) );
    2312             :         }
    2313     1646150 :         I_ele = Sqrt32( W_extract_l( I_ele ), &ele_q );
    2314     1646150 :         IF( ele_q < 0 )
    2315             :         {
    2316      651787 :             I_ele = W_shr( I_ele, negate( ele_q ) ); // Q0
    2317      651787 :             ele_q = 0;
    2318      651787 :             move16();
    2319             :         }
    2320     1646150 :         ele_fx = BASOP_util_atan2( Iz_fx, W_extract_l( I_ele ), sub( sub( 31, q_inCovarianceMtx ), ele_q ) ); // Q13
    2321             : 
    2322     1646150 :         num_q = sub( 31, q_I_res );
    2323     1646150 :         denom_q = q_inCovarianceMtx;
    2324     1646150 :         move16();
    2325     1646150 :         res_q = 0;
    2326     1646150 :         move16();
    2327     1646150 :         IF( E_fx <= 0 )
    2328             :         {
    2329        3620 :             E_fx = 1;
    2330        3620 :             move32();
    2331             :         }
    2332     1646150 :         ratio_float_fx = BASOP_Util_Divide3232_Scale( I_fx, E_fx, &res_q );
    2333     1646150 :         res_q = sub( res_q, sub( num_q, denom_q ) );
    2334     1646150 :         ratio_fx = L_shl_sat( ratio_float_fx, add( Q15, res_q ) ); // Q(15 + res_q)
    2335             : 
    2336     1646150 :         ratio_fx = L_max( 0, L_min( ratio_fx, ONE_IN_Q30 ) ); // Q30
    2337             : 
    2338     1646150 :         azi_val = W_mult0_32_32( azi_fx, ONE_BY_PI_OVER_180_Q25 ); // Q13 + Q25
    2339     1646150 :         IF( azi_val < 0 )
    2340             :         {
    2341     1055453 :             azi_val = W_shr( W_neg( azi_val ), 13 + 25 ); // Q0
    2342     1055453 :             azi_val = W_neg( azi_val );
    2343             :         }
    2344             :         ELSE
    2345             :         {
    2346      590697 :             azi_val = W_shr( azi_val, 13 + 25 ); // Q0
    2347             :         }
    2348     1646150 :         ele_val = W_mult0_32_32( ele_fx, ONE_BY_PI_OVER_180_Q25 ); // Q13 + q25
    2349     1646150 :         IF( ele_val < 0 )
    2350             :         {
    2351      603107 :             ele_val = W_shr( W_neg( ele_val ), 13 + 25 ); // Q0
    2352      603107 :             ele_val = W_neg( ele_val );                   // Q0
    2353             :         }
    2354             :         ELSE
    2355             :         {
    2356     1043043 :             ele_val = W_shr( ele_val, 13 + 25 ); // Q0
    2357             :         }
    2358             : 
    2359     1646150 :         hSpatParamRendCom->azimuth[dirac_write_idx][bin] = extract_l( W_extract_l( azi_val ) ); // Q0
    2360     1646150 :         move16();
    2361     1646150 :         hSpatParamRendCom->elevation[dirac_write_idx][bin] = extract_l( W_extract_l( ele_val ) ); // Q0
    2362     1646150 :         move16();
    2363     1646150 :         hSpatParamRendCom->energy_ratio1_fx[dirac_write_idx][bin] = ratio_fx; // Q30
    2364     1646150 :         move32();
    2365     1646150 :         hSpatParamRendCom->diffuseness_vector_fx[dirac_write_idx][bin] = L_sub( ONE_IN_Q30, ratio_fx ); // Q30
    2366     1646150 :         move32();
    2367             : 
    2368     1646150 :         hSpatParamRendCom->spreadCoherence_fx[dirac_write_idx][bin] = 0; // Q15
    2369     1646150 :         move16();
    2370     1646150 :         hSpatParamRendCom->surroundingCoherence_fx[dirac_write_idx][bin] = 0; // q15
    2371     1646150 :         move16();
    2372             : 
    2373             :         /* Determine directional distribution of the indirect audio based on the SPAR mixing matrices (and the transport audio signals when 2 TC) */
    2374     1646150 :         IF( hDiffuseDist != NULL )
    2375             :         {
    2376     1646150 :             IF( EQ_16( nchan_transport, 1 ) )
    2377             :             {
    2378      708466 :                 diffuseGainY_fx = L_abs( mixer_mat_sf_bins_real_fx[bin][1][1] ); // Q31
    2379      708466 :                 diffuseGainX_fx = L_abs( mixer_mat_sf_bins_real_fx[bin][3][2] ); // Q31
    2380      708466 :                 diffuseGainZ_fx = L_abs( mixer_mat_sf_bins_real_fx[bin][2][3] ); // Q31
    2381             :             }
    2382      937684 :             ELSE IF( EQ_16( nchan_transport, 2 ) )
    2383             :             {
    2384      937684 :                 diffuseGainY_fx = L_abs( Mpy_32_32( mixer_mat_sf_bins_real_fx[bin][1][1], transportSignalEnergies_32[1][bin] ) );                                                                                                              // Q(q_max_common)
    2385      937684 :                 diffuseGainX_fx = L_add_sat( L_abs( Mpy_32_32( mixer_mat_sf_bins_real_fx[bin][3][2], transportSignalEnergies_32[0][bin] ) ), L_abs( Mpy_32_32( mixer_mat_sf_bins_real_fx[bin][3][1], transportSignalEnergies_32[1][bin] ) ) ); // Q(q_max_common)
    2386      937684 :                 diffuseGainZ_fx = L_add_sat( L_abs( Mpy_32_32( mixer_mat_sf_bins_real_fx[bin][2][3], transportSignalEnergies_32[0][bin] ) ), L_abs( Mpy_32_32( mixer_mat_sf_bins_real_fx[bin][2][1], transportSignalEnergies_32[1][bin] ) ) ); // Q(q_max_common)
    2387             :             }
    2388             :             ELSE
    2389             :             {
    2390           0 :                 diffuseGainY_fx = ONE_IN_Q31;
    2391           0 :                 move32();
    2392           0 :                 diffuseGainX_fx = ONE_IN_Q31;
    2393           0 :                 move32();
    2394           0 :                 diffuseGainZ_fx = ONE_IN_Q31;
    2395           0 :                 move32();
    2396             :             }
    2397     1646150 :             diffuseGainSum_fx = L_add_sat( L_add_sat( diffuseGainY_fx, diffuseGainX_fx ), diffuseGainZ_fx );
    2398             : 
    2399     1646150 :             IF( diffuseGainSum_fx == 0 )
    2400             :             {
    2401       29006 :                 hDiffuseDist->diffuseRatioX_fx[bin] = 715827904; //(1.0f / 3.0f) in Q31
    2402       29006 :                 move32();
    2403       29006 :                 hDiffuseDist->diffuseRatioY_fx[bin] = 715827904;
    2404       29006 :                 move32();
    2405       29006 :                 hDiffuseDist->diffuseRatioZ_fx[bin] = 715827904;
    2406       29006 :                 move32();
    2407             :             }
    2408             :             ELSE
    2409             :             {
    2410     1617144 :                 Word16 temp_q = 0;
    2411     1617144 :                 move16();
    2412             :                 Word16 intermediate_results; // temp_q
    2413     1617144 :                 intermediate_results = BASOP_Util_Divide3232_Scale( diffuseGainX_fx, L_add_sat( diffuseGainSum_fx, EPSILON_FX_SMALL ), &temp_q );
    2414             :                 // saturating value to less than 1
    2415     1617144 :                 IF( temp_q <= 0 )
    2416             :                 {
    2417     1435964 :                     intermediate_results = shr( intermediate_results, negate( temp_q ) ); // Q15
    2418             :                 }
    2419             :                 ELSE
    2420             :                 {
    2421      181180 :                     intermediate_results = shl_sat( intermediate_results, temp_q ); // Q15
    2422             :                 }
    2423     1617144 :                 hDiffuseDist->diffuseRatioX_fx[bin] = L_deposit_h( intermediate_results ); // Q31
    2424     1617144 :                 move32();
    2425             : 
    2426     1617144 :                 intermediate_results = BASOP_Util_Divide3232_Scale( diffuseGainY_fx, L_add_sat( diffuseGainSum_fx, EPSILON_FX_SMALL ), &temp_q );
    2427             :                 // saturating value to less than 1
    2428     1617144 :                 IF( temp_q <= 0 )
    2429             :                 {
    2430     1535534 :                     intermediate_results = shr( intermediate_results, negate( temp_q ) ); // Q15
    2431             :                 }
    2432             :                 ELSE
    2433             :                 {
    2434       81610 :                     intermediate_results = shl_sat( intermediate_results, temp_q ); // Q15
    2435             :                 }
    2436     1617144 :                 hDiffuseDist->diffuseRatioY_fx[bin] = L_deposit_h( intermediate_results ); // Q31
    2437     1617144 :                 move32();
    2438             : 
    2439     1617144 :                 intermediate_results = BASOP_Util_Divide3232_Scale( diffuseGainZ_fx, L_add_sat( diffuseGainSum_fx, EPSILON_FX_SMALL ), &temp_q );
    2440             :                 // saturating value to less than 1
    2441     1617144 :                 IF( temp_q <= 0 )
    2442             :                 {
    2443     1408818 :                     intermediate_results = shr( intermediate_results, negate( temp_q ) ); // Q15
    2444             :                 }
    2445             :                 ELSE
    2446             :                 {
    2447      208326 :                     intermediate_results = shl_sat( intermediate_results, temp_q ); // Q15
    2448             :                 }
    2449     1617144 :                 hDiffuseDist->diffuseRatioZ_fx[bin] = L_deposit_h( intermediate_results ); // Q31
    2450     1617144 :                 move32();
    2451             :             }
    2452             :         }
    2453             :     }
    2454             : 
    2455      149650 :     return;
    2456             : }
    2457             : 
    2458             : 
    2459             : /* Estimate FOA properties: foaCov = mixMtx * inCov * mixMtx' */
    2460     1646150 : static void compute_foa_cov_matrix_fx(
    2461             :     Word32 foaCov_fx[FOA_CHANNELS][FOA_CHANNELS], /* o  : Estimated FOA covariance matrix Qx*/
    2462             :     Word32 inCov_fx[FOA_CHANNELS][FOA_CHANNELS],  /* i  : Input covariance matrix         Qx*/
    2463             :     Word32 mixMtx_fx[FOA_CHANNELS][FOA_CHANNELS]  /* i  : Mixing matrix                   Q31*/
    2464             : )
    2465             : {
    2466             :     Word32 tmpMtx_fx[FOA_CHANNELS][FOA_CHANNELS];
    2467             :     Word16 i, j, k;
    2468             :     /* tmpMtx = mixMtx * inCov */
    2469     8230750 :     FOR( i = 0; i < FOA_CHANNELS; i++ )
    2470             :     {
    2471    32923000 :         FOR( j = 0; j < FOA_CHANNELS; j++ )
    2472             :         {
    2473    26338400 :             tmpMtx_fx[i][j] = 0;
    2474    26338400 :             move32();
    2475   131692000 :             FOR( k = 0; k < FOA_CHANNELS; k++ )
    2476             :             {
    2477   105353600 :                 tmpMtx_fx[i][j] = L_add_sat( tmpMtx_fx[i][j], Mpy_32_32( mixMtx_fx[i][k], inCov_fx[k][j] ) ); // Qx
    2478   105353600 :                 move32();
    2479             :             }
    2480             :         }
    2481             :     }
    2482             : 
    2483             :     /* foaCov = inCov * mixMtx' */
    2484     8230750 :     FOR( i = 0; i < FOA_CHANNELS; i++ )
    2485             :     {
    2486    32923000 :         FOR( j = 0; j < FOA_CHANNELS; j++ )
    2487             :         {
    2488    26338400 :             foaCov_fx[i][j] = 0;
    2489    26338400 :             move32();
    2490   131692000 :             FOR( k = 0; k < FOA_CHANNELS; k++ )
    2491             :             {
    2492   105353600 :                 foaCov_fx[i][j] = L_add_sat( foaCov_fx[i][j], Mpy_32_32( tmpMtx_fx[i][k], mixMtx_fx[j][k] ) ); // Qx
    2493   105353600 :                 move32();
    2494             :             }
    2495             :         }
    2496             :     }
    2497             : 
    2498     1646150 :     return;
    2499             : }
    2500             : 
    2501             : 
    2502        5462 : static void create_masa_ext_out_meta_fx(
    2503             :     MASA_DECODER *hMasa,
    2504             :     IVAS_QMETADATA_HANDLE hQMetaData,
    2505             :     const Word16 nchan_transport )
    2506             : {
    2507        5462 :     const UWord8 ivasmasaFormatDescriptor[8] = { 0x49, 0x56, 0x41, 0x53, 0x4D, 0x41, 0x53, 0x41 }; /* "IVASMASA" */
    2508             :     Word16 i, sf, b_old, b_new, dir;
    2509             :     MASA_DECRIPTIVE_META *descMeta;
    2510             :     Word16 *bandMap;
    2511             :     UWord8 numCodingBands;
    2512             :     UWord8 numDirections;
    2513             :     MASA_DECODER_EXT_OUT_META *extOutMeta;
    2514        5462 :     move16(); /*ivasmasaFormatDescriptor*/
    2515        5462 :     move16();
    2516        5462 :     move16();
    2517        5462 :     move16();
    2518        5462 :     move16();
    2519        5462 :     move16();
    2520        5462 :     move16();
    2521        5462 :     move16();
    2522             : 
    2523        5462 :     numDirections = hMasa->config.numberOfDirections;
    2524        5462 :     move16();
    2525        5462 :     numCodingBands = hMasa->config.numCodingBands;
    2526        5462 :     move16();
    2527        5462 :     bandMap = hMasa->data.band_mapping;
    2528        5462 :     move16();
    2529        5462 :     extOutMeta = hMasa->data.extOutMeta;
    2530        5462 :     descMeta = &hMasa->data.extOutMeta->descriptiveMeta;
    2531             : 
    2532             :     /* Construct descriptive meta */
    2533       49158 :     FOR( i = 0; i < 8; i++ )
    2534             :     {
    2535       43696 :         descMeta->formatDescriptor[i] = ivasmasaFormatDescriptor[i];
    2536       43696 :         move16();
    2537             :     }
    2538        5462 :     descMeta->numberOfDirections = (UWord8) sub( numDirections, 1 );
    2539        5462 :     descMeta->numberOfChannels = (UWord8) ( sub( nchan_transport, 1 ) );
    2540             :     /* Following correspond to "unknown" values until transmission is implemented */
    2541        5462 :     descMeta->sourceFormat = 0x0u;
    2542        5462 :     descMeta->transportDefinition = 0x0u;
    2543        5462 :     descMeta->channelAngle = 0x0u;
    2544        5462 :     descMeta->channelDistance = 0x0u;
    2545        5462 :     descMeta->channelLayout = 0x0u;
    2546             : 
    2547        5462 :     move16();
    2548        5462 :     move16();
    2549        5462 :     move16();
    2550        5462 :     move16();
    2551        5462 :     move16();
    2552        5462 :     move16();
    2553        5462 :     move16();
    2554             : 
    2555             :     /* Construct spatial metadata from qmetadata */
    2556       27310 :     FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
    2557             :     {
    2558       50640 :         FOR( dir = 0; dir < numDirections; dir++ )
    2559             :         {
    2560             :             /* Spherical index */
    2561      295416 :             FOR( b_old = 0; b_old < numCodingBands; b_old++ )
    2562             :             {
    2563      952424 :                 FOR( b_new = bandMap[b_old]; b_new < bandMap[b_old + 1]; b_new++ )
    2564             :                 {
    2565      685800 :                     extOutMeta->directionIndex[dir][sf][b_new] = hQMetaData->q_direction[dir].band_data[b_old].spherical_index[sf];
    2566      685800 :                     move16();
    2567             :                 }
    2568             :             }
    2569             : 
    2570             :             /* Direct-to-total ratio */
    2571      295416 :             FOR( b_old = 0; b_old < numCodingBands; b_old++ )
    2572             :             {
    2573      952424 :                 FOR( b_new = bandMap[b_old]; b_new < bandMap[b_old + 1]; b_new++ )
    2574             :                 {
    2575      685800 :                     IF( EQ_32( hQMetaData->q_direction[dir].band_data[b_old].energy_ratio_fx[sf], ONE_IN_Q30 ) )
    2576             :                     {
    2577         214 :                         hQMetaData->q_direction[dir].band_data[b_old].energy_ratio_fx[sf]--;
    2578             :                     }
    2579      685800 :                     UWord8 tmp = (UWord8) L_shr( hQMetaData->q_direction[dir].band_data[b_old].energy_ratio_fx[sf], Q30 - 8 ); // Q8
    2580      685800 :                     move16();
    2581      685800 :                     extOutMeta->directToTotalRatio[dir][sf][b_new] = tmp; // Q8
    2582      685800 :                     move16();
    2583             :                 }
    2584             :             }
    2585             : 
    2586             :             /* Spread coherence */
    2587       28792 :             IF( hQMetaData->q_direction[dir].coherence_band_data != NULL )
    2588             :             {
    2589      248328 :                 FOR( b_old = 0; b_old < numCodingBands; b_old++ )
    2590             :                 {
    2591      730040 :                     FOR( b_new = bandMap[b_old]; b_new < bandMap[b_old + 1]; b_new++ )
    2592             :                     {
    2593      502656 :                         extOutMeta->spreadCoherence[dir][sf][b_new] = hQMetaData->q_direction[dir].coherence_band_data[b_old].spread_coherence[sf];
    2594      502656 :                         move16();
    2595             :                     }
    2596             :                 }
    2597             :             }
    2598             :             ELSE
    2599             :             {
    2600      196200 :                 FOR( i = 0; i < MASA_FREQUENCY_BANDS; i++ )
    2601             :                 {
    2602      188352 :                     extOutMeta->spreadCoherence[dir][sf][i] = 0;
    2603      188352 :                     move16();
    2604             :                 }
    2605             :             }
    2606             :         }
    2607             : 
    2608             :         /* Fill second direction with zero energy data for EXT output */
    2609       21848 :         IF( EQ_16( numDirections, 1 ) )
    2610             :         {
    2611      372600 :             FOR( i = 0; i < MASA_FREQUENCY_BANDS; i++ )
    2612             :             {
    2613      357696 :                 extOutMeta->directionIndex[1][sf][i] = SPH_IDX_FRONT;
    2614      357696 :                 move16();
    2615             :             }
    2616             : 
    2617      372600 :             FOR( i = 0; i < MASA_FREQUENCY_BANDS; i++ )
    2618             :             {
    2619      357696 :                 extOutMeta->directToTotalRatio[1][sf][i] = 0;
    2620      357696 :                 move16();
    2621             :             }
    2622             : 
    2623      372600 :             FOR( i = 0; i < MASA_FREQUENCY_BANDS; i++ )
    2624             :             {
    2625      357696 :                 extOutMeta->spreadCoherence[1][sf][i] = 0;
    2626      357696 :                 move16();
    2627             :             }
    2628             :         }
    2629             : 
    2630             :         /* Common spatial meta */
    2631             :         /* Diffuse-to-total ratio = 1 - sum(direct-to-total ratios) */
    2632      204444 :         FOR( b_old = 0; b_old < numCodingBands; b_old++ )
    2633             :         {
    2634      701740 :             FOR( b_new = bandMap[b_old]; b_new < bandMap[b_old + 1]; b_new++ )
    2635             :             {
    2636      519144 :                 extOutMeta->diffuseToTotalRatio[sf][b_new] = UINT8_MAX;
    2637      519144 :                 move16();
    2638     1204944 :                 FOR( dir = 0; dir < numDirections; dir++ )
    2639             :                 {
    2640             :                     /* todo: not optimal, but less invasive */
    2641      685800 :                     IF( EQ_32( hQMetaData->q_direction[dir].band_data[b_old].energy_ratio_fx[sf], ONE_IN_Q30 ) )
    2642             :                     {
    2643           0 :                         hQMetaData->q_direction[dir].band_data[b_old].energy_ratio_fx[sf]--;
    2644             :                     }
    2645      685800 :                     UWord8 tmp = (UWord8) L_shr( hQMetaData->q_direction[dir].band_data[b_old].energy_ratio_fx[sf], Q30 - 8 ); // Q8
    2646      685800 :                     move16();
    2647      685800 :                     extOutMeta->diffuseToTotalRatio[sf][b_new] = (UWord8) sub( extOutMeta->diffuseToTotalRatio[sf][b_new], tmp ); // Q8
    2648      685800 :                     move16();
    2649             :                 }
    2650             :             }
    2651             :         }
    2652             : 
    2653             :         /* Surround coherence */
    2654       21848 :         IF( hQMetaData->surcoh_band_data != NULL )
    2655             :         {
    2656      157356 :             FOR( b_old = 0; b_old < numCodingBands; b_old++ )
    2657             :             {
    2658      479356 :                 FOR( b_new = bandMap[b_old]; b_new < bandMap[b_old + 1]; b_new++ )
    2659             :                 {
    2660      336000 :                     extOutMeta->surroundCoherence[sf][b_new] = hQMetaData->surcoh_band_data[b_old].surround_coherence[sf];
    2661      336000 :                     move16();
    2662             :                 }
    2663             :             }
    2664             :         }
    2665             :         ELSE
    2666             :         {
    2667      196200 :             FOR( i = 0; i < MASA_FREQUENCY_BANDS; i++ )
    2668             :             {
    2669      188352 :                 extOutMeta->surroundCoherence[sf][i] = 0;
    2670      188352 :                 move16();
    2671             :             }
    2672             :         }
    2673             :     }
    2674             : 
    2675        5462 :     return;
    2676             : }
    2677             : 
    2678             : 
    2679        5775 : static void decode_index_slice_fx(
    2680             :     Word16 index,           /* i  : index to decode                        */
    2681             :     Word16 *ratio_idx_ism,  /* o  : decodec array of integers              Q0*/
    2682             :     const Word16 nchan_ism, /* i  : number of elements in array (objects)  */
    2683             :     const Word16 K          /* i  : sum of array elements                  Q0*/
    2684             : )
    2685             : {
    2686             :     Word16 i, j, sum, elem;
    2687             :     Word16 base[MAX_NUM_OBJECTS];
    2688             : 
    2689        5775 :     SWITCH( nchan_ism )
    2690             :     {
    2691         217 :         case 2:
    2692         217 :             ratio_idx_ism[0] = index;
    2693         217 :             move16();
    2694         217 :             ratio_idx_ism[1] = sub( K, ratio_idx_ism[0] );
    2695         217 :             move16();
    2696         217 :             BREAK;
    2697        5558 :         case 3:
    2698             :         case 4:
    2699             :         {
    2700        5558 :             j = 0;
    2701        5558 :             move16();
    2702      764963 :             WHILE( index >= 0 )
    2703             :             {
    2704      759405 :                 IF( valid_ratio_index_fx( j, K, nchan_ism - 1 ) )
    2705             :                 {
    2706      209974 :                     index = sub( index, 1 );
    2707             :                 }
    2708      759405 :                 j = add( j, 1 );
    2709             :             }
    2710        5558 :             j = sub( j, 1 );
    2711        5558 :             base[0] = 1;
    2712        5558 :             move16();
    2713       14869 :             FOR( i = 1; i < nchan_ism - 1; i++ )
    2714             :             {
    2715        9311 :                 base[i] = i_mult( base[i - 1], 10 );
    2716        9311 :                 move16();
    2717             :             }
    2718        5558 :             sum = 0;
    2719        5558 :             move16();
    2720       20427 :             FOR( i = nchan_ism - 2; i >= 0; i-- )
    2721             :             {
    2722       14869 :                 IF( EQ_16( j, 0 ) )
    2723             :                 {
    2724        3190 :                     elem = 0;
    2725        3190 :                     move16();
    2726             :                 }
    2727             :                 ELSE
    2728             :                 {
    2729       11679 :                     elem = idiv1616( j, base[i] );
    2730             :                 }
    2731       14869 :                 ratio_idx_ism[nchan_ism - i - 2] = elem;
    2732       14869 :                 move16();
    2733       14869 :                 sum = add( sum, elem );
    2734       14869 :                 j = sub( j, i_mult( elem, base[i] ) );
    2735             :             }
    2736        5558 :             ratio_idx_ism[nchan_ism - 1] = sub( K, sum );
    2737        5558 :             move16();
    2738             :         }
    2739             : 
    2740        5558 :         default:
    2741        5558 :             BREAK;
    2742             :     }
    2743             : 
    2744        5775 :     return;
    2745             : }
    2746             : 
    2747             : 
    2748        4777 : static void read_ism_ratio_index_fx(
    2749             :     Word16 ratio_ism_idx[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS],         /* o  : ISM read ratio indexes                                        Q0*/
    2750             :     const Word16 nchan_ism,                                              /* i  : number of objects                                             */
    2751             :     const Word16 numCodingBands,                                         /* i  : number of subbands                                            */
    2752             :     const Word16 sf,                                                     /* i  : index of subframe                                             */
    2753             :     Word16 ratio_ism_idx_prev_sf[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS], /* i  : previous subframe ISM ratio indexes                           Q0*/
    2754             :     UWord16 *bit_stream,                                                 /* i  : bitstream                                                     */
    2755             :     Word16 *next_bit_pos,                                                /* i/o: position in bitstream                                         */
    2756             :     const Word32 *masa_to_total_energy_ratio_fx,                         /* i  : masa to total ratios                                          Q30*/
    2757             :     const Word16 idx_sep_obj,                                            /* i  : index of separated index, -1 if none                          */
    2758             :     Word16 *num_zeros                                                    /* i/o: number of zero values in first subframe for separated object  */
    2759             : )
    2760             : {
    2761             :     Word16 b, i, b_signif;
    2762             :     Word16 index;
    2763             :     Word16 GR_order, differential_subframe;
    2764             :     Word16 buf;
    2765             :     Word16 no_levels_ratio_ism;
    2766             :     Word16 bits_index;
    2767             :     Word16 ratio_ism_idx_ref[MAX_NUM_OBJECTS];
    2768             :     Word16 idx_sep_obj_local, shift_one;
    2769             : 
    2770        4777 :     idx_sep_obj_local = idx_sep_obj;
    2771        4777 :     move16();
    2772             : 
    2773        4777 :     IF( GT_16( idx_sep_obj, -1 ) )
    2774             :     {
    2775        4777 :         test();
    2776        4777 :         if ( EQ_16( idx_sep_obj, sub( nchan_ism, 1 ) ) && GT_16( nchan_ism, 2 ) )
    2777             :         {
    2778         766 :             idx_sep_obj_local = 0;
    2779         766 :             move16();
    2780             :         }
    2781             :     }
    2782             : 
    2783        4777 :     b_signif = 0;
    2784        4777 :     move16();
    2785        4777 :     no_levels_ratio_ism = sub( shl( 1, PARAM_ISM_POW_RATIO_NBITS ), 1 );
    2786             : 
    2787        5265 :     WHILE( ( LT_16( b_signif, numCodingBands ) ) && ( GE_32( masa_to_total_energy_ratio_fx[b_signif], MASA2TOTAL_THR_Q30 ) ) )
    2788             :     {
    2789         488 :         test();
    2790             :         /* distribute evenly the objects */
    2791         488 :         distribute_evenly_ism_fx( ratio_ism_idx[b_signif], no_levels_ratio_ism, nchan_ism );
    2792         488 :         b_signif = add( b_signif, 1 );
    2793             :     }
    2794             : 
    2795        4777 :     IF( EQ_16( b_signif, numCodingBands ) )
    2796             :     {
    2797          72 :         return;
    2798             :     }
    2799             :     ELSE
    2800             :     {
    2801             : 
    2802        4705 :         IF( sf == 0 )
    2803             :         {
    2804        1553 :             bits_index = bits_index_ism_ratio_fx( nchan_ism );
    2805             : 
    2806             :             /* read coding type */
    2807        1553 :             IF( EQ_32( bit_stream[( *next_bit_pos )--], 1 ) )
    2808             :             {
    2809             :                 /* independent coding*/
    2810        6700 :                 FOR( b = 0; b < numCodingBands; b++ )
    2811             :                 {
    2812        5749 :                     IF( LT_32( masa_to_total_energy_ratio_fx[b], MASA2TOTAL_THR_Q30 ) )
    2813             :                     {
    2814        5173 :                         index = 0;
    2815        5173 :                         move16();
    2816       39539 :                         FOR( i = 0; i < bits_index; i++ )
    2817             :                         {
    2818       34366 :                             index = add( shl( index, 1 ), (Word16) bit_stream[( *next_bit_pos )--] );
    2819             :                         }
    2820        5173 :                         decode_index_slice_fx( index, ratio_ism_idx[b], nchan_ism, no_levels_ratio_ism );
    2821        5173 :                         test();
    2822        5173 :                         IF( GT_16( idx_sep_obj, -1 ) && EQ_16( ratio_ism_idx[b][idx_sep_obj_local], 0 ) )
    2823             :                         {
    2824        4707 :                             *num_zeros = add( *num_zeros, 1 );
    2825        4707 :                             move16();
    2826             :                         }
    2827             :                     }
    2828             :                     ELSE
    2829             :                     {
    2830             :                         /* distribute evenly the objects */
    2831         576 :                         distribute_evenly_ism_fx( ratio_ism_idx[b], no_levels_ratio_ism, nchan_ism );
    2832             :                     }
    2833             :                 }
    2834             :             }
    2835             :             ELSE
    2836             :             {
    2837             :                 /* differential coding */
    2838         602 :                 index = 0;
    2839         602 :                 move16();
    2840        3988 :                 FOR( i = 0; i < bits_index; i++ )
    2841             :                 {
    2842        3386 :                     index = add( shl( index, 1 ), (Word16) bit_stream[( *next_bit_pos )--] );
    2843             :                 }
    2844         602 :                 decode_index_slice_fx( index, ratio_ism_idx[b_signif], nchan_ism, no_levels_ratio_ism );
    2845         602 :                 test();
    2846         602 :                 IF( GT_16( idx_sep_obj, -1 ) && ratio_ism_idx[b_signif][idx_sep_obj_local] == 0 )
    2847             :                 {
    2848         549 :                     *num_zeros = add( *num_zeros, 1 );
    2849         549 :                     move16();
    2850             :                 }
    2851         602 :                 Copy( ratio_ism_idx[b_signif], ratio_ism_idx_ref, nchan_ism );
    2852        4484 :                 FOR( b = b_signif + 1; b < numCodingBands; b++ )
    2853             :                 {
    2854        3882 :                     IF( LT_32( masa_to_total_energy_ratio_fx[b], MASA2TOTAL_THR_Q30 ) )
    2855             :                     {
    2856        3467 :                         ratio_ism_idx[b][nchan_ism - 1] = no_levels_ratio_ism;
    2857        3467 :                         move16();
    2858       11169 :                         FOR( i = 0; i < nchan_ism - 1; i++ )
    2859             :                         {
    2860        7702 :                             buf = ivas_qmetadata_DecodeExtendedGR( bit_stream, next_bit_pos, 100, 0 );
    2861        7702 :                             IF( EQ_16( buf % 2, 0 ) )
    2862             :                             {
    2863        6512 :                                 ratio_ism_idx[b][i] = negate( shr( buf, 1 ) );
    2864        6512 :                                 move16();
    2865             :                             }
    2866             :                             ELSE
    2867             :                             {
    2868        1190 :                                 ratio_ism_idx[b][i] = shr( add( buf, 1 ), 1 );
    2869        1190 :                                 move16();
    2870             :                             }
    2871        7702 :                             ratio_ism_idx[b][i] = add( ratio_ism_idx[b][i], ratio_ism_idx_ref[i] );
    2872        7702 :                             move16();
    2873        7702 :                             ratio_ism_idx[b][nchan_ism - 1] = sub( ratio_ism_idx[b][nchan_ism - 1], ratio_ism_idx[b][i] );
    2874        7702 :                             move16();
    2875             :                         }
    2876        3467 :                         Copy( ratio_ism_idx[b], ratio_ism_idx_ref, nchan_ism );
    2877        3467 :                         test();
    2878        3467 :                         IF( GT_16( idx_sep_obj, -1 ) && EQ_16( ratio_ism_idx[b][idx_sep_obj_local], 0 ) )
    2879             :                         {
    2880        3099 :                             *num_zeros = add( *num_zeros, 1 );
    2881        3099 :                             move16();
    2882             :                         }
    2883             :                     }
    2884             :                     ELSE
    2885             :                     {
    2886             :                         /* distribute evenly the objects */
    2887         415 :                         distribute_evenly_ism_fx( ratio_ism_idx[b], no_levels_ratio_ism, nchan_ism );
    2888             :                     }
    2889             :                 }
    2890             :             }
    2891             :         }
    2892             :         ELSE
    2893             :         {
    2894        3152 :             IF( GT_16( numCodingBands, 1 ) )
    2895             :             {
    2896             :                 /* read prediction type */
    2897        3108 :                 differential_subframe = bit_stream[( *next_bit_pos )--];
    2898        3108 :                 move16();
    2899             :             }
    2900             :             ELSE
    2901             :             {
    2902          44 :                 differential_subframe = 1;
    2903          44 :                 move16();
    2904             :             }
    2905             : 
    2906        3152 :             IF( EQ_16( *num_zeros, numCodingBands ) )
    2907             :             {
    2908        1785 :                 shift_one = 1;
    2909        1785 :                 move16();
    2910             :             }
    2911             :             ELSE
    2912             :             {
    2913        1367 :                 shift_one = 0;
    2914        1367 :                 move16();
    2915             :             }
    2916             : 
    2917        3152 :             test();
    2918        3152 :             IF( EQ_16( shift_one, 1 ) && EQ_16( nchan_ism, 2 ) )
    2919             :             {
    2920             :                 /* nothing has been sent ; values can be inferred */
    2921          72 :                 FOR( b = b_signif; b < numCodingBands; b++ )
    2922             :                 {
    2923          36 :                     IF( LT_32( masa_to_total_energy_ratio_fx[b], MASA2TOTAL_THR_Q30 ) )
    2924             :                     {
    2925          36 :                         IF( idx_sep_obj_local == 0 )
    2926             :                         {
    2927          30 :                             ratio_ism_idx[b][0] = 0;
    2928          30 :                             move16();
    2929          30 :                             ratio_ism_idx[b][1] = 7;
    2930          30 :                             move16();
    2931             :                         }
    2932             :                         ELSE
    2933             :                         {
    2934           6 :                             ratio_ism_idx[b][0] = 7;
    2935           6 :                             move16();
    2936           6 :                             ratio_ism_idx[b][1] = 0;
    2937           6 :                             move16();
    2938             :                         }
    2939             :                     }
    2940             :                 }
    2941             :             }
    2942             :             ELSE
    2943             :             {
    2944             :                 /* read GR order */
    2945        3116 :                 GR_order = bit_stream[( *next_bit_pos )--];
    2946        3116 :                 move16();
    2947             : 
    2948       18498 :                 FOR( b = b_signif; b < numCodingBands; b++ )
    2949             :                 {
    2950       15382 :                     IF( LT_32( masa_to_total_energy_ratio_fx[b], MASA2TOTAL_THR_Q30 ) )
    2951             :                     {
    2952       40314 :                         FOR( i = 0; i < nchan_ism - ( 1 + shift_one ); i++ )
    2953             :                         {
    2954       26456 :                             buf = ivas_qmetadata_DecodeExtendedGR( bit_stream, next_bit_pos, 100, GR_order );
    2955       26456 :                             IF( ( buf % 2 ) == 0 )
    2956             :                             {
    2957       21199 :                                 ratio_ism_idx[b][i] = negate( shr( buf, 1 ) );
    2958       21199 :                                 move16();
    2959             :                             }
    2960             :                             ELSE
    2961             :                             {
    2962        5257 :                                 ratio_ism_idx[b][i] = shr( add( buf, 1 ), 1 );
    2963        5257 :                                 move16();
    2964             :                             }
    2965             :                         }
    2966             : 
    2967             :                         /* insert separated obj */
    2968       13858 :                         IF( shift_one )
    2969             :                         {
    2970       25650 :                             FOR( i = nchan_ism - 1; i > idx_sep_obj_local; i-- )
    2971             :                             {
    2972       17303 :                                 ratio_ism_idx[b][i] = ratio_ism_idx[b][i - 1];
    2973       17303 :                                 move16();
    2974             :                             }
    2975        8347 :                             ratio_ism_idx[b][idx_sep_obj_local] = 0; /* this is only difference; need to pdate later as well  */
    2976        8347 :                             move16();
    2977             :                         }
    2978             :                     }
    2979             :                 }
    2980        3116 :                 IF( differential_subframe )
    2981             :                 {
    2982             :                     /* differential to previous subframe */
    2983       16690 :                     FOR( b = b_signif; b < numCodingBands; b++ )
    2984             :                     {
    2985       13876 :                         IF( LT_32( masa_to_total_energy_ratio_fx[b], MASA2TOTAL_THR_Q30 ) )
    2986             :                         {
    2987       12531 :                             ratio_ism_idx[b][sub( nchan_ism, 1 )] = no_levels_ratio_ism;
    2988       12531 :                             move16();
    2989       44158 :                             FOR( i = 0; i < nchan_ism - 1; i++ )
    2990             :                             {
    2991       31627 :                                 ratio_ism_idx[b][i] = add( ratio_ism_idx[b][i], ratio_ism_idx_prev_sf[b][i] );
    2992       31627 :                                 move16();
    2993             : 
    2994       31627 :                                 test();
    2995       31627 :                                 if ( ( shift_one != 0 ) && EQ_16( i, idx_sep_obj_local ) )
    2996             :                                 {
    2997        7977 :                                     ratio_ism_idx[b][i] = 0;
    2998        7977 :                                     move16();
    2999             :                                 }
    3000       31627 :                                 ratio_ism_idx[b][nchan_ism - 1] = sub( ratio_ism_idx[b][nchan_ism - 1], ratio_ism_idx[b][i] );
    3001             :                             }
    3002             :                         }
    3003             :                         ELSE
    3004             :                         {
    3005             :                             /* distribute evenly the objects */
    3006        1345 :                             distribute_evenly_ism_fx( ratio_ism_idx[b], no_levels_ratio_ism, nchan_ism );
    3007             :                         }
    3008             :                     }
    3009             :                 }
    3010             :                 ELSE
    3011             :                 {
    3012             :                     /* difference to previous subband */
    3013         302 :                     ratio_ism_idx[b_signif][nchan_ism - 1] = no_levels_ratio_ism;
    3014         302 :                     move16();
    3015             : 
    3016             :                     /* first significant subband - differential to previous subframe */
    3017        1022 :                     FOR( i = 0; i < nchan_ism - 1; i++ )
    3018             :                     {
    3019         720 :                         ratio_ism_idx[b_signif][i] = add( ratio_ism_idx[b_signif][i], ratio_ism_idx_prev_sf[b_signif][i] );
    3020         720 :                         move16();
    3021             : 
    3022         720 :                         test();
    3023         720 :                         if ( ( shift_one != 0 ) && EQ_16( i, idx_sep_obj_local ) )
    3024             :                         {
    3025          77 :                             ratio_ism_idx[b_signif][i] = 0;
    3026          77 :                             move16();
    3027             :                         }
    3028         720 :                         ratio_ism_idx[b_signif][nchan_ism - 1] = sub( ratio_ism_idx[b_signif][nchan_ism - 1], ratio_ism_idx[b_signif][i] );
    3029         720 :                         move16();
    3030             :                     }
    3031             : 
    3032             :                     /* rest of subbands differential to previous subband */
    3033         302 :                     Copy( ratio_ism_idx[b_signif], ratio_ism_idx_ref, nchan_ism );
    3034        1506 :                     FOR( b = b_signif + 1; b < numCodingBands; b++ )
    3035             :                     {
    3036        1204 :                         IF( LT_32( masa_to_total_energy_ratio_fx[b], MASA2TOTAL_THR_Q30 ) )
    3037             :                         {
    3038        1025 :                             ratio_ism_idx[b][nchan_ism - 1] = no_levels_ratio_ism;
    3039        1025 :                             move16();
    3040             : 
    3041        3481 :                             FOR( i = 0; i < nchan_ism - 1; i++ )
    3042             :                             {
    3043        2456 :                                 ratio_ism_idx[b][i] = add( ratio_ism_idx[b][i], ratio_ism_idx_ref[i] );
    3044        2456 :                                 move16();
    3045             : 
    3046        2456 :                                 test();
    3047        2456 :                                 if ( NE_16( shift_one, 0 ) && EQ_16( i, idx_sep_obj_local ) )
    3048             :                                 {
    3049         293 :                                     ratio_ism_idx[b][i] = 0;
    3050         293 :                                     move16();
    3051             :                                 }
    3052        2456 :                                 ratio_ism_idx[b][nchan_ism - 1] = sub( ratio_ism_idx[b][nchan_ism - 1], ratio_ism_idx[b][i] );
    3053        2456 :                                 move16();
    3054             :                             }
    3055        1025 :                             Copy( ratio_ism_idx[b], ratio_ism_idx_ref, nchan_ism );
    3056             :                         }
    3057             :                         ELSE
    3058             :                         {
    3059             :                             /* distribute evenly the objects */
    3060         179 :                             distribute_evenly_ism_fx( ratio_ism_idx[b], no_levels_ratio_ism, nchan_ism );
    3061             :                         }
    3062             :                     }
    3063             :                 }
    3064             :             }
    3065             :         }
    3066             : 
    3067        4705 :         return;
    3068             :     }
    3069             : }
    3070             : 
    3071             : 
    3072        1597 : static void decode_ism_ratios_fx(
    3073             :     UWord16 *bit_stream,                                                                     /* i  : bitstream                      */
    3074             :     Word16 *next_bit_pos,                                                                    /* i/o: position in bitstream          */
    3075             :     Word32 masa_to_total_energy_ratio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i  : masa_to_total energy ratios    Q30*/
    3076             :     Word32 ratio_ism[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS],    /* o  : ISM ratios                     Q30*/
    3077             :     const Word16 n_ism,                                                                      /* i  : number of objects              */
    3078             :     const Word16 nbands,                                                                     /* i  : number of subbands             */
    3079             :     const Word16 numSf,                                                                      /* i  : number of subframes            */
    3080             :     const Word16 idx_separated_object                                                        /* i  : index of separated object      */
    3081             : )
    3082             : {
    3083             :     Word16 sf, band;
    3084             :     Word16 ratio_ism_idx[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS];
    3085             :     Word16 ratio_ism_idx_prev_sf[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS];
    3086             :     Word32 tmp32_fx;
    3087             :     Word16 num_zeros;
    3088        1597 :     num_zeros = 0;
    3089        1597 :     move16();
    3090             : 
    3091             :     /* hQMetaData->q_direction->cfg.nblocks; */
    3092        6374 :     FOR( sf = 0; sf < numSf; sf++ )
    3093             :     {
    3094             :         /* read ism ratio indexes */
    3095        4777 :         read_ism_ratio_index_fx( ratio_ism_idx, n_ism, nbands, sf, ratio_ism_idx_prev_sf, bit_stream, next_bit_pos, masa_to_total_energy_ratio_fx[sf], idx_separated_object, &num_zeros );
    3096             :         /* save previous subframe index values */
    3097        4777 :         IF( LT_16( sf, sub( numSf, 1 ) ) )
    3098             :         {
    3099       18840 :             FOR( band = 0; band < nbands; band++ )
    3100             :             {
    3101       15660 :                 Copy( ratio_ism_idx[band], ratio_ism_idx_prev_sf[band], n_ism );
    3102             :             }
    3103             :         }
    3104             : 
    3105             :         /* reconstructed values */
    3106       30883 :         FOR( band = 0; band < nbands; band++ )
    3107             :         {
    3108       26106 :             reconstruct_ism_ratios_fx( ratio_ism_idx[band], n_ism, STEP_PARAM_ISM_POW_RATIO_NBITS_Q15, ratio_ism[sf][band] );
    3109             :         }
    3110             : 
    3111        4777 :         test();
    3112        4777 :         IF( GT_16( n_ism, 2 ) && ( EQ_16( idx_separated_object, sub( n_ism, 1 ) ) ) )
    3113             :         {
    3114             :             /* rotate */
    3115        4610 :             FOR( band = 0; band < nbands; band++ )
    3116             :             {
    3117        3844 :                 IF( LT_32( masa_to_total_energy_ratio_fx[sf][band], MASA2TOTAL_THR_Q30 ) )
    3118             :                 {
    3119        3352 :                     tmp32_fx = ratio_ism[sf][band][n_ism - 1]; // Q30
    3120        3352 :                     move32();
    3121        3352 :                     ratio_ism[sf][band][n_ism - 1] = ratio_ism[sf][band][0];
    3122        3352 :                     move32();
    3123        3352 :                     ratio_ism[sf][band][0] = tmp32_fx;
    3124        3352 :                     move32();
    3125             :                 }
    3126             :             }
    3127             :         }
    3128             : 
    3129        4777 :         IF( EQ_16( nbands, 1 ) )
    3130             :         {
    3131         400 :             FOR( band = 1; band < 5; band++ )
    3132             :             {
    3133         320 :                 Copy32( ratio_ism[sf][0], ratio_ism[sf][band], n_ism );
    3134             :             }
    3135             :         }
    3136             :     }
    3137             : 
    3138        1597 :     IF( EQ_16( numSf, 1 ) )
    3139             :     {
    3140        2148 :         FOR( sf = 1; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
    3141             :         {
    3142       17289 :             FOR( band = 0; band < nbands; band++ )
    3143             :             {
    3144       15678 :                 Copy32( ratio_ism[0][band], ratio_ism[sf][band], n_ism );
    3145             :             }
    3146             :         }
    3147             :     }
    3148             : 
    3149        1597 :     return;
    3150             : }
    3151             : 
    3152             : 
    3153        1597 : static Word16 ivas_decode_masaism_metadata_fx(
    3154             :     IVAS_QMETADATA_HANDLE hQMetaData,
    3155             :     MASA_DECODER_HANDLE hMasa,
    3156             :     MASA_ISM_DATA_HANDLE hMasaIsmData,
    3157             :     const Word16 nchan_ism,
    3158             :     UWord16 *bit_stream,
    3159             :     Word16 *next_bit_pos,
    3160             :     const Word16 idx_separated_object,
    3161             :     const Word16 ism_imp,
    3162             :     const Word16 dirac_bs_md_write_idx,
    3163             :     const Word16 dirac_md_buffer_length )
    3164             : {
    3165             :     Word16 sf, band, dir, nbands, nblocks, obj, i;
    3166             :     Word32 energy_ratio_ism_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS]; // Q30
    3167             :     Word16 *band_mapping;
    3168             :     Word16 b;
    3169             :     Word16 bits_ism[MAX_NUM_OBJECTS], index;
    3170             :     UWord16 idx_el, idx_az;
    3171             :     Word32 azimuth, elevation; // Q22
    3172             :     Word16 nb_bits_read;
    3173             :     Word32 delta_phi; // Q22
    3174             :     Word16 meta_write_index;
    3175             : 
    3176        1597 :     nb_bits_read = *next_bit_pos;
    3177        1597 :     move16();
    3178        1597 :     nbands = hQMetaData->q_direction->cfg.nbands;
    3179        1597 :     move16();
    3180        1597 :     nblocks = hQMetaData->q_direction->cfg.nblocks;
    3181        1597 :     move16();
    3182             : 
    3183             :     /* Read MASA-to-total energy ratios */
    3184        1597 :     ivas_omasa_decode_masa_to_total_fx( bit_stream, next_bit_pos, hMasaIsmData->masa_to_total_energy_ratio_fx, nbands, nblocks );
    3185             : 
    3186        1597 :     IF( GT_16( nchan_ism, 1 ) )
    3187             :     {
    3188             :         /* read ISM ratios */
    3189        1597 :         decode_ism_ratios_fx( bit_stream, next_bit_pos, hMasaIsmData->masa_to_total_energy_ratio_fx, energy_ratio_ism_fx, nchan_ism, nbands, nblocks, idx_separated_object );
    3190             :     }
    3191             :     ELSE
    3192             :     {
    3193           0 :         FOR( sf = 0; sf < nblocks; sf++ )
    3194             :         {
    3195           0 :             FOR( band = 0; band < nbands; band++ )
    3196             :             {
    3197           0 :                 energy_ratio_ism_fx[sf][band][0] = ONE_IN_Q30;
    3198           0 :                 move32();
    3199             :             }
    3200             :         }
    3201             :     }
    3202             : 
    3203             :     /* read ISM metadata */
    3204        1597 :     calculate_nbits_meta_fx( nchan_ism, energy_ratio_ism_fx, hMasaIsmData->masa_to_total_energy_ratio_fx, nblocks, nbands, bits_ism, idx_separated_object, ism_imp );
    3205             : 
    3206        6943 :     FOR( obj = 0; obj < nchan_ism; obj++ )
    3207             :     {
    3208        5346 :         index = 0;
    3209        5346 :         move16();
    3210        5346 :         IF( LT_16( bits_ism[obj], 8 ) ) /* if low resolution, can look to the past */
    3211             :         {
    3212             :             /* read if same as previous */
    3213        1606 :             IF( bit_stream[( *next_bit_pos )--] )
    3214             :             {
    3215         171 :                 azimuth = hMasaIsmData->q_azimuth_old_fx[obj]; // Q22
    3216         171 :                 move32();
    3217         171 :                 elevation = hMasaIsmData->q_elevation_old_fx[obj]; // Q22
    3218         171 :                 move32();
    3219             :             }
    3220             :             ELSE
    3221             :             {
    3222       10571 :                 FOR( i = 0; i < bits_ism[obj]; i++ )
    3223             :                 {
    3224        9136 :                     index = add( shl( index, 1 ), (Word16) bit_stream[( *next_bit_pos )--] );
    3225             :                 }
    3226             : 
    3227        1435 :                 deindex_spherical_component_fx( index, &azimuth, &elevation, &idx_az, &idx_el, bits_ism[obj], MC_LS_SETUP_INVALID );
    3228             : 
    3229        1435 :                 test();
    3230        1435 :                 test();
    3231        1435 :                 test();
    3232             :                 /*  if ( azimuth * hMasaIsmData->q_azimuth_old[obj] > 0 ) */
    3233        1435 :                 IF( ( ( azimuth > 0 ) && ( hMasaIsmData->q_azimuth_old_fx[obj] > 0 ) ) || ( ( azimuth < 0 ) && ( hMasaIsmData->q_azimuth_old_fx[obj] < 0 ) ) )
    3234             :                 {
    3235             :                     Word16 tmp_e;
    3236         637 :                     delta_phi = L_deposit_h( BASOP_Util_Divide1616_Scale( 180, no_phi_masa[bits_ism[obj] - 1][idx_el], &tmp_e ) );
    3237         637 :                     delta_phi = L_shr( delta_phi, sub( 9, tmp_e ) ); /* to maintain Q22 */
    3238             : 
    3239             :                     Word32 tmp_32;
    3240             :                     Word64 tmp_64;
    3241         637 :                     tmp_32 = L_sub( azimuth, hMasaIsmData->q_azimuth_old_fx[obj] );
    3242         637 :                     tmp_64 = W_mult_32_16( tmp_32, no_phi_masa[bits_ism[obj] - 1][idx_el] );
    3243             : 
    3244         637 :                     IF( GT_64( tmp_64, TOLERANCE_360_Q22 ) ) /* >= 360 in Q22 (because there is an additional shift left in W_mult_32_16) + 0.02 in Q22 to counteract for precision loss, */
    3245             :                     {
    3246          62 :                         azimuth = L_sub( azimuth, delta_phi );
    3247             :                     }
    3248             :                     ELSE
    3249             :                     {
    3250         575 :                         IF( GT_64( MINUS_TOLERANCE_360_Q22, tmp_64 ) )
    3251             :                         {
    3252          59 :                             azimuth = L_add( azimuth, delta_phi );
    3253             :                         }
    3254             :                     }
    3255             :                 }
    3256             : 
    3257        1435 :                 hMasaIsmData->q_azimuth_old_fx[obj] = azimuth;
    3258        1435 :                 move32();
    3259        1435 :                 hMasaIsmData->q_elevation_old_fx[obj] = elevation;
    3260        1435 :                 move32();
    3261             :             }
    3262             :         }
    3263             :         ELSE
    3264             :         {
    3265       41098 :             FOR( i = 0; i < bits_ism[obj]; i++ )
    3266             :             {
    3267       37358 :                 index = add( shl( index, 1 ), (Word16) bit_stream[( *next_bit_pos )--] );
    3268             :             }
    3269        3740 :             deindex_spherical_component_fx( index, &azimuth, &elevation, &idx_az, &idx_el, bits_ism[obj], MC_LS_SETUP_INVALID );
    3270             : 
    3271        3740 :             hMasaIsmData->q_azimuth_old_fx[obj] = azimuth;
    3272        3740 :             move32();
    3273        3740 :             hMasaIsmData->q_elevation_old_fx[obj] = elevation;
    3274        3740 :             move32();
    3275             :         }
    3276             : 
    3277       26730 :         FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
    3278             :         {
    3279       21384 :             meta_write_index = add( dirac_bs_md_write_idx, sf ) % dirac_md_buffer_length;
    3280             : 
    3281       21384 :             Word16 int_azi = rint_fx( L_shr( azimuth, Q22 - 16 ) );   // Q0, extra -16 is added as int_azi is W16 and azimuth is W32
    3282       21384 :             Word16 int_ele = rint_fx( L_shr( elevation, Q22 - 16 ) ); // Q0
    3283             : 
    3284       21384 :             hMasaIsmData->azimuth_ism[obj][meta_write_index] = int_azi; // Q0
    3285       21384 :             move16();
    3286       21384 :             hMasaIsmData->elevation_ism[obj][meta_write_index] = int_ele; // Q0
    3287       21384 :             move16();
    3288             :         }
    3289             :     }
    3290             : 
    3291             :     /* Modify ISM metadata based on the MASA-to-total energy ratios */
    3292        6374 :     FOR( sf = 0; sf < nblocks; sf++ )
    3293             :     {
    3294       30883 :         FOR( band = 0; band < nbands; band++ )
    3295             :         {
    3296      116678 :             FOR( dir = 0; dir < nchan_ism; dir++ )
    3297             :             {
    3298       90572 :                 energy_ratio_ism_fx[sf][band][dir] = L_shl( Mpy_32_32( energy_ratio_ism_fx[sf][band][dir], L_sub( ONE_IN_Q30, hMasaIsmData->masa_to_total_energy_ratio_fx[sf][band] ) ), 1 ); // Q30 + Q30 - 31 = Q29 + 1 = Q30
    3299       90572 :                 move32();
    3300             :             }
    3301             :         }
    3302             :     }
    3303             : 
    3304             :     /* Set data to struct in bins */
    3305        1597 :     band_mapping = hMasa->data.band_mapping;
    3306        1597 :     move16();
    3307       12123 :     FOR( band = 0; band < hMasa->config.numCodingBands; ++band )
    3308             :     {
    3309       93146 :         FOR( b = MASA_band_grouping_24[band_mapping[band]]; b < MASA_band_grouping_24[band_mapping[band + 1]]; ++b )
    3310             :         {
    3311      413100 :             FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; ++sf )
    3312             :             {
    3313      330480 :                 IF( EQ_16( nblocks, 1 ) )
    3314             :                 {
    3315      123360 :                     i = 0;
    3316      123360 :                     move16();
    3317             :                 }
    3318             :                 ELSE
    3319             :                 {
    3320      207120 :                     i = sf;
    3321      207120 :                     move16();
    3322             :                 }
    3323             : 
    3324      330480 :                 meta_write_index = ( add( dirac_bs_md_write_idx, sf ) ) % dirac_md_buffer_length;
    3325             : 
    3326     1449360 :                 FOR( dir = 0; dir < nchan_ism; dir++ )
    3327             :                 {
    3328     1118880 :                     hMasaIsmData->energy_ratio_ism_fx[dir][meta_write_index][b] = energy_ratio_ism_fx[i][band][dir];
    3329     1118880 :                     move32();
    3330             :                 }
    3331             :             }
    3332             :         }
    3333             :     }
    3334             : 
    3335        1597 :     return sub( nb_bits_read, *next_bit_pos );
    3336             : }
    3337             : 
    3338             : /*
    3339             :     Fixed point implementation of rint().
    3340             : */
    3341       42768 : static Word16 rint_fx(            /* returns in Q0 */
    3342             :                        Word32 num /* num in Q0     */
    3343             : )
    3344             : {
    3345       42768 :     Word32 frac_part = L_and( L_abs( num ), 0x0000FFFF ); // Q15
    3346       42768 :     Word16 int_part = extract_h( L_abs( num ) );
    3347       42768 :     Word16 res = int_part;
    3348       42768 :     move16();
    3349             : 
    3350       42768 :     test();
    3351       42768 :     test();
    3352       42768 :     if ( GT_32( frac_part, ONE_IN_Q15 ) || ( EQ_32( frac_part, ONE_IN_Q15 ) && EQ_16( s_and( int_part, 1 ), 1 ) ) )
    3353             :     {
    3354        9884 :         res = add( res, 1 );
    3355             :     }
    3356       42768 :     if ( num < 0 )
    3357             :     {
    3358       18932 :         res = negate( res );
    3359             :     }
    3360       42768 :     return res;
    3361             : }

Generated by: LCOV version 1.14