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

Generated by: LCOV version 1.14