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

Generated by: LCOV version 1.14