LCOV - code coverage report
Current view: top level - lib_dec - ivas_masa_dec_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ e95243e9e67ddeb69dddf129509de1b3d95b402e Lines: 1593 1685 94.5 %
Date: 2025-09-16 02:47:18 Functions: 19 19 100.0 %

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

Generated by: LCOV version 1.14