LCOV - code coverage report
Current view: top level - lib_dec - ivas_spar_md_dec_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 574a190e3c6896c6c4ed10d7f23649709a0c4347 Lines: 1356 1460 92.9 %
Date: 2025-06-27 02:59:36 Functions: 30 30 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 "options.h"
      35             : #include "math.h"
      36             : #include "prot_fx.h"
      37             : #include "ivas_rom_com.h"
      38             : #include <assert.h>
      39             : #include "wmc_auto.h"
      40             : #include "ivas_stat_dec.h"
      41             : #include "ivas_prot_fx.h"
      42             : #include "ivas_rom_com_fx.h"
      43             : 
      44             : /*------------------------------------------------------------------------------------------*
      45             :  * Local constants
      46             :  *------------------------------------------------------------------------------------------*/
      47             : 
      48             : #define IVAS_DEFAULT_DTX_CNG_RAMP ( 8 )
      49             : 
      50             : /* PLC constants */
      51             : static const Word16 ivas_spar_dec_plc_num_frames_keep = 9;
      52             : // static const Word16 ivas_spar_dec_plc_num_frames_fade_out = 9;
      53             : static const Word16 ivas_spar_dec_plc_per_frame_ramp_down_gain_dB = 3;
      54             : static const Word16 ivas_spar_dec_plc_max_num_frames_ramp_down = 33;
      55             : static const Word16 ivas_spar_dec_plc_spatial_target[IVAS_SPAR_MAX_CH] = { 1, 0, 0, 0, 0, 0, 0, 0 };
      56             : 
      57             : 
      58             : /*------------------------------------------------------------------------------------------*
      59             :  * Static functions declaration
      60             :  *------------------------------------------------------------------------------------------*/
      61             : 
      62             : static void ivas_get_spar_matrices_fx( ivas_spar_md_dec_state_t *hMdDec, const Word16 num_bands_out, const Word16 n_ts, const Word16 bw, const Word16 dtx_vad, const Word16 nB, const Word16 numch_out, const Word16 active_w_vlbr, const Word16 dyn_active_w_flag );
      63             : static void ivas_decode_arith_bs( ivas_spar_md_dec_state_t *hMdDec, Decoder_State *st, const UWord16 qsi, const Word16 nB, const Word16 bands_bw, Word16 *pDo_diff, const Word16 strat, const Word32 ivas_total_brate );
      64             : 
      65             : static void ivas_decode_huffman_bs( ivas_spar_md_dec_state_t *hMdDec, Decoder_State *st, const UWord16 qsi, const Word16 nB, const Word16 bands_bw );
      66             : 
      67             : static void ivas_fill_band_coeffs_idx( ivas_band_coeffs_ind_t *pBands_idx, const Word16 nB, Word16 *pSymbol_re, ivas_cell_dim_t *pCell_dims, ivas_coeffs_type_t coeff_type );
      68             : 
      69             : static void ivas_mat_col_rearrange_fx( Word32 in_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], const Word16 order[IVAS_SPAR_MAX_CH], const Word16 i_ts, Word32 ***mixer_mat, const Word16 bands, const Word16 num_ch );
      70             : 
      71             : static void ivas_spar_dec_compute_ramp_down_post_matrix_fx( ivas_spar_md_dec_state_t *hMdDec, const Word16 num_bands, const Word16 bfi, const Word16 num_md_sub_frames );
      72             : 
      73             : static void ivas_spar_md_fill_invalid_bands_fx( ivas_spar_dec_matrices_t *pSpar_coeffs, ivas_spar_dec_matrices_t *pSpar_coeffs_prev, const Word16 *valid_bands, Word16 *base_band_age, const Word16 num_bands, const Word16 num_channels, const Word16 num_md_sub_frames );
      74             : 
      75             : static void ivas_spar_md_fill_invalid_bandcoeffs( ivas_band_coeffs_t *pBand_coeffs, ivas_band_coeffs_t *pBand_coeffs_prev, const Word16 *valid_bands, Word16 *base_band_age, Word16 *first_valid_frame, const Word16 num_bands );
      76             : 
      77             : static ivas_error ivas_spar_set_dec_config( ivas_spar_md_dec_state_t *hMdDec, const Word16 nchan_transport, Word32 *pFC );
      78             : 
      79             : static void ivas_parse_parameter_bitstream_dtx( ivas_spar_md_t *pSpar_md, Decoder_State *st, const Word16 bw, const Word16 num_bands, Word16 *num_dmx_per_band, Word16 *num_dec_per_band );
      80             : 
      81             : static ivas_error ivas_deindex_real_index_fx( const Word16 *index, const Word16 q_levels, const Word32 min_value, const Word32 max_value, Word32 *quant, const Word16 num_ch_dim2 );
      82             : 
      83             : static void ivas_spar_dec_parse_md_bs_fx( ivas_spar_md_dec_state_t *hMdDec, Decoder_State *st, Word16 *nB, Word16 *bands_bw, Word16 *dtx_vad, const Word32 ivas_total_brate, const Word16 sba_inactive_mode );
      84             : 
      85             : 
      86        1514 : ivas_error ivas_spar_md_dec_matrix_open_fx(
      87             :     ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle       */
      88             :     const Word16 num_channels,        /* i  : number of internal channels  Q0*/
      89             :     const Word16 num_md_sub_frames    /* i  : number of MD subframes       Q0*/
      90             : )
      91             : {
      92             :     Word16 i, j;
      93             :     Word16 k;
      94        1514 :     IF( ( hMdDec->spar_md.band_coeffs = (ivas_band_coeffs_t *) malloc( i_mult( i_mult( IVAS_MAX_NUM_BANDS, num_md_sub_frames ), sizeof( ivas_band_coeffs_t ) ) ) ) == NULL )
      95             :     {
      96           0 :         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for band_coeffs in SPAR MD" );
      97             :     }
      98        1514 :     IF( ( hMdDec->band_coeffs_prev = (ivas_band_coeffs_t *) malloc( IVAS_MAX_NUM_BANDS * sizeof( ivas_band_coeffs_t ) ) ) == NULL )
      99             :     {
     100           0 :         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for band_coeffs in SPAR MD" );
     101             :     }
     102        1514 :     IF( ( hMdDec->mixer_mat_fx = (Word32 ***) malloc( i_mult( num_channels, sizeof( Word32 ** ) ) ) ) == NULL )
     103             :     {
     104           0 :         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" );
     105             :     }
     106        8684 :     FOR( i = 0; i < num_channels; i++ )
     107             :     {
     108        7170 :         IF( ( hMdDec->mixer_mat_fx[i] = (Word32 **) malloc( i_mult( num_channels, sizeof( Word32 * ) ) ) ) == NULL )
     109             :         {
     110           0 :             return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" );
     111             :         }
     112       46186 :         FOR( j = 0; j < num_channels; j++ )
     113             :         {
     114       39016 :             IF( ( hMdDec->mixer_mat_fx[i][j] = (Word32 *) malloc( i_mult( i_mult( num_md_sub_frames, IVAS_MAX_NUM_BANDS ), sizeof( Word32 ) ) ) ) == NULL )
     115             :             {
     116           0 :                 return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" );
     117             :             }
     118             :         }
     119             :     }
     120             : 
     121        1514 :     IF( ( hMdDec->spar_coeffs.C_re_fx = (Word32 ***) malloc( i_mult( num_channels, sizeof( Word32 ** ) ) ) ) == NULL )
     122             :     {
     123           0 :         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" );
     124             :     }
     125        8684 :     FOR( i = 0; i < num_channels; i++ )
     126             :     {
     127        7170 :         IF( ( hMdDec->spar_coeffs.C_re_fx[i] = (Word32 **) malloc( i_mult( num_channels, sizeof( Word32 * ) ) ) ) == NULL )
     128             :         {
     129           0 :             return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" );
     130             :         }
     131       46186 :         FOR( j = 0; j < num_channels; j++ )
     132             :         {
     133       39016 :             IF( ( hMdDec->spar_coeffs.C_re_fx[i][j] = (Word32 *) malloc( i_mult( i_mult( num_md_sub_frames, IVAS_MAX_NUM_BANDS ), sizeof( Word32 ) ) ) ) == NULL )
     134             :             {
     135           0 :                 return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" );
     136             :             }
     137             :         }
     138             :     }
     139             : 
     140        1514 :     IF( ( hMdDec->spar_coeffs.P_re_fx = (Word32 ***) malloc( i_mult( num_channels, sizeof( Word32 ** ) ) ) ) == NULL )
     141             :     {
     142           0 :         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" );
     143             :     }
     144        8684 :     FOR( i = 0; i < num_channels; i++ )
     145             :     {
     146        7170 :         IF( ( hMdDec->spar_coeffs.P_re_fx[i] = (Word32 **) malloc( i_mult( num_channels, sizeof( Word32 * ) ) ) ) == NULL )
     147             :         {
     148           0 :             return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" );
     149             :         }
     150       46186 :         FOR( j = 0; j < num_channels; j++ )
     151             :         {
     152       39016 :             IF( ( hMdDec->spar_coeffs.P_re_fx[i][j] = (Word32 *) malloc( i_mult( num_md_sub_frames, IVAS_MAX_NUM_BANDS * sizeof( Word32 ) ) ) ) == NULL )
     153             :             {
     154           0 :                 return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" );
     155             :             }
     156             :         }
     157             :     }
     158             : 
     159        1514 :     IF( ( hMdDec->spar_coeffs_prev.C_re_fx = (Word32 ***) malloc( i_mult( num_channels, sizeof( Word32 ** ) ) ) ) == NULL )
     160             :     {
     161           0 :         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" );
     162             :     }
     163        8684 :     FOR( i = 0; i < num_channels; i++ )
     164             :     {
     165        7170 :         IF( ( hMdDec->spar_coeffs_prev.C_re_fx[i] = (Word32 **) malloc( i_mult( num_channels, sizeof( Word32 * ) ) ) ) == NULL )
     166             :         {
     167           0 :             return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" );
     168             :         }
     169       46186 :         FOR( j = 0; j < num_channels; j++ )
     170             :         {
     171       39016 :             IF( ( hMdDec->spar_coeffs_prev.C_re_fx[i][j] = (Word32 *) malloc( IVAS_MAX_NUM_BANDS * sizeof( Word32 ) ) ) == NULL )
     172             :             {
     173           0 :                 return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" );
     174             :             }
     175             :         }
     176             :     }
     177             : 
     178        1514 :     IF( ( hMdDec->spar_coeffs_prev.P_re_fx = (Word32 ***) malloc( i_mult( num_channels, sizeof( Word32 ** ) ) ) ) == NULL )
     179             :     {
     180           0 :         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" );
     181             :     }
     182        8684 :     FOR( i = 0; i < num_channels; i++ )
     183             :     {
     184        7170 :         IF( ( hMdDec->spar_coeffs_prev.P_re_fx[i] = (Word32 **) malloc( i_mult( num_channels, sizeof( Word32 * ) ) ) ) == NULL )
     185             :         {
     186           0 :             return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" );
     187             :         }
     188       46186 :         FOR( j = 0; j < num_channels; j++ )
     189             :         {
     190       39016 :             IF( ( hMdDec->spar_coeffs_prev.P_re_fx[i][j] = (Word32 *) malloc( IVAS_MAX_NUM_BANDS * sizeof( Word32 ) ) ) == NULL )
     191             :             {
     192           0 :                 return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" );
     193             :             }
     194             :         }
     195             :     }
     196        1514 :     IF( ( hMdDec->spar_coeffs_tar.C_re_fx = (Word32 ***) malloc( i_mult( num_channels, sizeof( Word32 ** ) ) ) ) == NULL )
     197             :     {
     198           0 :         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" );
     199             :     }
     200        8684 :     FOR( i = 0; i < num_channels; i++ )
     201             :     {
     202        7170 :         IF( ( hMdDec->spar_coeffs_tar.C_re_fx[i] = (Word32 **) malloc( i_mult( num_channels, sizeof( Word32 * ) ) ) ) == NULL )
     203             :         {
     204           0 :             return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" );
     205             :         }
     206       46186 :         FOR( j = 0; j < num_channels; j++ )
     207             :         {
     208       39016 :             IF( ( hMdDec->spar_coeffs_tar.C_re_fx[i][j] = (Word32 *) malloc( IVAS_MAX_NUM_BANDS * sizeof( Word32 ) ) ) == NULL )
     209             :             {
     210           0 :                 return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" );
     211             :             }
     212             :         }
     213             :     }
     214        1514 :     IF( ( hMdDec->spar_coeffs_tar.P_re_fx = (Word32 ***) malloc( i_mult( num_channels, sizeof( Word32 ** ) ) ) ) == NULL )
     215             :     {
     216           0 :         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" );
     217             :     }
     218        8684 :     FOR( i = 0; i < num_channels; i++ )
     219             :     {
     220        7170 :         IF( ( hMdDec->spar_coeffs_tar.P_re_fx[i] = (Word32 **) malloc( i_mult( num_channels, sizeof( Word32 * ) ) ) ) == NULL )
     221             :         {
     222           0 :             return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" );
     223             :         }
     224       46186 :         FOR( j = 0; j < num_channels; j++ )
     225             :         {
     226       39016 :             IF( ( hMdDec->spar_coeffs_tar.P_re_fx[i][j] = (Word32 *) malloc( IVAS_MAX_NUM_BANDS * sizeof( Word32 ) ) ) == NULL )
     227             :             {
     228           0 :                 return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" );
     229             :             }
     230             :         }
     231             :     }
     232             : 
     233        8684 :     FOR( i = 0; i < num_channels; i++ )
     234             :     {
     235       46186 :         FOR( j = 0; j < num_channels; j++ )
     236             :         {
     237      507208 :             FOR( k = 0; k < IVAS_MAX_NUM_BANDS; k++ )
     238             :             {
     239      468192 :                 hMdDec->spar_coeffs_prev.C_re_fx[i][j][k] = 0;
     240      468192 :                 move32();
     241      468192 :                 hMdDec->spar_coeffs_prev.P_re_fx[i][j][k] = 0;
     242      468192 :                 move32();
     243      468192 :                 hMdDec->spar_coeffs_tar.C_re_fx[i][j][k] = 0;
     244      468192 :                 move32();
     245      468192 :                 hMdDec->spar_coeffs_tar.P_re_fx[i][j][k] = 0;
     246      468192 :                 move32();
     247             :             }
     248             :         }
     249             :     }
     250             : 
     251        1514 :     return IVAS_ERR_OK;
     252             : }
     253             : 
     254             : /*-------------------------------------------------------------------------
     255             :  * ivas_get_spar_dec_md_num_subframes()
     256             :  *
     257             :  * return number of MD subframes
     258             :  *------------------------------------------------------------------------*/
     259             : 
     260             : /*! r: number of MD subframes */
     261     1457997 : Word16 ivas_get_spar_dec_md_num_subframes(
     262             :     const Word16 sba_order,             /* i  : Ambisonic (SBA) order        Q0*/
     263             :     const Word32 ivas_total_brate,      /* i  : IVAS total bitrate           Q0*/
     264             :     const Word32 ivas_last_active_brate /* i  : IVAS last active bitrate     Q0*/
     265             : )
     266             : {
     267             :     Word16 num_subframes;
     268             : 
     269     1457997 :     num_subframes = MAX_PARAM_SPATIAL_SUBFRAMES;
     270     1457997 :     move16();
     271     1457997 :     IF( GT_16( sba_order, SBA_FOA_ORDER ) )
     272             :     {
     273      326688 :         if ( GE_32( ivas_total_brate, IVAS_512k ) )
     274             :         {
     275       68402 :             num_subframes = 1;
     276       68402 :             move16();
     277             :         }
     278             :     }
     279             : 
     280     1457997 :     test();
     281     1457997 :     test();
     282     1457997 :     test();
     283     1457997 :     if ( ( LE_32( ivas_total_brate, IVAS_SID_5k2 ) && LT_32( ivas_last_active_brate, IVAS_24k4 ) ) || ( GT_32( ivas_total_brate, IVAS_SID_5k2 ) && LT_32( ivas_total_brate, IVAS_24k4 ) ) )
     284             :     {
     285      119954 :         num_subframes = 1;
     286      119954 :         move16();
     287             :     }
     288             : 
     289     1457997 :     return ( num_subframes ); /*Q0*/
     290             : }
     291             : 
     292             : 
     293             : /*-------------------------------------------------------------------------
     294             :  * ivas_spar_md_dec_open()
     295             :  *
     296             :  * Allocate and initialize SPAR MD decoder handle
     297             :  *------------------------------------------------------------------------*/
     298             : 
     299        1476 : ivas_error ivas_spar_md_dec_open(
     300             :     ivas_spar_md_dec_state_t **hMdDec_out,      /* i/o: SPAR MD decoder handle      */
     301             :     const DECODER_CONFIG_HANDLE hDecoderConfig, /* i  : configuration structure     */
     302             :     const Word16 num_channels,                  /* i  : number of internal channels Q0*/
     303             :     const Word16 sba_order,                     /* i  : SBA order                   Q0*/
     304             :     const Word16 sid_format,                    /* i  : SID format                  Q0*/
     305             :     const Word32 last_active_ivas_total_brate   /* i  : IVAS last active bitrate    Q0*/
     306             : )
     307             : {
     308             :     ivas_spar_md_dec_state_t *hMdDec;
     309             :     ivas_error error;
     310             :     Word16 num_md_sub_frames;
     311             : 
     312        1476 :     error = IVAS_ERR_OK;
     313        1476 :     move32();
     314             : 
     315        1476 :     IF( ( hMdDec = (ivas_spar_md_dec_state_t *) malloc( sizeof( ivas_spar_md_dec_state_t ) ) ) == NULL )
     316             :     {
     317           0 :         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD decoder" );
     318             :     }
     319             : 
     320        1476 :     num_md_sub_frames = ivas_get_spar_dec_md_num_subframes( sba_order, hDecoderConfig->ivas_total_brate, last_active_ivas_total_brate ); /*Q0*/
     321             : 
     322        1476 :     IF( NE_32( ( error = ivas_spar_md_dec_matrix_open_fx( hMdDec, num_channels, num_md_sub_frames ) ), IVAS_ERR_OK ) )
     323             :     {
     324           0 :         return error;
     325             :     }
     326             : 
     327        1476 :     IF( EQ_32( hDecoderConfig->ivas_total_brate, IVAS_SID_5k2 ) )
     328             :     {
     329           0 :         IF( EQ_16( sid_format, SID_SBA_2TC ) )
     330             :         {
     331           0 :             hMdDec->table_idx = ivas_get_spar_table_idx_fx( IVAS_48k, sba_order, SPAR_CONFIG_BW, NULL, NULL ); /*Q0*/
     332           0 :             move16();
     333             :         }
     334             :         ELSE
     335             :         {
     336           0 :             hMdDec->table_idx = ivas_get_spar_table_idx_fx( IVAS_24k4, sba_order, SPAR_CONFIG_BW, NULL, NULL );
     337           0 :             move16();
     338             :         }
     339             :     }
     340             :     ELSE
     341             :     {
     342        1476 :         hMdDec->table_idx = ivas_get_spar_table_idx_fx( hDecoderConfig->ivas_total_brate, sba_order, SPAR_CONFIG_BW, NULL, NULL );
     343        1476 :         move16();
     344             :     }
     345             : 
     346        1476 :     IF( NE_32( ( error = ivas_spar_md_dec_init( hMdDec, hDecoderConfig, num_channels, sba_order ) ), IVAS_ERR_OK ) )
     347             :     {
     348           0 :         return error;
     349             :     }
     350             : 
     351        1476 :     *hMdDec_out = hMdDec;
     352             : 
     353        1476 :     return error;
     354             : }
     355             : 
     356             : 
     357             : /*-------------------------------------------------------------------------
     358             :  * ivas_spar_md_dec_matrix_close()
     359             :  *
     360             :  * Deallocate SPAR MD decoder matrices
     361             :  *------------------------------------------------------------------------*/
     362             : 
     363        1514 : void ivas_spar_md_dec_matrix_close_fx(
     364             :     ivas_spar_md_dec_state_t *hMdDecoder, /* i/o: SPAR MD decoder handle      */
     365             :     const Word16 num_channels             /* i  : number of internal channels Q0*/
     366             : )
     367             : {
     368             :     Word16 i, j;
     369             : 
     370        1514 :     IF( hMdDecoder->spar_md.band_coeffs != NULL )
     371             :     {
     372        1514 :         free( hMdDecoder->spar_md.band_coeffs );
     373        1514 :         hMdDecoder->spar_md.band_coeffs = NULL;
     374             :     }
     375        1514 :     IF( hMdDecoder->band_coeffs_prev != NULL )
     376             :     {
     377        1514 :         free( hMdDecoder->band_coeffs_prev );
     378        1514 :         hMdDecoder->band_coeffs_prev = NULL;
     379             :     }
     380             : 
     381        1514 :     IF( hMdDecoder->mixer_mat_fx != NULL )
     382             :     {
     383        8684 :         FOR( i = 0; i < num_channels; i++ )
     384             :         {
     385       46186 :             FOR( j = 0; j < num_channels; j++ )
     386             :             {
     387       39016 :                 free( hMdDecoder->mixer_mat_fx[i][j] );
     388             :             }
     389        7170 :             free( hMdDecoder->mixer_mat_fx[i] );
     390             :         }
     391        1514 :         free( hMdDecoder->mixer_mat_fx );
     392             :     }
     393        1514 :     IF( hMdDecoder->spar_coeffs.C_re_fx != NULL )
     394             :     {
     395        8684 :         FOR( i = 0; i < num_channels; i++ )
     396             :         {
     397       46186 :             FOR( j = 0; j < num_channels; j++ )
     398             :             {
     399       39016 :                 free( hMdDecoder->spar_coeffs.C_re_fx[i][j] );
     400             :             }
     401        7170 :             free( hMdDecoder->spar_coeffs.C_re_fx[i] );
     402             :         }
     403        1514 :         free( hMdDecoder->spar_coeffs.C_re_fx );
     404             :     }
     405        1514 :     IF( hMdDecoder->spar_coeffs.P_re_fx != NULL )
     406             :     {
     407        8684 :         FOR( i = 0; i < num_channels; i++ )
     408             :         {
     409       46186 :             FOR( j = 0; j < num_channels; j++ )
     410             :             {
     411       39016 :                 free( hMdDecoder->spar_coeffs.P_re_fx[i][j] );
     412             :             }
     413        7170 :             free( hMdDecoder->spar_coeffs.P_re_fx[i] );
     414             :         }
     415        1514 :         free( hMdDecoder->spar_coeffs.P_re_fx );
     416             :     }
     417             : 
     418        1514 :     IF( hMdDecoder->spar_coeffs_prev.C_re_fx != NULL )
     419             :     {
     420        8684 :         FOR( i = 0; i < num_channels; i++ )
     421             :         {
     422       46186 :             FOR( j = 0; j < num_channels; j++ )
     423             :             {
     424       39016 :                 free( hMdDecoder->spar_coeffs_prev.C_re_fx[i][j] );
     425             :             }
     426        7170 :             free( hMdDecoder->spar_coeffs_prev.C_re_fx[i] );
     427             :         }
     428        1514 :         free( hMdDecoder->spar_coeffs_prev.C_re_fx );
     429             :     }
     430             : 
     431        1514 :     IF( hMdDecoder->spar_coeffs_prev.P_re_fx != NULL )
     432             :     {
     433        8684 :         FOR( i = 0; i < num_channels; i++ )
     434             :         {
     435       46186 :             FOR( j = 0; j < num_channels; j++ )
     436             :             {
     437       39016 :                 free( hMdDecoder->spar_coeffs_prev.P_re_fx[i][j] );
     438             :             }
     439        7170 :             free( hMdDecoder->spar_coeffs_prev.P_re_fx[i] );
     440             :         }
     441        1514 :         free( hMdDecoder->spar_coeffs_prev.P_re_fx );
     442             :     }
     443             : 
     444        1514 :     IF( hMdDecoder->spar_coeffs_tar.C_re_fx != NULL )
     445             :     {
     446        8684 :         FOR( i = 0; i < num_channels; i++ )
     447             :         {
     448       46186 :             FOR( j = 0; j < num_channels; j++ )
     449             :             {
     450       39016 :                 free( hMdDecoder->spar_coeffs_tar.C_re_fx[i][j] );
     451             :             }
     452        7170 :             free( hMdDecoder->spar_coeffs_tar.C_re_fx[i] );
     453             :         }
     454        1514 :         free( hMdDecoder->spar_coeffs_tar.C_re_fx );
     455             :     }
     456        1514 :     IF( hMdDecoder->spar_coeffs_tar.P_re_fx != NULL )
     457             :     {
     458        8684 :         FOR( i = 0; i < num_channels; i++ )
     459             :         {
     460       46186 :             FOR( j = 0; j < num_channels; j++ )
     461             :             {
     462       39016 :                 free( hMdDecoder->spar_coeffs_tar.P_re_fx[i][j] );
     463             :             }
     464        7170 :             free( hMdDecoder->spar_coeffs_tar.P_re_fx[i] );
     465             :         }
     466        1514 :         free( hMdDecoder->spar_coeffs_tar.P_re_fx );
     467             :     }
     468             : 
     469        1514 :     return;
     470             : }
     471             : 
     472             : /*-------------------------------------------------------------------------
     473             :  * ivas_spar_md_dec_close()
     474             :  *
     475             :  * Deallocate SPAR MD decoder handle
     476             :  *------------------------------------------------------------------------*/
     477             : 
     478        1476 : void ivas_spar_md_dec_close(
     479             :     ivas_spar_md_dec_state_t **hMdDec /* i/o: SPAR MD decoder handle     */
     480             : )
     481             : {
     482             :     ivas_spar_md_dec_state_t *hMdDecoder;
     483             :     Word16 num_channels;
     484             : 
     485        1476 :     hMdDecoder = *hMdDec;
     486        1476 :     num_channels = hMdDecoder->spar_md_cfg.num_umx_chs;
     487        1476 :     move16();
     488             : 
     489        1476 :     ivas_spar_md_dec_matrix_close_fx( hMdDecoder, num_channels );
     490             : 
     491        1476 :     free( *hMdDec );
     492        1476 :     *hMdDec = NULL;
     493             : 
     494        1476 :     return;
     495             : }
     496             : 
     497             : Word32 pFC_8k[IVAS_MAX_NUM_BANDS] = { 33, 100, 166, 233, 300, 366, 433, 566, 866, 1333, 2033, 3233 };            /*Q0*/
     498             : Word32 pFC_12k[IVAS_MAX_NUM_BANDS] = { 53, 160, 266, 373, 480, 586, 693, 906, 1386, 2133, 3253, 5173 };          /*Q0*/
     499             : Word32 pFC_16k[IVAS_MAX_NUM_BANDS] = { 66, 200, 333, 466, 600, 733, 866, 1133, 1733, 2666, 4066, 6466 };         /*Q0*/
     500             : Word32 pFC_32k[IVAS_MAX_NUM_BANDS] = { 133, 400, 666, 933, 1200, 1466, 1733, 2266, 3466, 5333, 8133, 12933 };    /*Q0*/
     501             : Word32 pFC_48k[IVAS_MAX_NUM_BANDS] = { 199, 600, 1000, 1400, 1800, 2200, 2600, 3400, 5200, 8000, 12200, 19400 }; /*Q0*/
     502             : 
     503             : /*-----------------------------------------------------------------------------------------*
     504             :  * Function ivas_spar_md_dec_init()
     505             :  *
     506             :  * SPAR MD decoder initialization
     507             :  *-----------------------------------------------------------------------------------------*/
     508        1764 : ivas_error ivas_spar_md_dec_init(
     509             :     ivas_spar_md_dec_state_t *hMdDec,           /* i/o: SPAR MD decoder handle       */
     510             :     const DECODER_CONFIG_HANDLE hDecoderConfig, /* i  : configuration structure      */
     511             :     const Word16 num_channels,                  /* i  : number of internal channels  Q0*/
     512             :     const Word16 sba_order                      /* i  : SBA order                    Q0*/
     513             : )
     514             : {
     515             :     Word16 i, j;
     516             :     Word16 nchan_transport;
     517        1764 :     Word32 *pFC_fx = NULL, PR_minmax_fx[2];
     518             :     ivas_error error;
     519             : 
     520        1764 :     ivas_sba_get_spar_hoa_md_flag_fx( sba_order, hDecoderConfig->ivas_total_brate, &hMdDec->spar_hoa_md_flag, &hMdDec->spar_hoa_dirac2spar_md_flag );
     521             : 
     522        1764 :     ivas_sba_get_spar_hoa_ch_ind_fx( num_channels, hDecoderConfig->ivas_total_brate, hMdDec->HOA_md_ind );
     523             : 
     524        1764 :     IF( hMdDec->spar_hoa_md_flag )
     525             :     {
     526         240 :         hMdDec->spar_md.num_bands = IVAS_MAX_NUM_BANDS;
     527         240 :         move16();
     528             :     }
     529             :     ELSE
     530             :     {
     531        1524 :         hMdDec->spar_md.num_bands = s_min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND );
     532        1524 :         move16();
     533             :     }
     534             : 
     535        1764 :     ivas_spar_set_bitrate_config_fx( &hMdDec->spar_md_cfg, hMdDec->table_idx, hMdDec->spar_md.num_bands, hMdDec->spar_hoa_dirac2spar_md_flag, 0, 0, 0 );
     536             : 
     537        1764 :     nchan_transport = hMdDec->spar_md_cfg.nchan_transport;
     538        1764 :     move16();
     539             : 
     540        1764 :     IF( EQ_32( hDecoderConfig->output_Fs, 8000 ) )
     541             :     {
     542           0 :         pFC_fx = pFC_8k; /*Q0*/
     543             :     }
     544        1764 :     ELSE IF( EQ_32( hDecoderConfig->output_Fs, 12800 ) )
     545             :     {
     546           0 :         pFC_fx = pFC_12k; /*Q0*/
     547             :     }
     548        1764 :     ELSE IF( EQ_32( hDecoderConfig->output_Fs, 16000 ) )
     549             :     {
     550          40 :         pFC_fx = pFC_16k; /*Q0*/
     551             :     }
     552        1724 :     ELSE IF( EQ_32( hDecoderConfig->output_Fs, 32000 ) )
     553             :     {
     554         530 :         pFC_fx = pFC_32k; /*Q0*/
     555             :     }
     556        1194 :     ELSE IF( EQ_32( hDecoderConfig->output_Fs, 48000 ) )
     557             :     {
     558        1194 :         pFC_fx = pFC_48k; /*Q0*/
     559             :     }
     560             :     ELSE
     561             :     {
     562           0 :         assert( 0 ); // update sample rate
     563             :     }
     564             : 
     565        1764 :     IF( NE_32( ( error = ivas_spar_set_dec_config( hMdDec, nchan_transport, pFC_fx ) ), IVAS_ERR_OK ) )
     566             :     {
     567           0 :         return error;
     568             :     }
     569             : 
     570        1764 :     test();
     571        1764 :     test();
     572        1764 :     IF( NE_16( nchan_transport, 2 ) && ( EQ_16( hMdDec->spar_md_cfg.remix_unmix_order, 2 ) || EQ_16( hMdDec->spar_md_cfg.remix_unmix_order, 1 ) ) )
     573             :     {
     574           0 :         return IVAS_ERR_INTERNAL;
     575             :     }
     576             : 
     577             :     /* DTX quant init */
     578        1764 :     PR_minmax_fx[0] = hMdDec->spar_md_cfg.quant_strat[0].PR.min_fx; /*Q28*/
     579        1764 :     move32();
     580        1764 :     PR_minmax_fx[1] = hMdDec->spar_md_cfg.quant_strat[0].PR.max_fx; /*Q28*/
     581        1764 :     move32();
     582        1764 :     ivas_spar_quant_dtx_init_fx( &hMdDec->spar_md, PR_minmax_fx );
     583             : 
     584        1764 :     ivas_spar_arith_coeffs_com_init_fx( &hMdDec->arith_coeffs, &hMdDec->spar_md_cfg, hMdDec->table_idx, DEC );
     585        1764 :     ivas_spar_huff_coeffs_com_init_fx( &hMdDec->huff_coeffs, &hMdDec->spar_md_cfg, hMdDec->table_idx, DEC );
     586             : 
     587        1764 :     hMdDec->spar_md_cfg.prev_quant_idx = -1;
     588        1764 :     move16();
     589             : 
     590             :     /* initialize PLC state */
     591        1764 :     set16_fx( hMdDec->valid_bands, 0, IVAS_MAX_NUM_BANDS );
     592        1764 :     set16_fx( hMdDec->base_band_age, 0, IVAS_MAX_NUM_BANDS );
     593        1764 :     set16_fx( hMdDec->base_band_coeffs_age, 0, IVAS_MAX_NUM_BANDS );
     594        1764 :     hMdDec->spar_plc_num_lost_frames = 0;
     595        1764 :     move16();
     596        1764 :     hMdDec->spar_plc_enable_fadeout_flag = 1;
     597        1764 :     move16();
     598        1764 :     hMdDec->dtx_md_smoothing_cntr = 1;
     599        1764 :     move16();
     600             : 
     601        1764 :     ivas_clear_band_coeffs_fx( hMdDec->spar_md.band_coeffs, IVAS_MAX_NUM_BANDS );
     602        1764 :     ivas_clear_band_coeffs_fx( hMdDec->band_coeffs_prev, IVAS_MAX_NUM_BANDS );
     603             : 
     604        1764 :     ivas_clear_band_coeff_idx( hMdDec->spar_md.band_coeffs_idx, IVAS_MAX_NUM_BANDS );
     605        1764 :     ivas_clear_band_coeff_idx( hMdDec->spar_md_prev.band_coeffs_idx, IVAS_MAX_NUM_BANDS );
     606        1764 :     ivas_clear_band_coeff_idx( hMdDec->spar_md_prev.band_coeffs_idx_mapped, IVAS_MAX_NUM_BANDS );
     607             : 
     608        1764 :     hMdDec->spar_md.dtx_vad = 0;
     609        1764 :     move16();
     610        1764 :     hMdDec->td_decorr_flag = 1;
     611        1764 :     move16();
     612             : 
     613             : 
     614        1764 :     set32_fx( hMdDec->spar_md.en_ratio_slow_fx, 0, IVAS_MAX_NUM_BANDS );
     615        1764 :     set32_fx( hMdDec->spar_md.ref_pow_slow_fx, 0, IVAS_MAX_NUM_BANDS );
     616        1764 :     set16_fx( hMdDec->smooth_fac_fx, 0, IVAS_MAX_NUM_BANDS );
     617             : 
     618       22932 :     FOR( i = 0; i < IVAS_MAX_NUM_BANDS; i++ )
     619             :     {
     620       21168 :         set32_fx( hMdDec->smooth_buf_fx[i], 0, 2 * SBA_DIRAC_NRG_SMOOTH_LONG + 1 );
     621             :     }
     622             : 
     623       21168 :     FOR( i = 0; i < IVAS_SPAR_MAX_CH; i++ )
     624             :     {
     625      232848 :         FOR( j = 0; j < IVAS_SPAR_MAX_CH; j++ )
     626             :         {
     627      213444 :             set32_fx( hMdDec->mixer_mat_prev2_fx[i][j], 0, IVAS_MAX_NUM_BANDS );
     628             :         }
     629             :     }
     630        1764 :     hMdDec->first_valid_frame = 1;
     631        1764 :     move16();
     632             : 
     633        1764 :     return IVAS_ERR_OK;
     634             : }
     635             : 
     636             : 
     637             : /*-----------------------------------------------------------------------------------------*
     638             :  * Function ivas_spar_set_dec_config()
     639             :  *
     640             :  * Set configuration for SPAR MD decoder
     641             :  *-----------------------------------------------------------------------------------------*/
     642        1764 : static ivas_error ivas_spar_set_dec_config(
     643             :     ivas_spar_md_dec_state_t *hMdDec,
     644             :     const Word16 nchan_transport,
     645             :     Word32 *pFC /*Q0*/ )
     646             : {
     647             :     Word16 i, j, nchan, dmx_ch;
     648             : 
     649        5733 :     FOR( i = 0; i < nchan_transport; i++ )
     650             :     {
     651        3969 :         hMdDec->spar_md_cfg.max_freq_per_chan[i] = ivas_spar_br_table_consts[hMdDec->table_idx].fpcs; /*Q0*/
     652        3969 :         move16();
     653             :     }
     654             : 
     655        1764 :     nchan = ivas_sba_get_nchan_metadata_fx( ivas_spar_br_table_consts[hMdDec->table_idx].sba_order, ivas_spar_br_table_consts[hMdDec->table_idx].ivas_total_brate ); /*Q0*/
     656             : 
     657        1764 :     SWITCH( nchan )
     658             :     {
     659        1524 :         case 4: /* FOA_CHANNELS */
     660        1524 :             hMdDec->num_decorr = IVAS_TD_DECORR_OUT_3CH;
     661        1524 :             move16();
     662        1524 :             BREAK;
     663          17 :         case 9: /* IVAS_HOA_2_CH */
     664          17 :             hMdDec->num_decorr = IVAS_TD_DECORR_OUT_5CH;
     665          17 :             move16();
     666          17 :             BREAK;
     667          38 :         case 6: /* IVAS_HOA_2_CH */
     668          38 :             hMdDec->num_decorr = IVAS_TD_DECORR_OUT_2CH;
     669          38 :             move16();
     670          38 :             BREAK;
     671         114 :         case 8: /* IVAS_HOA_3_CH */
     672         114 :             hMdDec->num_decorr = IVAS_TD_DECORR_OUT_4CH;
     673         114 :             move16();
     674         114 :             BREAK;
     675             :     }
     676             : 
     677        1764 :     hMdDec->spar_md_cfg.num_umx_chs = nchan; /*Q0*/
     678        1764 :     move16();
     679             : 
     680        1764 :     dmx_ch = 0;
     681        1764 :     move16();
     682       22932 :     FOR( i = 0; i < IVAS_MAX_NUM_BANDS; i++ )
     683             :     {
     684       21168 :         dmx_ch = 0;
     685       21168 :         move16();
     686       68796 :         FOR( j = 0; j < nchan_transport; j++ )
     687             :         {
     688       47628 :             if ( LT_32( pFC[i], hMdDec->spar_md_cfg.max_freq_per_chan[j] ) )
     689             :             {
     690       47628 :                 dmx_ch = add( dmx_ch, 1 );
     691             :             }
     692             :         }
     693             : 
     694       21168 :         hMdDec->spar_md_cfg.num_dmx_chans_per_band[i] = hMdDec->spar_md_cfg.nchan_transport; /*Q0*/
     695       21168 :         move16();
     696       21168 :         hMdDec->spar_md_cfg.num_decorr_per_band[i] = sub( nchan, hMdDec->spar_md_cfg.nchan_transport ); /*Q0*/
     697       21168 :         move16();
     698             :     }
     699             : 
     700        1764 :     hMdDec->spar_md_cfg.nchan_transport = dmx_ch; /*Q0*/
     701        1764 :     move16();
     702             : 
     703        1764 :     return IVAS_ERR_OK;
     704             : }
     705             : 
     706             : 
     707             : /*-----------------------------------------------------------------------------------------*
     708             :  * Function ivas_dec_mono_sba_handling()
     709             :  *
     710             :  *
     711             :  *-----------------------------------------------------------------------------------------*/
     712             : 
     713      140904 : static void ivas_dec_mono_sba_handling_fx(
     714             :     Decoder_Struct *st_ivas /* i/o: IVAS decoder handle                                 */
     715             : )
     716             : {
     717             :     Word16 mono_flag, b, block;
     718             : 
     719      140904 :     mono_flag = 1;
     720      140904 :     move16();
     721             : 
     722      697173 :     FOR( b = 0; b < st_ivas->hQMetaData->q_direction[0].cfg.nbands; b++ )
     723             :     {
     724     2781345 :         FOR( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; ++block )
     725             :         {
     726     2225076 :             Word32 azimuth_fx = st_ivas->hQMetaData->q_direction[0].band_data[b].azimuth_fx[block]; /*Q22*/
     727     2225076 :             move32();
     728     2225076 :             Word32 elevation_fx = st_ivas->hQMetaData->q_direction[0].band_data[b].azimuth_fx[block]; /*Q22*/
     729     2225076 :             move32();
     730     2225076 :             Word32 energy_ratio_fx = st_ivas->hQMetaData->q_direction[0].band_data[0].energy_ratio_fx[block]; /*Q30*/
     731     2225076 :             move32();
     732             : 
     733     2225076 :             test();
     734     2225076 :             test();
     735     2225076 :             if (
     736      525613 :                 ( ( azimuth_fx != 0 ) ) ||
     737      525613 :                 ( ( elevation_fx != 0 ) ) ||
     738      525613 :                 ( GT_32( energy_ratio_fx, 161061274 /* 0.15f in Q30 */ ) ) ) /* 0.15f is just above the lowest quantised value. */
     739             :             {
     740     1932195 :                 mono_flag = 0;
     741     1932195 :                 move16();
     742             :             }
     743             :         }
     744             :     }
     745             : 
     746             :     /* Combine the SPAR prediction coefs flag with the azimuth, elevation and energy ratio flag.*/
     747      140904 :     test();
     748      140904 :     mono_flag = mono_flag && ivas_spar_chk_zero_coefs_fx( st_ivas );
     749             : 
     750      140904 :     IF( mono_flag )
     751             :     {
     752             :         /* Set Energy Ratio values to be zero */
     753          96 :         FOR( b = 0; b < st_ivas->hQMetaData->q_direction[0].cfg.nbands; b++ )
     754             :         {
     755          72 :             set32_fx( st_ivas->hQMetaData->q_direction[0].band_data[b].energy_ratio_fx, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
     756             :         }
     757          24 :         IF( st_ivas->hDirAC != NULL )
     758             :         {
     759          21 :             FOR( block = 0; block < st_ivas->hSpatParamRendCom->dirac_md_buffer_length; ++block )
     760             :             {
     761             :                 /* Set directional Energy Ratio values to be zero */
     762          18 :                 set32_fx( st_ivas->hSpatParamRendCom->energy_ratio1_fx[block], 0, st_ivas->hSpatParamRendCom->num_freq_bands );
     763          18 :                 IF( EQ_32( st_ivas->hQMetaData->no_directions, 2 ) )
     764             :                 {
     765           0 :                     set32_fx( st_ivas->hSpatParamRendCom->energy_ratio2_fx[block], 0, st_ivas->hSpatParamRendCom->num_freq_bands );
     766             :                 }
     767             :                 /* Set Diffuseness values to be 1.0 */
     768          18 :                 set32_fx( st_ivas->hSpatParamRendCom->diffuseness_vector_fx[block], ONE_IN_Q30, st_ivas->hSpatParamRendCom->num_freq_bands ); /*Q30*/
     769             :             }
     770             :         }
     771             :     }
     772             : 
     773      140904 :     return;
     774             : }
     775             : 
     776             : 
     777             : /*-----------------------------------------------------------------------------------------*
     778             :  * Function ivas_spar_md_dec_process_fx()
     779             :  *
     780             :  * SPAR Meta Data decoder process
     781             :  *-----------------------------------------------------------------------------------------*/
     782             : 
     783      140904 : void ivas_spar_md_dec_process_fx(
     784             :     Decoder_Struct *st_ivas,    /* i/o: IVAS decoder handle                                */
     785             :     Decoder_State *st0,         /* i/o: decoder state structure - for bitstream handling   */
     786             :     const Word16 num_bands_out, /* i  : number of output bands                             Q0*/
     787             :     const Word16 sba_order      /* i  : Ambisonic (SBA) order                              Q0*/
     788             : )
     789             : {
     790             :     Word16 j, k, b, bw, dtx_vad, nB, i_ts;
     791             :     ivas_spar_md_dec_state_t *hMdDec;
     792             :     Word16 num_md_chs;
     793             :     Word16 num_md_sub_frames;
     794             :     Word16 dyn_active_w_flag;
     795             :     Word16 active_w_vlbr;
     796             : 
     797      140904 :     hMdDec = st_ivas->hSpar->hMdDec;
     798             : 
     799      140904 :     IF( LT_32( st_ivas->hDecoderConfig->ivas_total_brate, IVAS_24k4 ) )
     800             :     {
     801       11277 :         active_w_vlbr = 1;
     802       11277 :         move16();
     803             :     }
     804             :     ELSE
     805             :     {
     806      129627 :         active_w_vlbr = 0;
     807      129627 :         move16();
     808             :     }
     809             : 
     810      140904 :     num_md_chs = ivas_sba_get_nchan_metadata_fx( sba_order, st_ivas->hDecoderConfig->ivas_total_brate ); /*Q0*/
     811             : 
     812      140904 :     num_md_sub_frames = ivas_get_spar_dec_md_num_subframes( sba_order, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->last_active_ivas_total_brate ); /*Q0*/
     813             : 
     814      140904 :     test();
     815      140904 :     IF( GT_16( hMdDec->spar_md_cfg.nchan_transport, 1 ) && LE_16( hMdDec->spar_md_cfg.nchan_transport, 3 ) )
     816             :     {
     817       66317 :         hMdDec->spar_md.res_ind = 0;
     818       66317 :         move16();
     819       66317 :         dyn_active_w_flag = get_next_indice_fx( st0, 1 ); /*Q0*/
     820       66317 :         IF( EQ_16( dyn_active_w_flag, 1 ) )
     821             :         {
     822           0 :             IF( EQ_16( hMdDec->spar_md_cfg.nchan_transport, 2 ) )
     823             :             {
     824           0 :                 hMdDec->spar_md.res_ind = get_next_indice_fx( st0, 1 ); /*Q0*/
     825           0 :                 move16();
     826           0 :                 hMdDec->spar_md.res_ind = add( hMdDec->spar_md_cfg.nchan_transport, hMdDec->spar_md.res_ind ); /*Q0*/
     827           0 :                 move16();
     828             :             }
     829           0 :             ELSE IF( EQ_16( hMdDec->spar_md_cfg.nchan_transport, 3 ) )
     830             :             {
     831           0 :                 hMdDec->spar_md.res_ind = remix_order_set[hMdDec->spar_md_cfg.remix_unmix_order][hMdDec->spar_md_cfg.nchan_transport]; /*Q0*/
     832           0 :                 move16();
     833             :             }
     834             :         }
     835             :     }
     836             :     ELSE
     837             :     {
     838       74587 :         dyn_active_w_flag = 0;
     839       74587 :         move16();
     840       74587 :         IF( EQ_16( hMdDec->spar_md_cfg.nchan_transport, FOA_CHANNELS ) )
     841             :         {
     842       36993 :             get_next_indice_fx( st0, 1 );
     843             :         }
     844             :     }
     845             : 
     846      140904 :     ivas_spar_dec_parse_md_bs_fx( hMdDec, st0, &nB, &bw, &dtx_vad, st_ivas->hDecoderConfig->ivas_total_brate,
     847      140904 :                                   st_ivas->hQMetaData->sba_inactive_mode );
     848             : 
     849      140904 :     assert( nB == hMdDec->spar_md.num_bands );
     850      140904 :     assert( bw == 1 );
     851      140904 :     ivas_spar_md_fill_invalid_bandcoeffs(
     852             :         hMdDec->spar_md.band_coeffs,
     853             :         hMdDec->band_coeffs_prev,
     854      140904 :         &hMdDec->valid_bands[0],
     855             :         &hMdDec->base_band_coeffs_age[0],
     856             :         &hMdDec->first_valid_frame,
     857             :         nB );
     858             : 
     859      140904 :     ivas_dec_mono_sba_handling_fx( st_ivas );
     860             : 
     861             :     /* SPAR to DirAC conversion */
     862      140904 :     IF( EQ_16( hMdDec->spar_hoa_dirac2spar_md_flag, 1 ) )
     863             :     {
     864      131040 :         ivas_spar_to_dirac_fx( st_ivas, hMdDec, dtx_vad, num_bands_out, bw, dyn_active_w_flag );
     865             :     }
     866             : 
     867             :     /* set correct number of bands*/
     868      140904 :     nB = IVAS_MAX_NUM_BANDS;
     869      140904 :     move16();
     870             : 
     871             :     /* expand DirAC MD to all time slots */
     872      501129 :     FOR( i_ts = 1; i_ts < num_md_sub_frames; i_ts++ )
     873             :     {
     874     3373413 :         FOR( b = 0; b < hMdDec->spar_md.num_bands; b++ )
     875             :         {
     876    33145068 :             FOR( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ )
     877             :             {
     878    30131880 :                 hMdDec->spar_md.band_coeffs[( b + ( i_ts * IVAS_MAX_NUM_BANDS ) )].pred_re_fx[j] = hMdDec->spar_md.band_coeffs[b].pred_re_fx[j]; /*Q22*/
     879    30131880 :                 move32();
     880             :             }
     881             : 
     882    24105504 :             FOR( j = 0; j < IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS; j++ )
     883             :             {
     884    84369264 :                 FOR( k = 0; k < IVAS_SPAR_MAX_DMX_CHS - 1; k++ )
     885             :                 {
     886    63276948 :                     hMdDec->spar_md.band_coeffs[( b + ( i_ts * IVAS_MAX_NUM_BANDS ) )].C_re_fx[j][k] = hMdDec->spar_md.band_coeffs[b].C_re_fx[j][k]; /*Q22*/
     887    63276948 :                     move32();
     888             :                 }
     889             :             }
     890             : 
     891    33145068 :             FOR( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ )
     892             :             {
     893    30131880 :                 hMdDec->spar_md.band_coeffs[add( b, i_mult( i_ts, IVAS_MAX_NUM_BANDS ) )].P_re_fx[j] = hMdDec->spar_md.band_coeffs[b].P_re_fx[j]; /*Q22*/
     894    30131880 :                 move32();
     895             :             }
     896             :         }
     897             :     }
     898             : 
     899      140904 :     ivas_get_spar_matrices_fx( hMdDec, num_bands_out, num_md_sub_frames, bw, dtx_vad, nB, num_md_chs, active_w_vlbr, dyn_active_w_flag );
     900             : 
     901             : #ifdef DEBUG_SPAR_DIRAC_WRITE_OUT_PRED_PARS
     902             :     {
     903             :         static FILE *fid = 0;
     904             :         int16_t band = 9;
     905             :         if ( !fid )
     906             :         {
     907             :             fid = fopen( "pred_coeffs_dec.txt", "wt" );
     908             :         }
     909             :         fprintf( fid, "%.6f\n", hMdDec->mixer_mat[1][0][band] );
     910             :     }
     911             : #endif
     912      140904 :     ivas_spar_md_fill_invalid_bands_fx( &hMdDec->spar_coeffs, &hMdDec->spar_coeffs_prev, &hMdDec->valid_bands[0], &hMdDec->base_band_age[0], num_bands_out, num_md_chs, num_md_sub_frames );
     913             : 
     914             : 
     915      140904 :     hMdDec->dtx_md_smoothing_cntr = 1;
     916      140904 :     move16();
     917             : 
     918      140904 :     return;
     919             : }
     920             : 
     921             : 
     922         744 : Word16 ivas_spar_chk_zero_coefs_fx(
     923             :     Decoder_Struct *st_ivas /* i/o: IVAS decoder handle        */
     924             : )
     925             : {
     926             :     Word16 j, k, b;
     927             :     ivas_spar_md_dec_state_t *hMdDec;
     928         744 :     Word16 mono = 1;
     929         744 :     move16();
     930             :     Word16 ndec, ndm;
     931             : 
     932         744 :     hMdDec = st_ivas->hSpar->hMdDec;
     933         744 :     ndec = hMdDec->spar_md_cfg.num_decorr_per_band[0]; /*Q0*/
     934         744 :     move16();
     935         744 :     ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[0]; /*Q0*/
     936         744 :     move16();
     937             : 
     938         744 :     Word16 min_bands = s_min( hMdDec->spar_md.num_bands, SPAR_DIRAC_SPLIT_START_BAND );
     939        6696 :     FOR( b = 0; b < min_bands; b++ )
     940             :     {
     941       23888 :         FOR( j = 0; j < ( ( ndm + ndec ) - 1 ); j++ )
     942             :         {
     943       17936 :             if ( hMdDec->spar_md.band_coeffs[b].pred_re_fx[j] != 0 )
     944             :             {
     945        9517 :                 mono = 0;
     946        9517 :                 move16();
     947             :             }
     948             :         }
     949       22352 :         FOR( j = 0; j < ndec; j++ )
     950             :         {
     951       18480 :             FOR( k = 0; k < ( ndm - 1 ); k++ )
     952             :             {
     953        2080 :                 if ( hMdDec->spar_md.band_coeffs[b].C_re_fx[j][k] != 0 )
     954             :                 {
     955         708 :                     mono = 0;
     956         708 :                     move16();
     957             :                 }
     958             :             }
     959             :         }
     960       22352 :         FOR( j = 0; j < ndec; j++ )
     961             :         {
     962       16400 :             if ( hMdDec->spar_md.band_coeffs[b].P_re_fx[j] != 0 )
     963             :             {
     964       15287 :                 mono = 0;
     965       15287 :                 move16();
     966             :             }
     967             :         }
     968             :     }
     969             : 
     970         744 :     return mono;
     971             : }
     972             : 
     973             : 
     974             : /*-----------------------------------------------------------------------------------------*
     975             :  * Function ivas_spar_smooth_md_dtx()
     976             :  *
     977             :  * Smooth MD during no data frame during DTX
     978             :  *-----------------------------------------------------------------------------------------*/
     979             : 
     980        2189 : void ivas_spar_smooth_md_dtx_fx(
     981             :     ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle        */
     982             :     const Word16 num_bands_out,       /* i  : number of output bands        Q0*/
     983             :     const Word16 num_md_sub_frames    /* i  : number of metadata subframes  Q0*/
     984             : )
     985             : {
     986             :     Word16 j, k, b, dmx_ch;
     987             :     Word16 ramp_fx;
     988             :     Word32 tar_fx, prev_fx, new_val_fx;
     989             : 
     990             :     /* ramp = (float)hMdDec->dtx_md_smoothing_cntr / IVAS_DEFAULT_DTX_CNG_RAMP; */
     991        2189 :     ramp_fx = i_mult_sat( hMdDec->dtx_md_smoothing_cntr, 4096 /* 1 / IVAS_DEFAULT_DTX_CNG_RAMP in Q15 */ ); /* Q15 */
     992             : 
     993       28457 :     FOR( b = 0; b < num_bands_out; b++ )
     994             :     {
     995       26268 :         dmx_ch = hMdDec->spar_md_cfg.num_dmx_chans_per_band[b];
     996       26268 :         move16();
     997             : 
     998      105072 :         FOR( j = 1; j < FOA_CHANNELS; j++ )
     999             :         {
    1000      276948 :             FOR( k = dmx_ch; k < FOA_CHANNELS; k++ )
    1001             :             {
    1002      198144 :                 prev_fx = hMdDec->spar_coeffs_prev.P_re_fx[j][k][b]; /* Q22 */
    1003      198144 :                 move32();
    1004      198144 :                 tar_fx = hMdDec->spar_coeffs_tar.P_re_fx[j][k][b]; /* Q22 */
    1005      198144 :                 move32();
    1006      198144 :                 new_val_fx = L_add( prev_fx, Mpy_32_16_1( L_sub( tar_fx, prev_fx ), ramp_fx ) ); /* Q22 + Q15 - Q15 = Q22*/
    1007      198144 :                 hMdDec->spar_coeffs.P_re_fx[j][k][b] = new_val_fx;                               /* Q22 */
    1008      198144 :                 move32();
    1009             :             }
    1010             :         }
    1011             : 
    1012      131340 :         FOR( j = 0; j < FOA_CHANNELS; j++ )
    1013             :         {
    1014      261168 :             FOR( k = 0; k < dmx_ch; k++ )
    1015             :             {
    1016      156096 :                 prev_fx = hMdDec->spar_coeffs_prev.C_re_fx[j][k][b]; /* Q22 */
    1017      156096 :                 move32();
    1018      156096 :                 tar_fx = hMdDec->spar_coeffs_tar.C_re_fx[j][k][b]; /* Q22 */
    1019      156096 :                 move32();
    1020      156096 :                 new_val_fx = L_add( prev_fx, Mpy_32_16_1( L_sub( tar_fx, prev_fx ), ramp_fx ) ); /* Q22 + Q15 - Q15 = Q22*/
    1021      156096 :                 hMdDec->spar_coeffs.C_re_fx[j][k][b] = new_val_fx;                               /* Q22 */
    1022      156096 :                 move32();
    1023             :             }
    1024             :         }
    1025             :     }
    1026             : 
    1027             :     /* expand MD to all time slots */
    1028        8519 :     FOR( Word16 i_ts = 1; i_ts < num_md_sub_frames; i_ts++ )
    1029             :     {
    1030       82290 :         FOR( b = 0; b < num_bands_out; b++ )
    1031             :         {
    1032       75960 :             dmx_ch = hMdDec->spar_md_cfg.num_dmx_chans_per_band[b]; /*Q0*/
    1033       75960 :             move16();
    1034             : 
    1035      303840 :             FOR( j = 1; j < FOA_CHANNELS; j++ )
    1036             :             {
    1037      796716 :                 FOR( k = dmx_ch; k < FOA_CHANNELS; k++ )
    1038             :                 {
    1039      568836 :                     hMdDec->spar_coeffs.P_re_fx[j][k][( b + ( i_ts * IVAS_MAX_NUM_BANDS ) )] = hMdDec->spar_coeffs.P_re_fx[j][k][b]; /* Q22 */
    1040      568836 :                     move32();
    1041             :                 }
    1042             :             }
    1043             : 
    1044      379800 :             FOR( j = 0; j < FOA_CHANNELS; j++ )
    1045             :             {
    1046      760752 :                 FOR( k = 0; k < dmx_ch; k++ )
    1047             :                 {
    1048      456912 :                     hMdDec->spar_coeffs.C_re_fx[j][k][( b + ( i_ts * IVAS_MAX_NUM_BANDS ) )] = hMdDec->spar_coeffs.C_re_fx[j][k][b]; /* Q22 */
    1049      456912 :                     move32();
    1050             :                 }
    1051             :             }
    1052             :         }
    1053             :     }
    1054             : 
    1055        2189 :     hMdDec->dtx_md_smoothing_cntr = s_min( add( hMdDec->dtx_md_smoothing_cntr, 1 ), IVAS_DEFAULT_DTX_CNG_RAMP );
    1056        2189 :     move16();
    1057             : 
    1058        2189 :     return;
    1059             : }
    1060             : 
    1061             : 
    1062             : /*-----------------------------------------------------------------------------------------*
    1063             :  * Function ivas_spar_setup_md_smoothing()
    1064             :  *
    1065             :  * Set up smoothing of SPAR MD when SID update frame is received
    1066             :  *-----------------------------------------------------------------------------------------*/
    1067             : 
    1068         125 : void ivas_spar_setup_md_smoothing_fx(
    1069             :     ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle        */
    1070             :     const Word16 num_bands_out,       /* i  : number of output bands        Q0*/
    1071             :     const Word16 num_md_sub_frames    /* i  : number of metadata subframes  Q0*/
    1072             : )
    1073             : {
    1074             :     /* copy the coeffs */
    1075             :     Word16 num_channels, i, j, k;
    1076             : 
    1077         125 :     num_channels = hMdDec->spar_md_cfg.num_umx_chs; /*Q0*/
    1078         125 :     move16();
    1079             : 
    1080         625 :     FOR( i = 0; i < num_channels; i++ )
    1081             :     {
    1082        2500 :         FOR( j = 0; j < num_channels; j++ )
    1083             :         {
    1084       26000 :             FOR( k = 0; k < IVAS_MAX_NUM_BANDS; k++ )
    1085             :             {
    1086       24000 :                 hMdDec->spar_coeffs_prev.C_re_fx[i][j][k] = hMdDec->spar_coeffs_tar.C_re_fx[i][j][k]; /* Q22 */
    1087       24000 :                 move32();
    1088             :             }
    1089             :         }
    1090             :     }
    1091             : 
    1092         625 :     FOR( i = 0; i < num_channels; i++ )
    1093             :     {
    1094        2500 :         FOR( j = 0; j < num_channels; j++ )
    1095             :         {
    1096       26000 :             FOR( k = 0; k < IVAS_MAX_NUM_BANDS; k++ )
    1097             :             {
    1098       24000 :                 hMdDec->spar_coeffs_prev.P_re_fx[i][j][k] = hMdDec->spar_coeffs_tar.P_re_fx[i][j][k]; /* Q22 */
    1099       24000 :                 move32();
    1100             :             }
    1101             :         }
    1102             :     }
    1103             : 
    1104         625 :     FOR( i = 0; i < num_channels; i++ )
    1105             :     {
    1106        2500 :         FOR( j = 0; j < num_channels; j++ )
    1107             :         {
    1108       26000 :             FOR( k = 0; k < IVAS_MAX_NUM_BANDS; k++ )
    1109             :             {
    1110       24000 :                 hMdDec->spar_coeffs_tar.C_re_fx[i][j][k] = hMdDec->spar_coeffs.C_re_fx[i][j][k]; /* Q22 */
    1111       24000 :                 move32();
    1112             :             }
    1113             :         }
    1114             :     }
    1115             : 
    1116         625 :     FOR( i = 0; i < num_channels; i++ )
    1117             :     {
    1118        2500 :         FOR( j = 0; j < num_channels; j++ )
    1119             :         {
    1120       26000 :             FOR( k = 0; k < IVAS_MAX_NUM_BANDS; k++ )
    1121             :             {
    1122       24000 :                 hMdDec->spar_coeffs_tar.P_re_fx[i][j][k] = hMdDec->spar_coeffs.P_re_fx[i][j][k]; /* Q22 */
    1123       24000 :                 move32();
    1124             :             }
    1125             :         }
    1126             :     }
    1127             : 
    1128         125 :     ivas_spar_smooth_md_dtx_fx( hMdDec, num_bands_out, num_md_sub_frames );
    1129             : 
    1130         125 :     return;
    1131             : }
    1132             : 
    1133             : 
    1134             : /*-----------------------------------------------------------------------------------------*
    1135             :  * Function ivas_spar_update_md_hist()
    1136             :  *
    1137             :  * Update previous and target MD
    1138             :  *-----------------------------------------------------------------------------------------*/
    1139             : 
    1140      140779 : void ivas_spar_update_md_hist_fx(
    1141             :     ivas_spar_md_dec_state_t *hMdDec /* i/o: SPAR MD decoder handle */
    1142             : )
    1143             : {
    1144             :     Word16 num_channels, i, j, k;
    1145             : 
    1146      140779 :     num_channels = hMdDec->spar_md_cfg.num_umx_chs; /*Q0*/
    1147      140779 :     move16();
    1148             : 
    1149      801395 :     FOR( i = 0; i < num_channels; i++ )
    1150             :     {
    1151     4233268 :         FOR( j = 0; j < num_channels; j++ )
    1152             :         {
    1153    46444476 :             FOR( k = 0; k < IVAS_MAX_NUM_BANDS; k++ )
    1154             :             {
    1155    42871824 :                 hMdDec->spar_coeffs_prev.C_re_fx[i][j][k] = hMdDec->spar_coeffs.C_re_fx[i][j][k]; /* Q22 */
    1156    42871824 :                 move32();
    1157             :             }
    1158             :         }
    1159             :     }
    1160             : 
    1161      801395 :     FOR( i = 0; i < num_channels; i++ )
    1162             :     {
    1163     4233268 :         FOR( j = 0; j < num_channels; j++ )
    1164             :         {
    1165    46444476 :             FOR( k = 0; k < IVAS_MAX_NUM_BANDS; k++ )
    1166             :             {
    1167    42871824 :                 hMdDec->spar_coeffs_prev.P_re_fx[i][j][k] = hMdDec->spar_coeffs.P_re_fx[i][j][k]; /* Q22 */
    1168    42871824 :                 move32();
    1169             :             }
    1170             :         }
    1171             :     }
    1172             : 
    1173      801395 :     FOR( i = 0; i < num_channels; i++ )
    1174             :     {
    1175     4233268 :         FOR( j = 0; j < num_channels; j++ )
    1176             :         {
    1177    46444476 :             FOR( k = 0; k < IVAS_MAX_NUM_BANDS; k++ )
    1178             :             {
    1179    42871824 :                 hMdDec->spar_coeffs_tar.C_re_fx[i][j][k] = hMdDec->spar_coeffs.C_re_fx[i][j][k]; /* Q22 */
    1180    42871824 :                 move32();
    1181             :             }
    1182             :         }
    1183             :     }
    1184             : 
    1185      801395 :     FOR( i = 0; i < num_channels; i++ )
    1186             :     {
    1187     4233268 :         FOR( j = 0; j < num_channels; j++ )
    1188             :         {
    1189    46444476 :             FOR( k = 0; k < IVAS_MAX_NUM_BANDS; k++ )
    1190             :             {
    1191    42871824 :                 hMdDec->spar_coeffs_tar.P_re_fx[i][j][k] = hMdDec->spar_coeffs.P_re_fx[i][j][k]; /* Q22 */
    1192    42871824 :                 move32();
    1193             :             }
    1194             :         }
    1195             :     }
    1196             : 
    1197      140779 :     return;
    1198             : }
    1199             : 
    1200             : /*-----------------------------------------------------------------------------------------*
    1201             :  * Function ivas_get_spar_matrices()
    1202             :  *
    1203             :  * Get SPAR matrices
    1204             :  *-----------------------------------------------------------------------------------------*/
    1205             : 
    1206      140904 : static void ivas_get_spar_matrices_fx(
    1207             :     ivas_spar_md_dec_state_t *hMdDec,
    1208             :     const Word16 num_bands_out, /*Q0*/
    1209             :     const Word16 n_ts,          /*Q0*/
    1210             :     const Word16 bw,            /*Q0*/
    1211             :     const Word16 dtx_vad,       /*Q0*/
    1212             :     const Word16 nB,            /*Q0*/
    1213             :     const Word16 numch_out,     /*Q0*/
    1214             :     const Word16 active_w_vlbr, /*Q0*/
    1215             :     const Word16 dyn_active_w_flag /*Q0*/ )
    1216             : {
    1217             :     Word16 num_bands, dmx_ch, split_band;
    1218             :     Word16 i, j, k, m, b, i_ts, active_w;
    1219             :     const Word16 *order;
    1220             :     Word32 active_w_dm_fac_fx, re_fx, re_fx1;
    1221             : 
    1222      140904 :     num_bands = num_bands_out;
    1223      140904 :     move16();
    1224      140904 :     order = remix_order_set[hMdDec->spar_md_cfg.remix_unmix_order];
    1225             : 
    1226      140904 :     split_band = SPAR_DIRAC_SPLIT_START_BAND;
    1227      140904 :     move16();
    1228             : 
    1229             :     // Dead code as SPAR_DIRAC_SPLIT_START_BAND = 8 and IVAS_MAX_NUM_BANDS = 12
    1230      140904 :     IF( GE_16( split_band, IVAS_MAX_NUM_BANDS ) )
    1231             :     {
    1232             :         /*store previous 4x4 parameters for linear interpolation to current*/
    1233             : 
    1234           0 :         FOR( i = 0; i < numch_out; i++ )
    1235             :         {
    1236           0 :             FOR( j = 0; j < numch_out; j++ )
    1237             :             {
    1238           0 :                 FOR( b = 0; b < num_bands; b++ )
    1239             :                 {
    1240           0 :                     hMdDec->mixer_mat_prev_fx[0][i][j][b] = hMdDec->mixer_mat_fx[i][j][b]; /*hMdDec->Q_mixer_mat*/
    1241           0 :                     move32();
    1242             :                 }
    1243             :             }
    1244             :         }
    1245             :     }
    1246             : 
    1247      140904 :     if ( EQ_16( bw, IVAS_RED_BAND_FACT ) )
    1248             :     {
    1249           0 :         num_bands = shr( num_bands, 1 );
    1250             :     }
    1251             : 
    1252      140904 :     test();
    1253      140904 :     active_w = EQ_16( dyn_active_w_flag, 1 ) || EQ_16( hMdDec->spar_md_cfg.active_w, 1 );
    1254             : 
    1255      140904 :     IF( dtx_vad == 0 )
    1256             :     {
    1257         557 :         active_w_dm_fac_fx = IVAS_ACTIVEW_DM_F_SCALE_DTX_FX;
    1258         557 :         move32();
    1259             :     }
    1260      140347 :     ELSE IF( EQ_16( active_w_vlbr, 1 ) )
    1261             :     {
    1262       10943 :         active_w_dm_fac_fx = IVAS_ACTIVEW_DM_F_SCALE_VLBR_FX;
    1263       10943 :         move32();
    1264             :     }
    1265             :     ELSE
    1266             :     {
    1267      129404 :         active_w_dm_fac_fx = IVAS_ACTIVEW_DM_F_SCALE_FX;
    1268      129404 :         move32();
    1269             :     }
    1270             : 
    1271      642033 :     FOR( i_ts = 0; i_ts < n_ts; i_ts++ )
    1272             :     {
    1273     2701635 :         FOR( i = 0; i < numch_out; i++ )
    1274             :         {
    1275    12654842 :             FOR( j = 0; j < numch_out; j++ )
    1276             :             {
    1277             : 
    1278    10454336 :                 set32_fx( &hMdDec->spar_coeffs.C_re_fx[i][j][( i_ts * IVAS_MAX_NUM_BANDS )], 0, IVAS_MAX_NUM_BANDS );
    1279    10454336 :                 set32_fx( &hMdDec->spar_coeffs.P_re_fx[i][j][( i_ts * IVAS_MAX_NUM_BANDS )], 0, IVAS_MAX_NUM_BANDS );
    1280             :             }
    1281             :         }
    1282      501129 :         num_bands = s_min( num_bands, nB );
    1283      501129 :         move16();
    1284             : 
    1285     6425845 :         FOR( b = 0; b < num_bands; b++ )
    1286             :         {
    1287             :             Word32 tmp_C1_re_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH];
    1288             :             Word32 tmp_C2_re_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH];
    1289             :             Word32 tmp_dm_re_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH];
    1290     5924716 :             dmx_ch = hMdDec->spar_md_cfg.num_dmx_chans_per_band[( bw * b )]; /*Q0*/
    1291     5924716 :             move16();
    1292             : 
    1293    31959460 :             FOR( j = 0; j < numch_out; j++ )
    1294             :             {
    1295    26034744 :                 set_zero_fx( tmp_C1_re_fx[j], numch_out );
    1296    26034744 :                 set_zero_fx( tmp_C2_re_fx[j], numch_out );
    1297    26034744 :                 set_zero_fx( tmp_dm_re_fx[j], numch_out );
    1298             : 
    1299    26034744 :                 tmp_C1_re_fx[j][j] = ONE_IN_Q22; /*Q22*/
    1300    26034744 :                 tmp_C2_re_fx[j][j] = ONE_IN_Q22; /*Q22*/
    1301    26034744 :                 tmp_dm_re_fx[j][j] = ONE_IN_Q22; /*Q22*/
    1302    26034744 :                 move32();
    1303    26034744 :                 move32();
    1304    26034744 :                 move32();
    1305             :             }
    1306             : 
    1307    26034744 :             FOR( j = 1; j < numch_out; j++ )
    1308             :             {
    1309    20110028 :                 tmp_C1_re_fx[j][0] = hMdDec->spar_md.band_coeffs[( b + ( i_ts * IVAS_MAX_NUM_BANDS ) )].pred_re_fx[j - 1]; // Q.22
    1310    20110028 :                 move32();
    1311             :             }
    1312             : 
    1313     5924716 :             IF( EQ_16( active_w, 1 ) )
    1314             :             {
    1315     5509424 :                 FOR( j = 1; j < numch_out; j++ )
    1316             :                 {
    1317             : 
    1318     4132068 :                     tmp_C2_re_fx[0][j] = Mpy_32_32( active_w_dm_fac_fx, L_negate( hMdDec->spar_md.band_coeffs[( b + ( i_ts * IVAS_MAX_NUM_BANDS ) )].pred_re_fx[j - 1] ) ); // Q31 *Q22=Q22
    1319     4132068 :                     move32();
    1320             :                 }
    1321             : #ifdef OPT_SBA_DEC_V2_BE
    1322     1377356 :                 re_fx1 = Madd_32_32( ONE_IN_Q13, tmp_C2_re_fx[0][1], tmp_C1_re_fx[1][0] ); // Q13+Q13
    1323             : 
    1324     1377356 :                 re_fx1 = Madd_32_32( re_fx1, tmp_C2_re_fx[0][2], tmp_C1_re_fx[2][0] ); // Q13+Q13
    1325             : 
    1326     1377356 :                 tmp_dm_re_fx[0][0] = L_shl( Madd_32_32( re_fx1, tmp_C2_re_fx[0][3], tmp_C1_re_fx[3][0] ), Q9 ); // (Q13+Q13) << Q9 = Q22;
    1327             :                                                                                                                 //
    1328             : #else                                                                                                           /* OPT_SBA_DEC_V2_BE */
    1329             :                 re_fx = Mpy_32_32( tmp_C2_re_fx[0][1], tmp_C1_re_fx[1][0] ); // Q22 *Q22 =Q13
    1330             :                 re_fx1 = L_add( ONE_IN_Q13, re_fx );                         // Q13+Q13
    1331             : 
    1332             :                 re_fx = Mpy_32_32( tmp_C2_re_fx[0][2], tmp_C1_re_fx[2][0] ); // Q22 *Q22 =Q13
    1333             :                 re_fx1 = L_add( re_fx1, re_fx );                             // Q13+Q13
    1334             : 
    1335             :                 re_fx = Mpy_32_32( tmp_C2_re_fx[0][3], tmp_C1_re_fx[3][0] ); // Q22 *Q22 =Q13
    1336             :                 tmp_dm_re_fx[0][0] = L_shl( L_add( re_fx1, re_fx ), Q9 );    // (Q13+Q13) << Q9 = Q22;
    1337             : #endif                                                                                                          /* OPT_SBA_DEC_V2_BE */
    1338     1377356 :                 move32();
    1339             : 
    1340     1377356 :                 IF( EQ_16( dyn_active_w_flag, 1 ) )
    1341             :                 {
    1342           0 :                     tmp_dm_re_fx[0][0] = Mpy_32_32( tmp_dm_re_fx[0][0], IVAS_SPAR_DYN_ACTIVEW_THRESH_FX ); // Q22 * Q31 = Q22
    1343           0 :                     move32();
    1344             :                 }
    1345             : 
    1346     1377356 :                 tmp_dm_re_fx[0][1] = tmp_C2_re_fx[0][1]; /*Q22*/
    1347     1377356 :                 move32();
    1348             : 
    1349     1377356 :                 tmp_dm_re_fx[0][2] = tmp_C2_re_fx[0][2]; /*Q22*/
    1350     1377356 :                 move32();
    1351             : 
    1352     1377356 :                 tmp_dm_re_fx[0][3] = tmp_C2_re_fx[0][3]; /*Q22*/
    1353     1377356 :                 move32();
    1354             : 
    1355     1377356 :                 tmp_dm_re_fx[1][0] = tmp_C1_re_fx[1][0]; /*Q22*/
    1356     1377356 :                 move32();
    1357             : 
    1358     1377356 :                 tmp_dm_re_fx[2][0] = tmp_C1_re_fx[2][0]; /*Q22*/
    1359     1377356 :                 move32();
    1360             : 
    1361     1377356 :                 tmp_dm_re_fx[3][0] = tmp_C1_re_fx[3][0]; /*Q22*/
    1362     1377356 :                 move32();
    1363             : 
    1364     1377356 :                 IF( NE_16( hMdDec->spar_md_cfg.remix_unmix_order, 3 ) )
    1365             :                 {
    1366     1377356 :                     ivas_mat_col_rearrange_fx( tmp_dm_re_fx, order, i_ts, hMdDec->mixer_mat_fx, b, numch_out );
    1367             :                 }
    1368             :             }
    1369             :             ELSE
    1370             :             {
    1371     4547360 :                 IF( NE_16( hMdDec->spar_md_cfg.remix_unmix_order, 3 ) )
    1372             :                 {
    1373     4547360 :                     ivas_mat_col_rearrange_fx( tmp_C1_re_fx, order, i_ts, hMdDec->mixer_mat_fx, b, numch_out );
    1374             :                 }
    1375             :             }
    1376     5924716 :             hMdDec->Q_mixer_mat = Q30;
    1377     5924716 :             move16();
    1378     5924716 :             IF( dmx_ch > 0 )
    1379             :             {
    1380             :                 Word32 tmpC_re_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH];
    1381             :                 Word32 tmpP_re_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH];
    1382             : 
    1383    31959460 :                 FOR( j = 0; j < numch_out; j++ )
    1384             :                 {
    1385    26034744 :                     set32_fx( tmpC_re_fx[j], 0, numch_out );
    1386    26034744 :                     set32_fx( tmpP_re_fx[j], 0, numch_out );
    1387             :                 }
    1388             : 
    1389    31959460 :                 FOR( j = 0; j < numch_out; j++ )
    1390             :                 {
    1391    26034744 :                     set32_fx( tmpC_re_fx[j], 0, numch_out );
    1392             :                 }
    1393             : 
    1394    20593280 :                 FOR( k = 0; k < dmx_ch; k++ )
    1395             :                 {
    1396    14668564 :                     tmpC_re_fx[k][k] = ONE_IN_Q22; /*Q22*/
    1397    14668564 :                     move32();
    1398             :                 }
    1399             : 
    1400    17290896 :                 FOR( j = dmx_ch; j < numch_out; j++ )
    1401             :                 {
    1402    24667628 :                     FOR( k = 1; k < dmx_ch; k++ )
    1403             :                     {
    1404    13301448 :                         tmpC_re_fx[j][k] = hMdDec->spar_md.band_coeffs[add( b, i_mult( i_ts, IVAS_MAX_NUM_BANDS ) )].C_re_fx[sub( j, dmx_ch )][k - 1]; // Q22
    1405    13301448 :                         move32();
    1406             :                     }
    1407             :                 }
    1408             : 
    1409    17290896 :                 FOR( j = dmx_ch; j < numch_out; j++ )
    1410             :                 {
    1411    42551496 :                     FOR( k = dmx_ch; k < numch_out; k++ )
    1412             :                     {
    1413             : #ifndef OPT_SBA_DEC_V2_BE
    1414             :                         IF( EQ_16( sub( j, dmx_ch ), sub( k, dmx_ch ) ) )
    1415             : #else  /* OPT_SBA_DEC_V2_BE */
    1416    31185316 :                         IF( EQ_16( j, k ) )
    1417             : #endif /* OPT_SBA_DEC_V2_BE */
    1418             :                         {
    1419    11366180 :                             tmpP_re_fx[j][k] = hMdDec->spar_md.band_coeffs[add( b, i_mult( i_ts, IVAS_MAX_NUM_BANDS ) )].P_re_fx[sub( k, dmx_ch )]; // Q22
    1420    11366180 :                             move32();
    1421             :                         }
    1422             :                         ELSE
    1423             :                         {
    1424    19819136 :                             tmpP_re_fx[j][k] = 0;
    1425    19819136 :                             move32();
    1426             :                         }
    1427             :                     }
    1428             :                 }
    1429             : 
    1430             : 
    1431    26034744 :                 FOR( j = 1; j < numch_out; j++ )
    1432             :                 {
    1433    64596792 :                     FOR( k = dmx_ch; k < numch_out; k++ )
    1434             :                     {
    1435   307305316 :                         FOR( m = 0; m < numch_out; m++ )
    1436             :                         {
    1437   262818552 :                             re_fx = Mpy_32_32( hMdDec->mixer_mat_fx[j][m][( b + ( i_ts * IVAS_MAX_NUM_BANDS ) )], tmpP_re_fx[m][k] );                                                                              // Q30*Q22 = Q21
    1438   262818552 :                             re_fx = L_shl( re_fx, 1 );                                                                                                                                                             /*Q22*/
    1439   262818552 :                             hMdDec->spar_coeffs.P_re_fx[j][k][( ( b * bw ) + ( i_ts * IVAS_MAX_NUM_BANDS ) )] = L_add( hMdDec->spar_coeffs.P_re_fx[j][k][( ( b * bw ) + ( i_ts * IVAS_MAX_NUM_BANDS ) )], re_fx ); /*Q22*/
    1440   262818552 :                             move32();
    1441             :                         }
    1442             :                     }
    1443             :                 }
    1444             : 
    1445             : 
    1446    31959460 :                 FOR( j = 0; j < numch_out; j++ )
    1447             :                 {
    1448    94052520 :                     FOR( k = 0; k < dmx_ch; k++ )
    1449             :                     {
    1450   419015856 :                         FOR( m = 0; m < numch_out; m++ )
    1451             :                         {
    1452   350998080 :                             re_fx = Mpy_32_32( hMdDec->mixer_mat_fx[j][m][( b + ( i_ts * IVAS_MAX_NUM_BANDS ) )], tmpC_re_fx[m][k] );                                                                              // Q30* Q22 = Q21
    1453   350998080 :                             re_fx = L_shl( re_fx, 1 );                                                                                                                                                             /*Q22*/
    1454   350998080 :                             hMdDec->spar_coeffs.C_re_fx[j][k][( ( b * bw ) + ( i_ts * IVAS_MAX_NUM_BANDS ) )] = L_add( hMdDec->spar_coeffs.C_re_fx[j][k][( ( b * bw ) + ( i_ts * IVAS_MAX_NUM_BANDS ) )], re_fx ); /*Q22*/
    1455   350998080 :                             move32();
    1456             :                         }
    1457             :                     }
    1458             :                 }
    1459             : 
    1460    11849432 :                 hMdDec->spar_coeffs.C_re_fx[0][0][( ( b * bw ) + ( i_ts * IVAS_MAX_NUM_BANDS ) )] =
    1461     5924716 :                     L_max( 0, hMdDec->spar_coeffs.C_re_fx[0][0][( ( b * bw ) + ( i_ts * IVAS_MAX_NUM_BANDS ) )] ); /*Q22*/
    1462     5924716 :                 move32();
    1463             :             }
    1464             :         }
    1465             : 
    1466             :         /* band mixing */
    1467      501129 :         IF( EQ_16( bw, IVAS_RED_BAND_FACT ) )
    1468             :         {
    1469           0 :             FOR( b = 0; b < num_bands_out; b = ( b + bw ) )
    1470             :             {
    1471           0 :                 dmx_ch = hMdDec->spar_md_cfg.num_dmx_chans_per_band[b];
    1472           0 :                 move16();
    1473           0 :                 FOR( j = 0; j < numch_out; j++ )
    1474             :                 {
    1475           0 :                     FOR( k = dmx_ch; k < numch_out; k++ )
    1476             :                     {
    1477           0 :                         hMdDec->spar_coeffs.P_re_fx[j][k][( ( b + 1 ) + ( i_ts * IVAS_MAX_NUM_BANDS ) )] = hMdDec->spar_coeffs.P_re_fx[j][k][( b + ( i_ts * IVAS_MAX_NUM_BANDS ) )]; /*Q22*/
    1478           0 :                         move32();
    1479             :                     }
    1480             :                 }
    1481             : 
    1482           0 :                 FOR( j = 0; j < numch_out; j++ )
    1483             :                 {
    1484           0 :                     FOR( k = 0; k < dmx_ch; k++ )
    1485             :                     {
    1486           0 :                         hMdDec->spar_coeffs.C_re_fx[j][k][( ( b + 1 ) + ( i_ts * IVAS_MAX_NUM_BANDS ) )] = hMdDec->spar_coeffs.C_re_fx[j][k][( b + ( i_ts * IVAS_MAX_NUM_BANDS ) )]; /*Q22*/
    1487           0 :                         move32();
    1488             :                     }
    1489             :                 }
    1490             :             }
    1491             :         }
    1492             :     }
    1493             : 
    1494      140904 :     return;
    1495             : }
    1496             : 
    1497             : /*-----------------------------------------------------------------------------------------*
    1498             :  * Function ivas_mat_col_rearrange()
    1499             :  *
    1500             :  * reorders the input matrix based on order
    1501             :  *-----------------------------------------------------------------------------------------*/
    1502             : 
    1503     5924716 : static void ivas_mat_col_rearrange_fx(
    1504             :     Word32 in_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /*Q22*/
    1505             :     const Word16 order[IVAS_SPAR_MAX_CH],             /*Q0*/
    1506             :     const Word16 i_ts,                                /*Q0*/
    1507             :     Word32 ***mixer_mat,                              /*Q30*/
    1508             :     const Word16 bands,                               /*Q0*/
    1509             :     const Word16 num_ch /*Q0*/ )
    1510             : {
    1511             :     Word16 i, j, idx;
    1512             : 
    1513    31959460 :     FOR( i = 0; i < num_ch; i++ )
    1514             :     {
    1515    26034744 :         idx = order[i]; /*Q0*/
    1516    26034744 :         move16();
    1517             : 
    1518   149905464 :         FOR( j = 0; j < num_ch; j++ )
    1519             :         {
    1520   123870720 :             mixer_mat[j][i][( bands + ( i_ts * IVAS_MAX_NUM_BANDS ) )] = L_shl_sat( in_re[j][idx], Q8 ); /*Q30*/
    1521   123870720 :             move32();
    1522             :         }
    1523             :     }
    1524             : 
    1525     5924716 :     return;
    1526             : }
    1527             : 
    1528             : /*-----------------------------------------------------------------------------------------*
    1529             :  * Function ivas_spar_dec_gen_umx_mat()
    1530             :  *
    1531             :  * generates upmix matrix
    1532             :  *-----------------------------------------------------------------------------------------*/
    1533      182441 : void ivas_spar_dec_gen_umx_mat_fx(
    1534             :     ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle        */
    1535             :     const Word16 nchan_transport,     /* i  : number of transport channels  Q0*/
    1536             :     const Word16 num_bands_out,       /* i  : number of output bands        Q0*/
    1537             :     const Word16 bfi,                 /* i  : bad frame indicator           Q0*/
    1538             :     const Word16 num_md_sub_frames /*Q0*/ )
    1539             : {
    1540             :     Word16 i, j, b, i_ts, num_out_ch;
    1541      182441 :     num_out_ch = hMdDec->spar_md_cfg.num_umx_chs;
    1542      182441 :     move16();
    1543      837784 :     FOR( i_ts = 0; i_ts < num_md_sub_frames; i_ts++ )
    1544             :     {
    1545      655343 :         IF( EQ_16( hMdDec->td_decorr_flag, 1 ) )
    1546             :         {
    1547     3462119 :             FOR( i = 0; i < num_out_ch; i++ )
    1548             :             {
    1549     9466884 :                 FOR( j = 0; j < nchan_transport; j++ )
    1550             :                 {
    1551    85693404 :                     FOR( b = 0; b < num_bands_out; b++ )
    1552             :                     {
    1553    79033296 :                         hMdDec->mixer_mat_fx[i][j][( b + ( i_ts * IVAS_MAX_NUM_BANDS ) )] = L_shl_sat( hMdDec->spar_coeffs.C_re_fx[i][j][( b + ( i_ts * IVAS_MAX_NUM_BANDS ) )], Q8 ); /*Q30*/
    1554    79033296 :                         move32();
    1555             :                     }
    1556             :                 }
    1557             :             }
    1558     3462119 :             FOR( i = 0; i < num_out_ch; i++ )
    1559             :             {
    1560     8955924 :                 FOR( j = nchan_transport; j < num_out_ch; j++ )
    1561             :                 {
    1562    79034924 :                     FOR( b = 0; b < num_bands_out; b++ )
    1563             :                     {
    1564    72885776 :                         hMdDec->mixer_mat_fx[i][j][( b + ( i_ts * IVAS_MAX_NUM_BANDS ) )] = L_shl_sat( hMdDec->spar_coeffs.P_re_fx[i][j][( b + ( i_ts * IVAS_MAX_NUM_BANDS ) )], Q8 ); /*Q30*/
    1565    72885776 :                         move32();
    1566             :                     }
    1567             :                 }
    1568             :             }
    1569             :         }
    1570             :         ELSE
    1571             :         {
    1572           0 :             FOR( i = 0; i < num_out_ch; i++ )
    1573             :             {
    1574           0 :                 FOR( j = 0; j < nchan_transport; j++ )
    1575             :                 {
    1576           0 :                     FOR( b = 0; b < num_bands_out; b++ )
    1577             :                     {
    1578           0 :                         hMdDec->mixer_mat_fx[i][j][( b + ( i_ts * IVAS_MAX_NUM_BANDS ) )] = L_shl_sat( hMdDec->spar_coeffs.C_re_fx[i][j][( b + ( i_ts * IVAS_MAX_NUM_BANDS ) )], Q8 ); /*Q30*/
    1579           0 :                         move32();
    1580             :                     }
    1581             :                 }
    1582             :             }
    1583             :         }
    1584             :     }
    1585      182441 :     hMdDec->Q_mixer_mat = Q30;
    1586      182441 :     move16();
    1587      182441 :     ivas_spar_dec_compute_ramp_down_post_matrix_fx( hMdDec, num_bands_out, bfi, num_md_sub_frames );
    1588      182441 :     return;
    1589             : }
    1590             : 
    1591       11500 : static void ivas_spar_md_band_upmix(
    1592             :     ivas_band_coeffs_t *band_coeffs,
    1593             :     Word16 *nB,          /*Q0*/
    1594             :     Word16 *bands_bw,    /*Q0*/
    1595             :     Word16 *valid_bands, /*Q0*/
    1596             :     Word16 bw_final,     /*Q0*/
    1597             :     Word16 ndec,         /*Q0*/
    1598             :     Word16 ndm /*Q0*/ )
    1599             : {
    1600             :     Word16 i, ii, jj, b, idx, bw_fact;
    1601             : 
    1602       11500 :     bw_fact = idiv1616( *bands_bw, bw_final ); /*Q0*/
    1603       56386 :     FOR( i = sub( *nB, 1 ); i >= 0; i-- )
    1604             :     {
    1605             : 
    1606      136886 :         FOR( b = sub( bw_fact, 1 ); b >= 0; b-- )
    1607             :         {
    1608       92000 :             idx = add( i_mult( i, bw_fact ), b ); /*Q0*/
    1609      368000 :             FOR( ii = 0; ii < ( ( ndec + ndm ) - 1 ); ii++ )
    1610             :             {
    1611      276000 :                 band_coeffs[idx].pred_re_fx[ii] = band_coeffs[i].pred_re_fx[ii]; /*Q22*/
    1612      276000 :                 move32();
    1613             :             }
    1614      365456 :             FOR( ii = 0; ii < ndec; ii++ )
    1615             :             {
    1616      278544 :                 FOR( jj = 0; jj < sub( ndm, 1 ); jj++ )
    1617             :                 {
    1618        5088 :                     band_coeffs[idx].C_re_fx[ii][jj] = band_coeffs[i].C_re_fx[ii][jj]; /*Q22*/
    1619        5088 :                     move32();
    1620             :                 }
    1621             :             }
    1622      365456 :             FOR( jj = 0; jj < ndec; jj++ )
    1623             :             {
    1624      273456 :                 band_coeffs[idx].P_re_fx[jj] = band_coeffs[i].P_re_fx[jj]; /*Q22*/
    1625      273456 :                 move32();
    1626             :             }
    1627       92000 :             valid_bands[idx] = valid_bands[i]; /*Q0*/
    1628       92000 :             move16();
    1629             :         }
    1630             :     }
    1631       11500 :     *nB = idiv1616( i_mult( ( *nB ), ( *bands_bw ) ), bw_final ); /*Q0*/
    1632       11500 :     move16();
    1633       11500 :     *bands_bw = bw_final; /*Q0*/
    1634       11500 :     move16();
    1635             : 
    1636       11500 :     return;
    1637             : }
    1638             : 
    1639             : /*-----------------------------------------------------------------------------------------*
    1640             :  * Function ivas_spar_dec_parse_md_bs()
    1641             :  *
    1642             :  * Parse SPAR MD bitstream
    1643             :  *-----------------------------------------------------------------------------------------*/
    1644             : 
    1645      140904 : static void ivas_spar_dec_parse_md_bs_fx(
    1646             :     ivas_spar_md_dec_state_t *hMdDec,
    1647             :     Decoder_State *st0,
    1648             :     Word16 *nB,                    /*Q0*/
    1649             :     Word16 *bands_bw,              /*Q0*/
    1650             :     Word16 *dtx_vad,               /*Q0*/
    1651             :     const Word32 ivas_total_brate, /*Q0*/
    1652             :     const Word16 sba_inactive_mode /*Q0*/ )
    1653             : {
    1654             :     Word16 i, j, k, num_bands;
    1655             :     Word16 ii, jj, ndec, ndm;
    1656             :     UWord16 qsi;
    1657             :     ivas_quant_strat_t qs;
    1658             :     Word16 strat, no_ec;
    1659             :     Word16 do_diff[IVAS_MAX_NUM_BANDS];
    1660             :     Word32 quant_fx[IVAS_SPAR_MAX_C_COEFF];
    1661             :     Word16 do_repeat[IVAS_MAX_NUM_BANDS];
    1662      140904 :     *dtx_vad = 1;
    1663      140904 :     move16();
    1664      140904 :     *bands_bw = 1;
    1665      140904 :     move16();
    1666      140904 :     qsi = 0;
    1667      140904 :     move16();
    1668      140904 :     num_bands = hMdDec->spar_md.num_bands;
    1669      140904 :     move16();
    1670             : 
    1671      140904 :     IF( GT_32( ivas_total_brate, IVAS_SID_5k2 ) )
    1672             :     {
    1673      140580 :         IF( hMdDec->spar_md_cfg.quant_strat_bits > 0 )
    1674             :         {
    1675      140580 :             IF( GE_32( ivas_total_brate, BRATE_SPAR_Q_STRAT ) )
    1676             :             {
    1677             :                 /*only one bit written for quantization strategy to indicate either a fixed quantization strategy or dtx_vad==0 */
    1678       36993 :                 qsi = get_next_indice_fx( st0, 1 ); /*Q0*/
    1679       36993 :                 if ( EQ_32( qsi, 1 ) )
    1680             :                 {
    1681           0 :                     *dtx_vad = 0;
    1682           0 :                     move16();
    1683             :                 }
    1684             :             }
    1685             :             ELSE
    1686             :             {
    1687      103587 :                 IF( EQ_16( sba_inactive_mode, 1 ) )
    1688             :                 {
    1689         233 :                     *dtx_vad = 0;
    1690         233 :                     move16();
    1691         233 :                     qsi = add( hMdDec->spar_md_cfg.quant_strat_bits, 1 );
    1692             :                 }
    1693             :                 ELSE
    1694             :                 {
    1695      103354 :                     qsi = get_next_indice_fx( st0, hMdDec->spar_md_cfg.quant_strat_bits );
    1696             :                 }
    1697             :             }
    1698             :         }
    1699             :         ELSE
    1700             :         {
    1701           0 :             qsi = 0;
    1702           0 :             move16();
    1703             :         }
    1704             :     }
    1705             :     ELSE
    1706             :     {
    1707         324 :         *dtx_vad = 0;
    1708         324 :         move16();
    1709             :     }
    1710             : 
    1711      140904 :     hMdDec->dtx_vad = *dtx_vad; /*Q0*/
    1712      140904 :     move16();
    1713             : 
    1714      140904 :     IF( *dtx_vad == 0 )
    1715             :     {
    1716         557 :         *nB = SPAR_DTX_BANDS;
    1717         557 :         move16();
    1718         557 :         *bands_bw = idiv1616( num_bands, *nB ); /*Q0*/
    1719         557 :         move16();
    1720             : 
    1721        1671 :         FOR( i = 0; i < *nB; i++ )
    1722             :         {
    1723       12254 :             FOR( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ )
    1724             :             {
    1725       11140 :                 hMdDec->spar_md.band_coeffs[i].pred_re_fx[j] = 0;
    1726       11140 :                 move32();
    1727       11140 :                 hMdDec->spar_md.band_coeffs[i].P_re_fx[j] = 0;
    1728       11140 :                 move32();
    1729             :             }
    1730        1114 :             hMdDec->valid_bands[i] = 1;
    1731        1114 :             move16();
    1732             :         }
    1733             : 
    1734        5013 :         FOR( i = 0; i < num_bands; i++ )
    1735             :         {
    1736       35648 :             FOR( j = 0; j < ( IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS ); j++ )
    1737             :             {
    1738      124768 :                 FOR( k = 0; k < ( IVAS_SPAR_MAX_DMX_CHS - 1 ); k++ )
    1739             :                 {
    1740       93576 :                     hMdDec->spar_md.band_coeffs[i].C_re_fx[j][k] = 0;
    1741       93576 :                     move32();
    1742             :                 }
    1743             :             }
    1744             :         }
    1745             : 
    1746         557 :         ivas_parse_parameter_bitstream_dtx( &hMdDec->spar_md, st0, *bands_bw, *nB, hMdDec->spar_md_cfg.num_dmx_chans_per_band, hMdDec->spar_md_cfg.num_decorr_per_band );
    1747             : 
    1748         557 :         IF( NE_16( *bands_bw, 1 ) )
    1749             :         {
    1750         557 :             ndec = hMdDec->spar_md_cfg.num_decorr_per_band[0]; /*Q0*/
    1751         557 :             move16();
    1752         557 :             ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[0]; /*Q0*/
    1753         557 :             move16();
    1754         557 :             ivas_spar_md_band_upmix(
    1755             :                 hMdDec->spar_md.band_coeffs,
    1756             :                 nB,
    1757             :                 bands_bw,
    1758         557 :                 hMdDec->valid_bands,
    1759             :                 1,
    1760             :                 ndec,
    1761             :                 ndm );
    1762             :         }
    1763             : 
    1764         557 :         return;
    1765             :     }
    1766             : 
    1767      140347 :     qs = hMdDec->spar_md_cfg.quant_strat[qsi];
    1768             : 
    1769      140347 :     strat = get_next_indice_fx( st0, 3 ); /*Q0*/
    1770             : 
    1771      140347 :     no_ec = 0;
    1772      140347 :     move16();
    1773             : 
    1774      140347 :     IF( LT_16( strat, 2 ) )
    1775             :     {
    1776       52471 :         *bands_bw = add( strat, 1 );
    1777       52471 :         move16();
    1778       52471 :         *nB = idiv1616( num_bands, *bands_bw ); /*Q0*/
    1779       52471 :         move16();
    1780      554399 :         FOR( i = 0; i < *nB; i++ )
    1781             :         {
    1782      501928 :             do_diff[i] = 0;
    1783      501928 :             move16();
    1784      501928 :             do_repeat[i] = 0;
    1785      501928 :             move16();
    1786             :         }
    1787             :     }
    1788       87876 :     ELSE IF( LT_16( strat, 4 ) )
    1789             :     {
    1790        2634 :         *bands_bw = sub( strat, 1 );
    1791        2634 :         move16();
    1792        2634 :         *nB = idiv1616( num_bands, *bands_bw ); /*Q0*/
    1793        2634 :         move16();
    1794       23378 :         FOR( i = 0; i < *nB; i++ )
    1795             :         {
    1796       20744 :             do_diff[i] = 0;
    1797       20744 :             move16();
    1798       20744 :             do_repeat[i] = 0;
    1799       20744 :             move16();
    1800             :         }
    1801        2634 :         no_ec = 1;
    1802        2634 :         move16();
    1803             :     }
    1804       85242 :     ELSE IF( LT_32( ivas_total_brate, IVAS_24k4 ) )
    1805             :     {
    1806       10588 :         *bands_bw = 2;
    1807       10588 :         move16();
    1808       10588 :         *nB = idiv1616( num_bands, *bands_bw ); /*Q0*/
    1809       10588 :         move16();
    1810             : 
    1811       52940 :         FOR( i = 0; i < *nB; i++ )
    1812             :         {
    1813       42352 :             do_diff[i] = 0;
    1814       42352 :             move16();
    1815       42352 :             do_repeat[i] = extract_l( EQ_16( ( strat % 2 ), ( add( i, 1 ) % 2 ) ) ); /*Q0*/
    1816       42352 :             move16();
    1817             :         }
    1818             :     }
    1819             :     ELSE
    1820             :     {
    1821       74654 :         *bands_bw = 1;
    1822       74654 :         move16();
    1823       74654 :         *nB = num_bands;
    1824       74654 :         move16();
    1825             : 
    1826      671886 :         FOR( i = 0; i < *nB; i++ )
    1827             :         {
    1828      597232 :             do_diff[i] = extract_l( NE_16( s_and( add( i, 1 ), 3 ), sub( strat, 4 ) ) ); /*Q0*/
    1829      597232 :             move16();
    1830      597232 :             do_repeat[i] = 0;
    1831      597232 :             move16();
    1832             :         }
    1833       74654 :         IF( hMdDec->spar_md_cfg.prev_quant_idx >= 0 )
    1834             :         {
    1835       74647 :             ivas_map_prior_coeffs_quant( &hMdDec->spar_md_prev, &hMdDec->spar_md_cfg, qsi, *nB );
    1836             :         }
    1837             :     }
    1838      140347 :     hMdDec->spar_md_cfg.prev_quant_idx = qsi;
    1839      140347 :     move16();
    1840             : 
    1841      140347 :     IF( no_ec == 0 )
    1842             :     {
    1843      137713 :         ivas_decode_arith_bs( hMdDec, st0, qsi, *nB, *bands_bw, do_diff, strat, ivas_total_brate );
    1844             :     }
    1845             :     ELSE
    1846             :     {
    1847        2634 :         ivas_decode_huffman_bs( hMdDec, st0, qsi, *nB, *bands_bw );
    1848             :     }
    1849             : 
    1850     1302603 :     FOR( i = 0; i < *nB; i++ )
    1851             :     {
    1852     1162256 :         ndec = hMdDec->spar_md_cfg.num_decorr_per_band[( ( *bands_bw ) * i )]; /*Q0*/
    1853     1162256 :         move16();
    1854     1162256 :         ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[( ( *bands_bw ) * i )]; /*Q0*/
    1855     1162256 :         move16();
    1856             : 
    1857     1162256 :         ivas_deindex_real_index_fx( hMdDec->spar_md.band_coeffs_idx[i].pred_index_re, qs.PR.q_levels[0], qs.PR.min_fx, qs.PR.max_fx, hMdDec->spar_md.band_coeffs[i].pred_re_fx, sub( add( ndm, ndec ), 1 ) );
    1858             : 
    1859     1162256 :         j = 0;
    1860     1162256 :         move16();
    1861     3918164 :         FOR( ii = 0; ii < ndec; ii++ )
    1862             :         {
    1863     7321892 :             FOR( jj = 0; jj < sub( ndm, 1 ); jj++ )
    1864             :             {
    1865     4565984 :                 quant_fx[j] = hMdDec->spar_md.band_coeffs[i].C_re_fx[ii][jj]; /*Q22*/
    1866     4565984 :                 move32();
    1867     4565984 :                 j = add( j, 1 );
    1868             :             }
    1869             :         }
    1870             : 
    1871     1162256 :         ivas_deindex_real_index_fx( hMdDec->spar_md.band_coeffs_idx[i].drct_index_re, qs.C.q_levels[0], qs.C.min_fx, qs.C.max_fx, quant_fx, i_mult( ndec, sub( ndm, 1 ) ) );
    1872             : 
    1873     1162256 :         j = 0;
    1874     1162256 :         move16();
    1875     3918164 :         FOR( ii = 0; ii < ndec; ii++ )
    1876             :         {
    1877     7321892 :             FOR( jj = 0; jj < sub( ndm, 1 ); jj++ )
    1878             :             {
    1879     4565984 :                 hMdDec->spar_md.band_coeffs[i].C_re_fx[ii][jj] = quant_fx[j]; /*Q22*/
    1880     4565984 :                 move32();
    1881     4565984 :                 j = add( j, 1 );
    1882             :             }
    1883             :         }
    1884             : 
    1885     1162256 :         ivas_deindex_real_index_fx( hMdDec->spar_md.band_coeffs_idx[i].decd_index_re, qs.P_r.q_levels[0], qs.P_r.min_fx, qs.P_r.max_fx, hMdDec->spar_md.band_coeffs[i].P_re_fx, sub( add( ndm, ndec ), 1 ) );
    1886             : 
    1887             :         /* Store prior coefficient indices */
    1888     5819024 :         FOR( j = 0; j < ( ( ndm + ndec ) - 1 ); j++ )
    1889             :         {
    1890     4656768 :             hMdDec->spar_md_prev.band_coeffs_idx[i].pred_index_re[j] = hMdDec->spar_md.band_coeffs_idx[i].pred_index_re[j]; /*Q0*/
    1891     4656768 :             move16();
    1892             :         }
    1893     5728240 :         FOR( j = 0; j < ( ndec * ( ndm - 1 ) ); j++ )
    1894             :         {
    1895     4565984 :             hMdDec->spar_md_prev.band_coeffs_idx[i].drct_index_re[j] = hMdDec->spar_md.band_coeffs_idx[i].drct_index_re[j]; /*Q0*/
    1896     4565984 :             move16();
    1897             :         }
    1898     3918164 :         FOR( j = 0; j < ndec; j++ )
    1899             :         {
    1900     2755908 :             hMdDec->spar_md_prev.band_coeffs_idx[i].decd_index_re[j] = hMdDec->spar_md.band_coeffs_idx[i].decd_index_re[j]; /*Q0*/
    1901     2755908 :             move16();
    1902             :         }
    1903     1162256 :         test();
    1904     1162256 :         IF( ( do_diff[i] == 0 ) && ( do_repeat[i] == 0 ) )
    1905             :         {
    1906      693156 :             hMdDec->valid_bands[i] = s_or( hMdDec->valid_bands[i], 1 );
    1907      693156 :             move16();
    1908             :         }
    1909             :         ELSE
    1910             :         {
    1911      469100 :             hMdDec->valid_bands[i] = s_or( hMdDec->valid_bands[i], 0 );
    1912      469100 :             move16();
    1913             :         }
    1914             :     }
    1915             : 
    1916      140347 :     ndec = hMdDec->spar_md_cfg.num_decorr_per_band[0];
    1917      140347 :     move16();
    1918      140347 :     ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[0];
    1919      140347 :     move16();
    1920      140347 :     IF( NE_16( *bands_bw, 1 ) )
    1921             :     {
    1922       10943 :         ivas_spar_md_band_upmix(
    1923             :             hMdDec->spar_md.band_coeffs,
    1924             :             nB,
    1925             :             bands_bw,
    1926       10943 :             hMdDec->valid_bands,
    1927             :             1,
    1928             :             ndec,
    1929             :             ndm );
    1930             :     }
    1931             : 
    1932             : 
    1933      140347 :     return;
    1934             : }
    1935             : 
    1936             : 
    1937             : /*-----------------------------------------------------------------------------------------*
    1938             :  * Function ivas_decode_arith_bs()
    1939             :  *
    1940             :  * Decode bitstream with arith decoder
    1941             :  *-----------------------------------------------------------------------------------------*/
    1942             : 
    1943      137713 : static void ivas_decode_arith_bs(
    1944             :     ivas_spar_md_dec_state_t *hMdDec,
    1945             :     Decoder_State *st0,    /* i/o: decoder state structure - for bitstream handling*/
    1946             :     const UWord16 qsi,     /*Q0*/
    1947             :     const Word16 nB,       /*Q0*/
    1948             :     const Word16 bands_bw, /*Q0*/
    1949             :     Word16 *pDo_diff,      /*Q0*/
    1950             :     const Word16 strat,    /*Q0*/
    1951             :     const Word32 ivas_total_brate /*Q0*/ )
    1952             : {
    1953             :     Word16 i, ndm, ndec;
    1954             :     Word16 j;
    1955             :     ivas_cell_dim_t pred_cell_dims[IVAS_MAX_NUM_BANDS];
    1956             :     ivas_cell_dim_t drct_cell_dims[IVAS_MAX_NUM_BANDS];
    1957             :     ivas_cell_dim_t decd_cell_dims[IVAS_MAX_NUM_BANDS];
    1958             :     ivas_cell_dim_t decx_cell_dims[IVAS_MAX_NUM_BANDS];
    1959             :     Word16 symbol_arr_re[IVAS_MAX_INPUT_LEN];
    1960             :     Word16 symbol_arr_old_re[IVAS_MAX_INPUT_LEN];
    1961             :     Word16 any_diff;
    1962             : 
    1963     1279225 :     FOR( i = 0; i < nB; i++ )
    1964             :     {
    1965     1141512 :         ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[bands_bw * i];
    1966     1141512 :         ndec = hMdDec->spar_md_cfg.num_decorr_per_band[bands_bw * i];
    1967     1141512 :         move16();
    1968     1141512 :         move16();
    1969     1141512 :         test();
    1970     1141512 :         test();
    1971     1141512 :         test();
    1972     1141512 :         test();
    1973     1141512 :         test();
    1974     1141512 :         IF( LT_32( ivas_total_brate, IVAS_24k4 ) && GT_16( strat, 3 ) && ( ( EQ_16( i % 2, 1 ) && ( strat % 2 == 0 ) ) || ( ( i % 2 == 0 ) && EQ_16( strat % 2, 1 ) ) ) )
    1975             :         {
    1976       21176 :             pred_cell_dims[i].dim1 = 0;
    1977       21176 :             pred_cell_dims[i].dim2 = 0;
    1978       21176 :             drct_cell_dims[i].dim1 = 0;
    1979       21176 :             drct_cell_dims[i].dim2 = 0;
    1980       21176 :             decd_cell_dims[i].dim1 = 0;
    1981       21176 :             decd_cell_dims[i].dim2 = 0;
    1982       21176 :             decx_cell_dims[i].dim1 = 0;
    1983       21176 :             decx_cell_dims[i].dim2 = 0;
    1984       21176 :             move16();
    1985       21176 :             move16();
    1986       21176 :             move16();
    1987       21176 :             move16();
    1988       21176 :             move16();
    1989       21176 :             move16();
    1990       21176 :             move16();
    1991       21176 :             move16();
    1992             :         }
    1993             :         ELSE
    1994             :         {
    1995     1120336 :             pred_cell_dims[i].dim1 = add( ndm, sub( ndec, 1 ) ); /*Q0*/
    1996     1120336 :             move16();
    1997     1120336 :             IF( hMdDec->spar_hoa_md_flag && hMdDec->spar_hoa_dirac2spar_md_flag )
    1998             :             {
    1999      131388 :                 IF( GE_16( i, SPAR_DIRAC_SPLIT_START_BAND ) )
    2000             :                 {
    2001       43796 :                     pred_cell_dims[i].dim1 = sub( pred_cell_dims[i].dim1, ( FOA_CHANNELS - 1 ) );
    2002       43796 :                     move16();
    2003             :                 }
    2004             :             }
    2005     1120336 :             pred_cell_dims[i].dim2 = 1;
    2006     1120336 :             drct_cell_dims[i].dim1 = ndec;
    2007     1120336 :             drct_cell_dims[i].dim2 = sub( ndm, 1 );
    2008     1120336 :             decd_cell_dims[i].dim1 = ndec;
    2009     1120336 :             decd_cell_dims[i].dim2 = 1;
    2010     1120336 :             decx_cell_dims[i].dim1 = shr( imult1616( ndec, sub( ndec, 1 ) ), 1 );
    2011     1120336 :             decx_cell_dims[i].dim2 = 1;
    2012     1120336 :             move16();
    2013     1120336 :             move16();
    2014     1120336 :             move16();
    2015     1120336 :             move16();
    2016     1120336 :             move16();
    2017     1120336 :             move16();
    2018     1120336 :             move16();
    2019             :         }
    2020             :     }
    2021             : 
    2022      137713 :     any_diff = 0;
    2023      137713 :     move16();
    2024      700743 :     FOR( i = 0; i < nB; i++ )
    2025             :     {
    2026      637684 :         IF( pDo_diff[i] != 0 )
    2027             :         {
    2028       74654 :             any_diff = 1;
    2029       74654 :             move16();
    2030       74654 :             break;
    2031             :         }
    2032             :     }
    2033             : 
    2034      137713 :     IF( EQ_16( any_diff, 1 ) )
    2035             :     {
    2036       74654 :         IF( hMdDec->spar_hoa_md_flag && hMdDec->spar_hoa_dirac2spar_md_flag )
    2037             :         {
    2038           0 :             FOR( i = 0; i < nB; i++ )
    2039             :             {
    2040           0 :                 IF( GE_16( i, SPAR_DIRAC_SPLIT_START_BAND ) )
    2041             :                 {
    2042           0 :                     FOR( j = 0; j < pred_cell_dims[i].dim1; j++ )
    2043             :                     {
    2044           0 :                         hMdDec->spar_md_prev.band_coeffs_idx_mapped[i].pred_index_re[j] =
    2045           0 :                             hMdDec->spar_md_prev.band_coeffs_idx_mapped[i].pred_index_re[j + ( FOA_CHANNELS - 1 )]; /*Q0*/
    2046           0 :                         move16();
    2047             :                     }
    2048             :                 }
    2049             :             }
    2050             :         }
    2051             : 
    2052       74654 :         ivas_copy_band_coeffs_idx_to_arr( hMdDec->spar_md_prev.band_coeffs_idx_mapped, nB, symbol_arr_old_re, pred_cell_dims, PRED_COEFF );
    2053             :     }
    2054             : 
    2055      137713 :     ivas_arith_decode_cmplx_cell_array( &hMdDec->arith_coeffs.pred_arith_re[qsi], &hMdDec->arith_coeffs.pred_arith_re_diff[qsi],
    2056             :                                         st0, pred_cell_dims, pDo_diff, nB, symbol_arr_re, symbol_arr_old_re );
    2057             : 
    2058      137713 :     ivas_fill_band_coeffs_idx( hMdDec->spar_md.band_coeffs_idx, nB, symbol_arr_re, pred_cell_dims, PRED_COEFF );
    2059             : 
    2060      137713 :     IF( hMdDec->spar_hoa_md_flag && hMdDec->spar_hoa_dirac2spar_md_flag )
    2061             :     {
    2062      142337 :         FOR( i = 0; i < nB; i++ )
    2063             :         {
    2064      131388 :             IF( GE_16( i, SPAR_DIRAC_SPLIT_START_BAND ) )
    2065             :             {
    2066      175116 :                 FOR( j = pred_cell_dims[i].dim1 - 1; j >= 0; j-- )
    2067             :                 {
    2068      131320 :                     hMdDec->spar_md.band_coeffs_idx[i].pred_index_re[j + ( FOA_CHANNELS - 1 )] =
    2069      131320 :                         hMdDec->spar_md.band_coeffs_idx[i].pred_index_re[j]; /*Q0*/
    2070      131320 :                     move16();
    2071             :                 }
    2072      175184 :                 FOR( j = 0; j < FOA_CHANNELS - 1; j++ )
    2073             :                 {
    2074      131388 :                     hMdDec->spar_md.band_coeffs_idx[i].pred_index_re[j] = 0;
    2075      131388 :                     move16();
    2076             :                 }
    2077             :             }
    2078             :         }
    2079             :     }
    2080             : 
    2081      137713 :     IF( EQ_16( any_diff, 1 ) )
    2082             :     {
    2083       74654 :         ivas_copy_band_coeffs_idx_to_arr( hMdDec->spar_md_prev.band_coeffs_idx_mapped, nB, symbol_arr_old_re, drct_cell_dims, DRCT_COEFF );
    2084             :     }
    2085             : 
    2086      137713 :     ivas_arith_decode_cmplx_cell_array( &hMdDec->arith_coeffs.drct_arith_re[qsi], &hMdDec->arith_coeffs.drct_arith_re_diff[qsi],
    2087             :                                         st0, drct_cell_dims, pDo_diff, nB, symbol_arr_re, symbol_arr_old_re );
    2088             : 
    2089      137713 :     ivas_fill_band_coeffs_idx( hMdDec->spar_md.band_coeffs_idx, nB, symbol_arr_re, drct_cell_dims, DRCT_COEFF );
    2090             : 
    2091      137713 :     IF( EQ_16( any_diff, 1 ) )
    2092             :     {
    2093       74654 :         ivas_copy_band_coeffs_idx_to_arr( hMdDec->spar_md_prev.band_coeffs_idx_mapped, nB, symbol_arr_old_re, decd_cell_dims, DECD_COEFF );
    2094             :     }
    2095             : 
    2096      137713 :     ivas_arith_decode_cmplx_cell_array( &hMdDec->arith_coeffs.decd_arith_re[qsi], &hMdDec->arith_coeffs.decd_arith_re_diff[qsi],
    2097             :                                         st0, decd_cell_dims, pDo_diff, nB, symbol_arr_re, symbol_arr_old_re );
    2098             : 
    2099      137713 :     ivas_fill_band_coeffs_idx( hMdDec->spar_md.band_coeffs_idx, nB, symbol_arr_re, decd_cell_dims, DECD_COEFF );
    2100             : 
    2101      137713 :     IF( EQ_16( any_diff, 1 ) )
    2102             :     {
    2103       74654 :         ivas_copy_band_coeffs_idx_to_arr( hMdDec->spar_md_prev.band_coeffs_idx_mapped, nB, symbol_arr_old_re, decx_cell_dims, DECX_COEFF );
    2104             :     }
    2105             : 
    2106      137713 :     ivas_fill_band_coeffs_idx( hMdDec->spar_md.band_coeffs_idx, nB, symbol_arr_re, decx_cell_dims, DECX_COEFF );
    2107             : 
    2108      137713 :     return;
    2109             : }
    2110             : 
    2111             : /*-----------------------------------------------------------------------------------------*
    2112             :  * Function ivas_fill_band_coeffs_idx()
    2113             :  *
    2114             :  * Copy pred band coeffs to arr
    2115             :  *-----------------------------------------------------------------------------------------*/
    2116             : 
    2117      550852 : static void ivas_fill_band_coeffs_idx(
    2118             :     ivas_band_coeffs_ind_t *pBands_idx,
    2119             :     const Word16 nB,    /*Q0*/
    2120             :     Word16 *pSymbol_re, /*Q0*/
    2121             :     ivas_cell_dim_t *pCell_dims,
    2122             :     const ivas_coeffs_type_t coeff_type )
    2123             : {
    2124             :     Word16 i, len;
    2125      550852 :     Word16 *pPtr_idx = NULL;
    2126             : 
    2127     5116900 :     FOR( i = 0; i < nB; i++ )
    2128             :     {
    2129     4566048 :         SWITCH( coeff_type )
    2130             :         {
    2131     1141512 :             case PRED_COEFF:
    2132             :             {
    2133     1141512 :                 pPtr_idx = pBands_idx[i].pred_index_re;
    2134     1141512 :                 BREAK;
    2135             :             }
    2136     1141512 :             case DRCT_COEFF:
    2137             :             {
    2138     1141512 :                 pPtr_idx = pBands_idx[i].drct_index_re;
    2139     1141512 :                 BREAK;
    2140             :             }
    2141     1141512 :             case DECD_COEFF:
    2142             :             {
    2143     1141512 :                 pPtr_idx = pBands_idx[i].decd_index_re;
    2144     1141512 :                 BREAK;
    2145             :             }
    2146     1141512 :             case DECX_COEFF:
    2147             :             {
    2148     1141512 :                 BREAK;
    2149             :             }
    2150             : 
    2151           0 :             default:
    2152           0 :                 assert( !"unsupported config!" );
    2153             :         }
    2154             : 
    2155     4566048 :         IF( NE_16( coeff_type, DECX_COEFF ) )
    2156             :         {
    2157     3424536 :             len = imult1616( pCell_dims[i].dim1, pCell_dims[i].dim2 ); /*Q0*/
    2158     3424536 :             Copy( pSymbol_re, pPtr_idx, len );                         /*Q0*/
    2159     3424536 :             pSymbol_re += len;
    2160             :         }
    2161             :     }
    2162             : 
    2163      550852 :     return;
    2164             : }
    2165             : 
    2166             : 
    2167             : /*-----------------------------------------------------------------------------------------*
    2168             :  * Function ivas_decode_huffman_bs()
    2169             :  *
    2170             :  * Decode bitstream with huffman decoder
    2171             :  *-----------------------------------------------------------------------------------------*/
    2172             : 
    2173        2634 : static void ivas_decode_huffman_bs(
    2174             :     ivas_spar_md_dec_state_t *hMdDec,
    2175             :     Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/
    2176             :     const UWord16 qsi,  /*Q0*/
    2177             :     const Word16 nB,    /*Q0*/
    2178             :     const Word16 bands_bw /*Q0*/ )
    2179             : {
    2180             :     Word16 i, j;
    2181             :     Word16 ndm, ndec;
    2182             :     Word16 pred_dim, drct_dim, decd_dim, pred_offset;
    2183             : 
    2184       23378 :     FOR( i = 0; i < nB; i++ )
    2185             :     {
    2186       20744 :         ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[bands_bw * i]; /*Q0*/
    2187       20744 :         ndec = hMdDec->spar_md_cfg.num_decorr_per_band[bands_bw * i];   /*Q0*/
    2188       20744 :         move16();
    2189       20744 :         move16();
    2190             : 
    2191       20744 :         pred_dim = sub( add( ndec, ndm ), 1 );
    2192       20744 :         drct_dim = imult1616( ndec, sub( ndm, 1 ) ); /*Q0*/
    2193       20744 :         decd_dim = ndec;
    2194       20744 :         pred_offset = 0;
    2195       20744 :         move16();
    2196       20744 :         move16();
    2197             : 
    2198       20744 :         IF( hMdDec->spar_hoa_md_flag && hMdDec->spar_hoa_dirac2spar_md_flag )
    2199             :         {
    2200           0 :             IF( GE_16( i, SPAR_DIRAC_SPLIT_START_BAND ) )
    2201             :             {
    2202           0 :                 pred_offset = FOA_CHANNELS - 1;
    2203           0 :                 move16();
    2204             :             }
    2205             :         }
    2206             : 
    2207       82976 :         FOR( j = pred_offset; j < pred_dim; j++ )
    2208             :         {
    2209       62232 :             ivas_huffman_decode( &hMdDec->huff_coeffs.pred_huff_re[qsi], st0, &hMdDec->spar_md.band_coeffs_idx[i].pred_index_re[j] );
    2210             :         }
    2211             : 
    2212       20744 :         IF( hMdDec->spar_hoa_md_flag && hMdDec->spar_hoa_dirac2spar_md_flag )
    2213             :         {
    2214           0 :             IF( i >= SPAR_DIRAC_SPLIT_START_BAND )
    2215             :             {
    2216           0 :                 FOR( j = 0; j < pred_offset; j++ )
    2217             :                 {
    2218           0 :                     hMdDec->spar_md.band_coeffs_idx[i].pred_index_re[j] = 0;
    2219           0 :                     move16();
    2220             :                 }
    2221             :             }
    2222             :         }
    2223             : 
    2224       22984 :         FOR( j = 0; j < drct_dim; j++ )
    2225             :         {
    2226        2240 :             ivas_huffman_decode( &hMdDec->huff_coeffs.drct_huff_re[qsi], st0, &hMdDec->spar_md.band_coeffs_idx[i].drct_index_re[j] );
    2227             :         }
    2228             : 
    2229       24736 :         FOR( j = 0; j < decd_dim; j++ )
    2230             :         {
    2231        3992 :             ivas_huffman_decode( &hMdDec->huff_coeffs.decd_huff_re[qsi], st0, &hMdDec->spar_md.band_coeffs_idx[i].decd_index_re[j] );
    2232             :         }
    2233             :     }
    2234             : 
    2235        2634 :     return;
    2236             : }
    2237             : 
    2238      281808 : static void ivas_spar_plc_get_band_age(
    2239             :     const Word16 *valid_bands,                      /*Q0*/
    2240             :     Word16 *base_band_age,                          /*Q0*/
    2241             :     const Word16 num_bands,                         /*Q0*/
    2242             :     Word16 last_valid_band_idx[IVAS_MAX_NUM_BANDS], /*Q0*/
    2243             :     Word16 valid_band_idx[IVAS_MAX_NUM_BANDS],      /*Q0*/
    2244             :     Word16 *all_valid,                              /*Q0*/
    2245             :     Word16 *b_idx /*Q0*/ )
    2246             : {
    2247             :     Word16 b, idx;
    2248             : 
    2249      281808 :     set16_fx( valid_band_idx, 0, IVAS_MAX_NUM_BANDS );
    2250      281808 :     set16_fx( last_valid_band_idx, 0, IVAS_MAX_NUM_BANDS );
    2251      281808 :     idx = -1;
    2252      281808 :     *all_valid = 1;
    2253      281808 :     move16();
    2254      281808 :     move16();
    2255     3160932 :     FOR( b = 0; b < num_bands; b++ ){
    2256     2879124 :         IF( valid_bands[b] != 0 ){
    2257     2845532 :             base_band_age[b] = 0; /* reset band age */
    2258     2845532 :     idx = add( idx, 1 );
    2259     2845532 :     valid_band_idx[idx] = b;
    2260     2845532 :     move16();
    2261     2845532 :     move16();
    2262             : }
    2263             : ELSE
    2264             : {
    2265       33592 :     base_band_age[b] = add( base_band_age[b], 1 ); /* increment the age of invalid bands */ /*Q0*/
    2266             : 
    2267       33592 :     IF( GT_16( base_band_age[b], 3 ) )
    2268             :     {
    2269        5276 :         last_valid_band_idx[b] = idx;
    2270        5276 :         move16();
    2271             :     }
    2272       33592 :     *all_valid = 0;
    2273       33592 :     move16();
    2274             : }
    2275             : }
    2276      281808 : *b_idx = idx;
    2277      281808 : move16();
    2278             : 
    2279      281808 : return;
    2280             : }
    2281             : 
    2282             : 
    2283        5276 : static void ivas_spar_get_plc_interp_weights_fx(
    2284             :     Word16 valid_band_idx[IVAS_MAX_NUM_BANDS], /*Q0*/
    2285             :     Word16 last_valid_band_idx,                /*Q0*/
    2286             :     Word16 idx,                                /*Q0*/
    2287             :     Word16 b,                                  /*Q0*/
    2288             :     Word16 *w,                                 /*Q15*/
    2289             :     Word16 *id0,                               /*Q0*/
    2290             :     Word16 *id1 /*Q0*/ )
    2291             : {
    2292        5276 :     IF( last_valid_band_idx < 0 ) /* Extrapolation */
    2293             :     {
    2294        1484 :         *id1 = valid_band_idx[0]; /*Q0*/
    2295        1484 :         move16();
    2296        1484 :         *id0 = 0;
    2297        1484 :         move16();
    2298        1484 :         *w = MAX_WORD16;
    2299        1484 :         move16();
    2300             :     }
    2301        3792 :     ELSE IF( EQ_16( last_valid_band_idx, idx ) ) /* Extrapolation */
    2302             :     {
    2303         434 :         *id1 = valid_band_idx[last_valid_band_idx]; /*Q0*/
    2304         434 :         move16();
    2305         434 :         *id0 = valid_band_idx[last_valid_band_idx]; /*Q0*/
    2306         434 :         move16();
    2307         434 :         *w = 0;
    2308         434 :         move16();
    2309             :     }
    2310             :     ELSE /* Interpolation */
    2311             :     {
    2312        3358 :         *id0 = valid_band_idx[last_valid_band_idx]; /*Q0*/
    2313        3358 :         move16();
    2314        3358 :         *id1 = valid_band_idx[last_valid_band_idx + 1]; /*Q0*/
    2315        3358 :         move16();
    2316        3358 :         IF( sub( b, *id0 ) == 0 )
    2317             :         {
    2318           0 :             *w = 0;
    2319           0 :             move16();
    2320             :         }
    2321             :         ELSE
    2322             :         {
    2323        3358 :             *w = divide3232( sub( b, *id0 ), sub( *id1, *id0 ) ); /*Q0*/
    2324        3358 :             move16();
    2325             :         }
    2326             :     }
    2327        5276 :     return;
    2328             : }
    2329             : 
    2330             : /*-----------------------------------------------------------------------------------------*
    2331             :  * Function ivas_spar_md_fill_invalid_bands_fx()
    2332             :  *
    2333             :  * Fill invalid bands in interpolation/extrapolation of valid bands
    2334             :  * when PLC is to be done with partial time differential coding
    2335             :  *-----------------------------------------------------------------------------------------*/
    2336      140904 : static void ivas_spar_md_fill_invalid_bands_fx(
    2337             :     ivas_spar_dec_matrices_t *pSpar_coeffs,
    2338             :     ivas_spar_dec_matrices_t *pSpar_coeffs_prev,
    2339             :     const Word16 *valid_bands, /*Q0*/
    2340             :     Word16 *base_band_age,     /*Q0*/
    2341             :     const Word16 num_bands,    /*Q0*/
    2342             :     const Word16 num_channels, /*Q0*/
    2343             :     const Word16 num_md_sub_frames /*Q0*/ )
    2344             : {
    2345             :     Word16 i, j, b, all_valid;
    2346      140904 :     Word16 valid_band_idx[IVAS_MAX_NUM_BANDS], idx = -1;
    2347      140904 :     move16();
    2348             :     Word16 last_valid_band_idx[IVAS_MAX_NUM_BANDS];
    2349      140904 :     Word16 w_fx = 0;
    2350      140904 :     move16();
    2351      140904 :     ivas_spar_plc_get_band_age( valid_bands, base_band_age, num_bands,
    2352             :                                 last_valid_band_idx, valid_band_idx, &all_valid, &idx );
    2353      140904 :     assert( idx > 0 ); /* some bands should be valid */
    2354             : 
    2355      140904 :     IF( all_valid == 0 )
    2356             :     {
    2357       45876 :         FOR( b = 0; b < num_bands; b++ )
    2358             :         {
    2359             :             /* check against non zero in if and else if */
    2360             : 
    2361       42186 :             IF( GT_16( base_band_age[b], 3 ) ) /* old invalid bands */
    2362             :             {
    2363             :                 Word16 id0, id1;
    2364        2638 :                 ivas_spar_get_plc_interp_weights_fx( valid_band_idx, last_valid_band_idx[b],
    2365             :                                                      idx, b, &w_fx, &id0, &id1 );
    2366       13190 :                 FOR( i = 0; i < num_channels; i++ )
    2367             :                 {
    2368       52760 :                     FOR( j = 0; j < num_channels; j++ )
    2369             :                     {
    2370       42208 :                         pSpar_coeffs->C_re_fx[i][j][b] = L_add( Mpy_32_16_1( pSpar_coeffs->C_re_fx[i][j][id0], sub( MAX_WORD16, w_fx ) ), Mpy_32_16_1( pSpar_coeffs->C_re_fx[i][j][id1], w_fx ) ); /*Q22*/
    2371       42208 :                         move32();
    2372       42208 :                         pSpar_coeffs->P_re_fx[i][j][b] = L_add( Mpy_32_16_1( pSpar_coeffs->P_re_fx[i][j][id0], sub( MAX_WORD16, w_fx ) ), Mpy_32_16_1( pSpar_coeffs->P_re_fx[i][j][id1], w_fx ) ); /*Q22*/
    2373       42208 :                         move32();
    2374             :                     }
    2375             :                 }
    2376             :             }
    2377             :             ELSE /* young invalid bands */
    2378             :             {
    2379       39548 :                 IF( valid_bands[b] == 0 )
    2380             :                 {
    2381       70790 :                     FOR( i = 0; i < num_channels; i++ )
    2382             :                     {
    2383      283160 :                         FOR( j = 0; j < num_channels; j++ )
    2384             :                         {
    2385      226528 :                             pSpar_coeffs->C_re_fx[i][j][b] = pSpar_coeffs_prev->C_re_fx[i][j][b]; /*Q22*/
    2386      226528 :                             move32();
    2387      226528 :                             pSpar_coeffs->P_re_fx[i][j][b] = pSpar_coeffs_prev->P_re_fx[i][j][b]; /*Q22*/
    2388      226528 :                             move32();
    2389             :                         }
    2390             :                     }
    2391             :                 }
    2392             :             }
    2393             : 
    2394       42186 :             IF( valid_bands[b] == 0 )
    2395             :             {
    2396             :                 Word16 i_ts;
    2397       83980 :                 FOR( i = 0; i < num_channels; i++ )
    2398             :                 {
    2399      335920 :                     FOR( j = 0; j < num_channels; j++ )
    2400             :                     {
    2401     1065248 :                         FOR( i_ts = 1; i_ts < num_md_sub_frames; i_ts++ )
    2402             :                         {
    2403      796512 :                             pSpar_coeffs->C_re_fx[i][j][( b + ( i_ts * IVAS_MAX_NUM_BANDS ) )] = pSpar_coeffs->C_re_fx[i][j][b]; /*Q22*/
    2404      796512 :                             move32();
    2405      796512 :                             pSpar_coeffs->P_re_fx[i][j][( b + ( i_ts * IVAS_MAX_NUM_BANDS ) )] = pSpar_coeffs->P_re_fx[i][j][b]; /*Q22*/
    2406      796512 :                             move32();
    2407             :                         }
    2408             :                     }
    2409             :                 }
    2410             :             }
    2411             :         }
    2412             :     }
    2413             : 
    2414      140904 :     return;
    2415             : }
    2416             : 
    2417      140904 : static void ivas_spar_md_fill_invalid_bandcoeffs(
    2418             :     ivas_band_coeffs_t *pBand_coeffs,
    2419             :     ivas_band_coeffs_t *pBand_coeffs_prev,
    2420             :     const Word16 *valid_bands, /*Q0*/
    2421             :     Word16 *base_band_age,     /*Q0*/
    2422             :     Word16 *first_valid_frame, /*Q0*/
    2423             :     const Word16 num_bands /*Q0*/ )
    2424             : {
    2425             :     Word16 j, k, b, all_valid;
    2426      140904 :     Word16 valid_band_idx[IVAS_MAX_NUM_BANDS], idx = -1;
    2427      140904 :     move16();
    2428             :     Word16 last_valid_band_idx[IVAS_MAX_NUM_BANDS];
    2429      140904 :     Word16 w_fx = 0;
    2430      140904 :     move16();
    2431             : 
    2432      140904 :     ivas_spar_plc_get_band_age( valid_bands, base_band_age, num_bands,
    2433             :                                 last_valid_band_idx, valid_band_idx, &all_valid, &idx );
    2434             : 
    2435      140904 :     assert( idx > 0 ); /* some bands should be valid */
    2436             : 
    2437      140904 :     IF( all_valid == 0 )
    2438             :     {
    2439       33210 :         FOR( b = 0; b < num_bands; b++ )
    2440             :         {
    2441             :             /* check against non zero in if and else if */
    2442       29520 :             test();
    2443       29520 :             IF( GT_16( base_band_age[b], 3 ) || ( *first_valid_frame == 0 ) ) /* old invalid bands */
    2444        2638 :             {
    2445             :                 Word16 id0, id1;
    2446             : 
    2447        2638 :                 ivas_spar_get_plc_interp_weights_fx( valid_band_idx, last_valid_band_idx[b],
    2448             :                                                      idx, b, &w_fx, &id0, &id1 );
    2449             : 
    2450       29018 :                 FOR( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ )
    2451             :                 {
    2452       26380 :                     pBand_coeffs[b].pred_re_fx[j] = L_add( Mpy_32_16_1( pBand_coeffs[id0].pred_re_fx[j], sub( MAX_WORD16, w_fx ) ), Mpy_32_16_1( pBand_coeffs[id1].pred_re_fx[j], w_fx ) ); /*Q22*/
    2453       26380 :                     move32();
    2454             :                 }
    2455             : 
    2456       21104 :                 FOR( j = 0; j < IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS; j++ )
    2457             :                 {
    2458       73864 :                     FOR( k = 0; k < IVAS_SPAR_MAX_DMX_CHS - 1; k++ )
    2459             :                     {
    2460       55398 :                         pBand_coeffs[b].C_re_fx[j][k] = L_add( Mpy_32_16_1( pBand_coeffs[id0].C_re_fx[j][k], sub( MAX_WORD16, w_fx ) ), Mpy_32_16_1( pBand_coeffs[id1].C_re_fx[j][k], w_fx ) ); /*Q22*/
    2461       55398 :                         move32();
    2462             :                     }
    2463             :                 }
    2464             : 
    2465       29018 :                 FOR( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ )
    2466             :                 {
    2467       26380 :                     pBand_coeffs[b].P_re_fx[j] = L_add( Mpy_32_16_1( pBand_coeffs[id0].P_re_fx[j], sub( MAX_WORD16, w_fx ) ), Mpy_32_16_1( pBand_coeffs[id1].P_re_fx[j], w_fx ) ); /*Q22*/
    2468       26380 :                     move32();
    2469             :                 }
    2470             :             }
    2471             :             ELSE /* young invalid bands */
    2472             :             {
    2473       26882 :                 IF( valid_bands[b] == 0 )
    2474             :                 {
    2475      155738 :                     FOR( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ )
    2476             :                     {
    2477      141580 :                         pBand_coeffs[b].pred_re_fx[j] = pBand_coeffs_prev[b].pred_re_fx[j]; /*Q22*/
    2478      141580 :                         move32();
    2479             :                     }
    2480             : 
    2481      113264 :                     FOR( j = 0; j < IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS; j++ )
    2482             :                     {
    2483      396424 :                         FOR( k = 0; k < IVAS_SPAR_MAX_DMX_CHS - 1; k++ )
    2484             :                         {
    2485      297318 :                             pBand_coeffs[b].C_re_fx[j][k] = pBand_coeffs_prev[b].C_re_fx[j][k]; /*Q22*/
    2486      297318 :                             move32();
    2487             :                         }
    2488             :                     }
    2489             : 
    2490      155738 :                     FOR( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ )
    2491             :                     {
    2492      141580 :                         pBand_coeffs[b].P_re_fx[j] = pBand_coeffs_prev[b].P_re_fx[j]; /*Q22*/
    2493      141580 :                         move32();
    2494             :                     }
    2495             :                 }
    2496             :             }
    2497             :         }
    2498             :     }
    2499             :     ELSE
    2500             :     {
    2501      137214 :         *first_valid_frame = 1;
    2502      137214 :         move16();
    2503             :     }
    2504             : 
    2505      140904 :     return;
    2506             : }
    2507             : 
    2508             : /*-----------------------------------------------------------------------------------------*
    2509             :  * Function ivas_spar_dec_compute_ramp_down_post_matrix_fx()
    2510             :  *
    2511             :  *
    2512             :  *-----------------------------------------------------------------------------------------*/
    2513             : 
    2514      182441 : static void ivas_spar_dec_compute_ramp_down_post_matrix_fx(
    2515             :     ivas_spar_md_dec_state_t *hMdDec,
    2516             :     const Word16 num_bands_out, /*Q0*/
    2517             :     const Word16 bfi,           /*Q0*/
    2518             :     const Word16 num_md_sub_frames /*Q0*/ )
    2519             : {
    2520             :     Word16 num_in_ch, num_out_ch, i, j, b;
    2521      182441 :     num_in_ch = hMdDec->spar_md_cfg.num_umx_chs;  /*Q0*/
    2522      182441 :     num_out_ch = hMdDec->spar_md_cfg.num_umx_chs; /*Q0*/
    2523      182441 :     move16();
    2524      182441 :     move16();
    2525      182441 :     IF( bfi == 0 )
    2526             :     {
    2527      176257 :         hMdDec->spar_plc_num_lost_frames = 0;
    2528      176257 :         move16();
    2529             :     }
    2530             :     ELSE
    2531             :     {
    2532        6184 :         if ( hMdDec->td_decorr_flag == 0 )
    2533             :         {
    2534           0 :             assert( 0 );
    2535             :         }
    2536             : 
    2537        6184 :         hMdDec->spar_plc_num_lost_frames = add( hMdDec->spar_plc_num_lost_frames, 1 );
    2538        6184 :         move16();
    2539        6184 :         hMdDec->spar_plc_num_lost_frames = s_min( hMdDec->spar_plc_num_lost_frames, 100 ); /*hMdDec->spar_plc_num_lost_frames is always <=100*/ /*Q0*/
    2540        6184 :         move16();
    2541             : 
    2542        6184 :         IF( GT_16( hMdDec->spar_plc_num_lost_frames, ivas_spar_dec_plc_num_frames_keep ) ) /*if control enters then ivas_spar_dec_plc_num_frames_keep<100 */
    2543             :         {
    2544             :             Word16 num_fade_frames;
    2545             :             Word16 gain_dB;
    2546             :             Word32 gain_fx;
    2547             :             Word32 post_matrix_fx[IVAS_SPAR_MAX_CH];
    2548             :             Word16 Q_post_matrix;
    2549             :             Word16 Q_gain;
    2550             :             Word16 norm_nff; /*norm of num_fade_frames*/
    2551        2038 :             num_fade_frames = s_max( sub( hMdDec->spar_plc_num_lost_frames, ivas_spar_dec_plc_num_frames_keep ), 0 );
    2552        2038 :             norm_nff = norm_s( num_fade_frames );
    2553        2038 :             gain_dB = negate( imult1616( s_min( num_fade_frames, ivas_spar_dec_plc_max_num_frames_ramp_down ), ivas_spar_dec_plc_per_frame_ramp_down_gain_dB ) ); /*abs(gain_dB)<99*/ /*Q(gain_dB)=7Q24*/
    2554        2038 :             Word16 exp_gain = 0;
    2555        2038 :             move16();                                                                                                                       /*stores exponent for gain_fx*/
    2556        2038 :             gain_fx = BASOP_util_Pow2( Mult_32_16( imult3216( 13421773 /*=2^28/20*/, gain_dB ), 27213 /*=log2(10)*2^13*/ ), 5, &exp_gain ); /*Q_gain*/
    2557        2038 :             Q_gain = sub( 31, exp_gain );
    2558       24456 :             FOR( i = 0; i < IVAS_SPAR_MAX_CH; i++ )
    2559             :             {
    2560       22418 :                 post_matrix_fx[i] = add( shl( 1, norm_nff ), mult( s_min( mult( shl( num_fade_frames, norm_nff ), 3640 /* 1 / ivas_spar_dec_plc_num_frames_fade_out in Q15 */ ), shl( 1, norm_nff ) ), shl( sub( ivas_spar_dec_plc_spatial_target[i], 1 ), 15 ) ) ); /*Q=norm_nff*/
    2561       22418 :                 move32();
    2562       22418 :                 post_matrix_fx[i] = Mult_32_16( gain_fx, extract_l( post_matrix_fx[i] ) ); /*Q_gain+norm_nff-15*/
    2563       22418 :                 move32();
    2564             :             }
    2565        2038 :             Q_post_matrix = sub( add( Q_gain, norm_nff ), 15 );
    2566             :             /* apply the post matrix */
    2567        2038 :             hMdDec->Q_mixer_mat = sub( add( Q_post_matrix, hMdDec->Q_mixer_mat ), 31 );
    2568        2038 :             move16();
    2569       10190 :             FOR( Word16 i_ts = 0; i_ts < num_md_sub_frames; i_ts++ )
    2570             :             {
    2571       40760 :                 FOR( i = 0; i < num_out_ch; i++ )
    2572             :                 {
    2573      163040 :                     FOR( j = 0; j < num_in_ch; j++ )
    2574             :                     {
    2575     1611648 :                         FOR( b = 0; b < num_bands_out; b++ )
    2576             :                         {
    2577     1481216 :                             hMdDec->mixer_mat_fx[i][j][( b + ( i_ts * IVAS_MAX_NUM_BANDS ) )] = L_shl( Mult_32_32( hMdDec->mixer_mat_fx[i][j][( b + ( i_ts * IVAS_MAX_NUM_BANDS ) )], post_matrix_fx[i] ), sub( Q30, hMdDec->Q_mixer_mat ) ); // Q30
    2578     1481216 :                             move32();
    2579             :                         }
    2580             :                     }
    2581             :                 }
    2582             :             }
    2583        2038 :             hMdDec->Q_mixer_mat = Q30;
    2584        2038 :             move16();
    2585             :         }
    2586             :     }
    2587             : 
    2588      182441 :     return;
    2589             : }
    2590             : 
    2591             : 
    2592             : /*-----------------------------------------------------------------------------------------*
    2593             :  * Function ivas_spar_unquant_dtx_indicies()
    2594             :  *
    2595             :  * Unquantize SPAR MD DYX indices
    2596             :  *-----------------------------------------------------------------------------------------*/
    2597         557 : static void ivas_spar_unquant_dtx_indicies(
    2598             :     ivas_spar_md_t *pSpar_md,
    2599             :     const Word16 nB, /*Q0*/
    2600             :     const Word16 bw, /*Q0*/
    2601             :     Word16 *ndm_per_band /*Q0*/ )
    2602             : {
    2603             :     Word16 i, b;
    2604             :     Word16 q_lvl;
    2605             :     Word32 val_fx;
    2606             :     Word16 idx;
    2607             :     Word32 pr_min_max_fx[2];
    2608             : 
    2609         557 :     pr_min_max_fx[0] = pSpar_md->min_max_fx[0]; /*Q28*/
    2610         557 :     move32();
    2611         557 :     pr_min_max_fx[1] = pSpar_md->min_max_fx[1]; /*Q28*/
    2612         557 :     move32();
    2613             : 
    2614        1671 :     FOR( b = 0; b < nB; b++ )
    2615             :     {
    2616        4456 :         FOR( i = 0; i < FOA_CHANNELS - 1; i++ )
    2617             :         {
    2618        3342 :             q_lvl = dtx_pr_real_q_levels[( ndm_per_band[( bw * b )] - 1 )][i]; /*Q0*/
    2619        3342 :             move16();
    2620             : 
    2621        3342 :             idx = pSpar_md->band_coeffs_idx[b].pred_index_re[i]; /*Q0*/
    2622        3342 :             move16();
    2623        3342 :             ivas_deindex_real_index_fx( &idx, q_lvl, pr_min_max_fx[0], pr_min_max_fx[1], &val_fx, 1 );
    2624        3342 :             pSpar_md->band_coeffs[b].pred_re_fx[i] = val_fx; /*Q22*/
    2625        3342 :             move32();
    2626             :         }
    2627             : 
    2628        3820 :         FOR( i = 0; i < ( FOA_CHANNELS - ndm_per_band[( bw - b )] ); i++ )
    2629             :         {
    2630        2706 :             q_lvl = dtx_pd_real_q_levels[( ndm_per_band[( bw * b )] - 1 )][i]; /*Q0*/
    2631        2706 :             move16();
    2632             : 
    2633        2706 :             idx = pSpar_md->band_coeffs_idx[b].decd_index_re[i]; /*Q0*/
    2634        2706 :             move16();
    2635        2706 :             ivas_deindex_real_index_fx( &idx, q_lvl, dtx_pd_real_min_max_fx[0], dtx_pd_real_min_max_fx[1], &val_fx, 1 );
    2636        2706 :             pSpar_md->band_coeffs[b].P_re_fx[i] = val_fx; /*Q22*/
    2637        2706 :             move32();
    2638             :         }
    2639             :     }
    2640             : 
    2641         557 :     return;
    2642             : }
    2643             : 
    2644             : /*-----------------------------------------------------------------------------------------*
    2645             :  * Function ivas_parse_parameter_bitstream_dtx()
    2646             :  *
    2647             :  * parse DTX bitstream parameters
    2648             :  *-----------------------------------------------------------------------------------------*/
    2649         557 : static void ivas_parse_parameter_bitstream_dtx(
    2650             :     ivas_spar_md_t *pSpar_md,
    2651             :     Decoder_State *st0,       /* i/o: decoder state structure - for bitstream handling*/
    2652             :     const Word16 bw,          /*Q0*/
    2653             :     const Word16 num_bands,   /*Q0*/
    2654             :     Word16 *num_dmx_per_band, /*Q0*/
    2655             :     Word16 *num_dec_per_band /*Q0*/ )
    2656             : {
    2657             :     Word16 i, j, ndec, ndm;
    2658             :     Word32 val_fx;
    2659             :     Word16 idx;
    2660             :     Word32 pr_min_max_fx[2];
    2661             :     Word16 pr_q_lvls, pr, pd, pd_q_lvls, pr_pd_bits;
    2662             :     Word16 zero_pad_bits, sid_bits_len;
    2663             : 
    2664         557 :     sid_bits_len = st0->next_bit_pos; /*Q0*/
    2665         557 :     move16();
    2666         557 :     pr_min_max_fx[0] = pSpar_md->min_max_fx[0]; /*Q28*/
    2667         557 :     move32();
    2668         557 :     pr_min_max_fx[1] = pSpar_md->min_max_fx[1]; /*Q28*/
    2669         557 :     move32();
    2670             : 
    2671        1671 :     FOR( i = 0; i < num_bands; i++ )
    2672             :     {
    2673        1114 :         ndec = num_dec_per_band[( bw * i )];
    2674        1114 :         move16();
    2675        1114 :         ndm = num_dmx_per_band[( bw * i )];
    2676        1114 :         move16();
    2677             : 
    2678        4456 :         FOR( j = 0; j < FOA_CHANNELS - 1; j++ )
    2679             :         {
    2680             :             Word16 pr_idx_1, pr_idx_2, pd_idx_1, pd_idx_2;
    2681             :             UWord16 value;
    2682             : 
    2683        3342 :             pr_idx_1 = pr_pr_idx_pairs[ndm - 1][j][0]; /*Q0*/
    2684        3342 :             move16();
    2685        3342 :             pr_idx_2 = pr_pr_idx_pairs[ndm - 1][j][1]; /*Q0*/
    2686        3342 :             move16();
    2687        3342 :             pd_idx_1 = pr_pd_idx_pairs[ndm - 1][j][0]; /*Q0*/
    2688        3342 :             move16();
    2689        3342 :             pd_idx_2 = pr_pd_idx_pairs[ndm - 1][j][1]; /*Q0*/
    2690        3342 :             move16();
    2691             : 
    2692        3342 :             test();
    2693        3342 :             test();
    2694        3342 :             test();
    2695        3342 :             IF( pr_idx_1 != 0 || pd_idx_1 != 0 || pr_idx_2 != 0 || pd_idx_2 != 0 )
    2696             :             {
    2697        3342 :                 pr_q_lvls = dtx_pr_real_q_levels[ndm - 1][pd_idx_1 - 1]; /*Q0*/
    2698        3342 :                 move16();
    2699             : 
    2700        3342 :                 IF( GT_16( add( j, 1 ), ndec ) )
    2701             :                 {
    2702         636 :                     pd_q_lvls = 1;
    2703         636 :                     move16();
    2704             :                 }
    2705             :                 ELSE
    2706             :                 {
    2707        2706 :                     pd_q_lvls = dtx_pd_real_q_levels[ndm - 1][pd_idx_2 - 1]; /*Q0*/
    2708        2706 :                     move16();
    2709             :                 }
    2710             : 
    2711        3342 :                 pr_pd_bits = ivas_get_bits_to_encode( L_mult0( pd_q_lvls, pr_q_lvls ) ); /*Q0*/
    2712             : 
    2713        3342 :                 value = get_next_indice_fx( st0, pr_pd_bits ); /*Q0*/
    2714             : 
    2715        3342 :                 IF( value != 0 )
    2716             :                 {
    2717        3342 :                     pr = idiv1616( value, pd_q_lvls ); /*Q0*/
    2718             :                 }
    2719             :                 ELSE
    2720             :                 {
    2721           0 :                     pr = 0;
    2722           0 :                     move16();
    2723             :                 }
    2724        3342 :                 pd = extract_l( L_sub( value, i_mult( pr, pd_q_lvls ) ) );
    2725        3342 :                 val_fx = dtx_pd_real_min_max_fx[0]; /*Q28*/
    2726        3342 :                 move32();
    2727        3342 :                 ivas_quantise_real_values_fx( &val_fx, pd_q_lvls, dtx_pd_real_min_max_fx[0], dtx_pd_real_min_max_fx[1], &idx, &val_fx, 1 );
    2728        3342 :                 pd = add( pd, idx );
    2729             : 
    2730        3342 :                 val_fx = pr_min_max_fx[0]; /*Q28*/
    2731        3342 :                 move32();
    2732        3342 :                 ivas_quantise_real_values_fx( &val_fx, pr_q_lvls, pr_min_max_fx[0], pr_min_max_fx[1], &idx, &val_fx, 1 );
    2733        3342 :                 pr = add( pr, idx );
    2734             : 
    2735        3342 :                 if ( LE_16( add( j, 1 ), ndec ) )
    2736             :                 {
    2737        2706 :                     pSpar_md->band_coeffs_idx[i].decd_index_re[pd_idx_2 - 1] = pd; /*Q0*/
    2738        2706 :                     move16();
    2739             :                 }
    2740             : 
    2741        3342 :                 pSpar_md->band_coeffs_idx[i].pred_index_re[pd_idx_1 - 1] = pr; /*Q0*/
    2742        3342 :                 move16();
    2743             :             }
    2744             :         }
    2745             :     }
    2746             : 
    2747         557 :     sid_bits_len = sub( st0->next_bit_pos, sid_bits_len );
    2748         557 :     zero_pad_bits = sub( ( SPAR_DTX_BANDS * SPAR_SID_BITS_TAR_PER_BAND ), sid_bits_len );
    2749         557 :     assert( zero_pad_bits >= 0 );
    2750         557 :     if ( EQ_16( num_dmx_per_band[0], 2 ) )
    2751             :     {
    2752         318 :         zero_pad_bits = sub( zero_pad_bits, 1 );
    2753             :     }
    2754             : 
    2755        2147 :     FOR( j = 0; j < zero_pad_bits; j++ )
    2756             :     {
    2757        1590 :         get_next_indice_fx( st0, 1 );
    2758             :     }
    2759             : 
    2760         557 :     ivas_spar_unquant_dtx_indicies( pSpar_md, num_bands, bw, num_dmx_per_band );
    2761             : 
    2762         557 :     return;
    2763             : }
    2764             : 
    2765             : /*-----------------------------------------------------------------------------------------*
    2766             :  * Function ivas_deindex_real_index()
    2767             :  *
    2768             :  * Deindex real index
    2769             :  *-----------------------------------------------------------------------------------------*/
    2770             : 
    2771             : 
    2772     3492816 : static ivas_error ivas_deindex_real_index_fx(
    2773             :     const Word16 *index,    /*Q0*/
    2774             :     const Word16 q_levels,  /*Q0*/
    2775             :     const Word32 min_value, /*Q28*/
    2776             :     const Word32 max_value, /*Q28*/
    2777             :     Word32 *quant,          /*Q22*/
    2778             :     const Word16 dim /*Q0*/ )
    2779             : {
    2780             :     Word16 i;
    2781             :     Word32 q_step_fx;
    2782     3492816 :     IF( q_levels == 0 )
    2783             :     {
    2784           0 :         return IVAS_ERR_INTERNAL;
    2785             :     }
    2786             : 
    2787     3492816 :     IF( EQ_16( q_levels, 1 ) )
    2788             :     {
    2789      902268 :         FOR( i = 0; i < dim; i++ )
    2790             :         {
    2791      388320 :             quant[i] = 0;
    2792      388320 :             move32();
    2793             :         }
    2794             :     }
    2795             :     ELSE
    2796             :     {
    2797     2978868 :         q_step_fx = L_sub( max_value, min_value );
    2798     2978868 :         q_step_fx = Mpy_32_32( q_step_fx, one_by_q_level[q_levels - 1] /*Q31*/ ); /*Q28*/
    2799    16476116 :         FOR( i = 0; i < dim; i++ )
    2800             :         {
    2801    13497248 :             quant[i] = Mpy_32_32( L_shl( index[i], 31 - 6 ), q_step_fx ); //(25+28)-31 = 22
    2802    13497248 :             move32();
    2803             :         }
    2804             :     }
    2805             : 
    2806     3492816 :     return IVAS_ERR_OK;
    2807             : }
    2808             : 
    2809             : 
    2810      131040 : void ivas_spar_to_dirac_fx(
    2811             :     Decoder_Struct *st_ivas,
    2812             :     ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle      Q0*/
    2813             :     const Word16 dtx_vad,             /* i  : DTX frame flag              Q0*/
    2814             :     const Word16 num_bands_out,       /* i  : number of output bands      Q0*/
    2815             :     const Word16 bw,                  /* i  : band joining factor         Q0*/
    2816             :     const Word16 dyn_active_w_flag )
    2817             : {
    2818             :     DIRAC_DEC_HANDLE hDirAC;
    2819             :     Word16 start_band, end_band, band, qmf_band_start, qmf_band_end;
    2820             :     Word16 block, b;
    2821             :     Word16 *band_grouping;
    2822             : 
    2823             :     Word32 diffuseness_fx[IVAS_MAX_NUM_BANDS];
    2824             :     Word16 sba_order_internal;
    2825             : 
    2826             :     Word32 azi_dirac_fx[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES];
    2827             : 
    2828             :     Word32 ele_dirac_fx[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES];
    2829             :     Word16 azi[IVAS_MAX_NUM_BANDS];
    2830             :     Word16 ele[IVAS_MAX_NUM_BANDS];
    2831             : 
    2832             :     Word32 dvx_fx[IVAS_MAX_NUM_BANDS], dvy_fx[IVAS_MAX_NUM_BANDS], dvz_fx[IVAS_MAX_NUM_BANDS];
    2833             : 
    2834             :     Word32 radius_fx;
    2835             : 
    2836             :     Word32 en_ratio_fx, res_pow_fx;
    2837             :     Word16 en_ratio_q;
    2838             :     Word16 num_slots_in_subfr;
    2839             :     Word16 tmp_write_idx_param_band;
    2840             :     Word16 tmp_write_idx_band;
    2841             : 
    2842             :     Word32 pred_re_20ms_fx[IVAS_MAX_NUM_BANDS][IVAS_SPAR_MAX_CH - 1];
    2843             :     Word16 pred_idx;
    2844             :     Word16 *dirac_to_spar_md_bands;
    2845             :     Word16 enc_param_start_band;
    2846             :     Word16 active_w_vlbr;
    2847             :     Word16 i, num_subframes;
    2848             :     Word16 active_w;
    2849             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
    2850             : 
    2851      131040 :     test();
    2852      131040 :     active_w = EQ_16( dyn_active_w_flag, 1 ) || EQ_16( hMdDec->spar_md_cfg.active_w, 1 );
    2853      131040 :     sba_order_internal = s_min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER );
    2854      131040 :     move16();
    2855      131040 :     start_band = 0;
    2856      131040 :     move16();
    2857      131040 :     end_band = idiv1616( s_min( num_bands_out, SPAR_DIRAC_SPLIT_START_BAND ), bw ); /*Q0*/
    2858             : 
    2859      131040 :     hDirAC = st_ivas->hDirAC;
    2860      131040 :     hSpatParamRendCom = st_ivas->hSpatParamRendCom;
    2861             : 
    2862      131040 :     dirac_to_spar_md_bands = st_ivas->hSpar->dirac_to_spar_md_bands; /*Q0*/
    2863      131040 :     move16();
    2864             : 
    2865      131040 :     IF( st_ivas->hSpar->enc_param_start_band > 0 )
    2866             :     {
    2867      124846 :         enc_param_start_band = idiv1616( st_ivas->hSpar->enc_param_start_band, bw ); /*Q0*/
    2868             :     }
    2869             :     ELSE
    2870             :     {
    2871        6194 :         enc_param_start_band = 0;
    2872        6194 :         move16();
    2873             :     }
    2874             : 
    2875      131040 :     IF( LT_32( st_ivas->hDecoderConfig->ivas_total_brate, IVAS_24k4 ) )
    2876             :     {
    2877       11277 :         active_w_vlbr = 1;
    2878       11277 :         move16();
    2879             :     }
    2880             :     ELSE
    2881             :     {
    2882      119763 :         active_w_vlbr = 0;
    2883      119763 :         move16();
    2884             :     }
    2885             : 
    2886      131040 :     test();
    2887      131040 :     IF( hDirAC != NULL && ivas_get_hodirac_flag_fx( st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->sba_analysis_order ) == 0 )
    2888             :     {
    2889       79292 :         band_grouping = hDirAC->band_grouping;
    2890             : 
    2891       79292 :         IF( st_ivas->hDirAC->hConfig->dec_param_estim )
    2892             :         {
    2893       43076 :             num_slots_in_subfr = CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES;
    2894       43076 :             move16();
    2895             :         }
    2896             :         ELSE
    2897             :         {
    2898       36216 :             num_slots_in_subfr = 1;
    2899       36216 :             move16();
    2900             :         }
    2901             : 
    2902      713628 :         FOR( band = start_band; band < end_band; band++ )
    2903             :         {
    2904             :             Word32 PR_fx[3], Pd_fx[3], dvnorm_fx, g_pred_fx;
    2905             :             Word16 q_g_pred;
    2906             :             Word16 q_dvnorm;
    2907      634336 :             PR_fx[0] = hMdDec->spar_md.band_coeffs[band].pred_re_fx[2]; /*Q22*/
    2908      634336 :             move32();
    2909      634336 :             PR_fx[1] = hMdDec->spar_md.band_coeffs[band].pred_re_fx[0]; /*Q22*/
    2910      634336 :             move32();
    2911      634336 :             PR_fx[2] = hMdDec->spar_md.band_coeffs[band].pred_re_fx[1]; /*Q22*/
    2912      634336 :             move32();
    2913      634336 :             g_pred_fx = L_add( L_add( Mpy_32_32( PR_fx[0], PR_fx[0] ), Mpy_32_32( PR_fx[1], PR_fx[1] ) ), Mpy_32_32( PR_fx[2], PR_fx[2] ) ); /*q_g_pred*/
    2914      634336 :             q_g_pred = Q22 + Q22 - Q31;
    2915      634336 :             move16();
    2916      634336 :             q_dvnorm = sub( Q31, q_g_pred );
    2917      634336 :             q_g_pred = q_dvnorm;
    2918      634336 :             move16();
    2919      634336 :             IF( LE_32( g_pred_fx, EPSILON_FIX ) )
    2920             :             {
    2921       28571 :                 dvx_fx[band] = ONE_IN_Q22; /*Q22*/
    2922       28571 :                 move32();
    2923       28571 :                 dvy_fx[band] = 0;
    2924       28571 :                 move32();
    2925       28571 :                 dvz_fx[band] = 0;
    2926       28571 :                 move32();
    2927             : 
    2928       28571 :                 azi[band] = 0;
    2929       28571 :                 move16();
    2930       28571 :                 ele[band] = 0;
    2931       28571 :                 move16();
    2932       28571 :                 q_g_pred = Q22;
    2933       28571 :                 move16();
    2934       28571 :                 q_dvnorm = Q22;
    2935       28571 :                 move16();
    2936             :             }
    2937             :             ELSE
    2938             :             {
    2939      605765 :                 dvnorm_fx = ISqrt32( g_pred_fx, &q_dvnorm ); /*Q31 - q_dvnorm*/
    2940      605765 :                 g_pred_fx = Sqrt32( g_pred_fx, &q_g_pred );  /*Q31 - q_g_pred*/
    2941      605765 :                 IF( q_g_pred < 0 )
    2942             :                 {
    2943      259374 :                     g_pred_fx = L_shr( g_pred_fx, negate( q_g_pred ) );
    2944      259374 :                     q_g_pred = 0;
    2945      259374 :                     move16();
    2946             :                 }
    2947             : 
    2948      605765 :                 dvx_fx[band] = Mpy_32_32( PR_fx[0], dvnorm_fx ); /*q_1*/
    2949      605765 :                 move32();
    2950      605765 :                 dvy_fx[band] = Mpy_32_32( PR_fx[1], dvnorm_fx ); /*q_1*/
    2951      605765 :                 move32();
    2952      605765 :                 dvz_fx[band] = Mpy_32_32( PR_fx[2], dvnorm_fx ); /*q_1*/
    2953      605765 :                 move32();
    2954      605765 :                 Word16 q_1 = sub( add( 22, sub( 31, q_dvnorm ) ), 31 );
    2955             : 
    2956      605765 :                 Word32 temp = L_add( Mpy_32_32( dvx_fx[band], dvx_fx[band] ), Mpy_32_32( dvy_fx[band], dvy_fx[band] ) ); /*q2*/
    2957      605765 :                 Word16 q2 = sub( add( q_1, q_1 ), 31 );
    2958      605765 :                 Word16 q_temp = sub( 31, q2 );
    2959      605765 :                 radius_fx = Sqrt32( temp, &q_temp );
    2960             : 
    2961      605765 :                 Word16 check_azi_fx = BASOP_util_atan2( dvy_fx[band], dvx_fx[band], 0 ); /*Q13*/
    2962      605765 :                 Word32 check_azi_fx_32 = L_shl( check_azi_fx, 16 );                      /*Q29*/
    2963             :                 Word16 check_azi_fx_res;
    2964      605765 :                 IF( check_azi_fx_32 < 0 )
    2965             :                 {
    2966      410203 :                     check_azi_fx_res = negate( divide3232( L_negate( check_azi_fx_32 ), 1686629760 /*3.145f in Q29*/ ) ); /*Q15*/
    2967             :                 }
    2968             :                 ELSE
    2969             :                 {
    2970      195562 :                     check_azi_fx_res = divide3232( check_azi_fx_32, 1686629760 /*3.145f in Q29*/ ); /*Q15*/
    2971             :                 }
    2972      605765 :                 Word32 azi_intermediate = Mpy_32_16_1( DEGREE_180_Q_22, check_azi_fx_res ); /*Q22*/
    2973      605765 :                 azi_intermediate = L_add( azi_intermediate, ONE_IN_Q21 );                   /*Q22*/
    2974             : 
    2975             :                 Word16 azi_res;
    2976      605765 :                 IF( azi_intermediate < 0 )
    2977             :                 {
    2978      410203 :                     azi_res = negate( extract_l( L_shr( L_negate( azi_intermediate ), 22 ) ) ); /*Q0*/
    2979             :                 }
    2980             :                 ELSE
    2981             :                 {
    2982      195562 :                     azi_res = extract_l( L_shr( azi_intermediate, 22 ) ); /*Q0*/
    2983             :                 }
    2984             : 
    2985      605765 :                 Word16 check_ele_fx = BASOP_util_atan2( dvz_fx[band], radius_fx, sub( add( 9, q_dvnorm ), q_temp ) ); /*Q13*/
    2986      605765 :                 Word32 check_ele_fx_32 = L_shl( check_ele_fx, 16 );                                                   /*Q29*/
    2987             :                 Word16 check_ele_fx_res;
    2988      605765 :                 IF( check_azi_fx_32 < 0 )
    2989             :                 {
    2990      410203 :                     check_ele_fx_res = negate( divide3232( L_negate( check_ele_fx_32 ), 1686629760 /*3.145f in Q29*/ ) ); /*Q15*/
    2991             :                 }
    2992             :                 ELSE
    2993             :                 {
    2994      195562 :                     check_ele_fx_res = divide3232( check_ele_fx_32, 1686629760 /*3.145f in Q29*/ ); /*Q15*/
    2995             :                 }
    2996      605765 :                 Word32 ele_intermediate = Mpy_32_16_1( DEGREE_180_Q_22, check_ele_fx_res ); /*Q22*/
    2997      605765 :                 ele_intermediate = L_add( ele_intermediate, ONE_IN_Q21 );                   /*Q22*/
    2998             : 
    2999             :                 Word16 ele_res;
    3000      605765 :                 IF( ele_intermediate < 0 )
    3001             :                 {
    3002      256577 :                     ele_res = negate( extract_l( L_shr( L_negate( ele_intermediate ), 22 ) ) ); /*Q0*/
    3003             :                 }
    3004             :                 ELSE
    3005             :                 {
    3006      349188 :                     ele_res = extract_l( L_shr( ele_intermediate, 22 ) ); /*Q0*/
    3007             :                 }
    3008             : 
    3009      605765 :                 azi[band] = s_max( -180, s_min( 180, azi_res ) ); /*Q0*/
    3010      605765 :                 move16();
    3011      605765 :                 ele[band] = s_max( -90, s_min( 180, ele_res ) ); /*Q0*/
    3012      605765 :                 move16();
    3013             :             }
    3014             : 
    3015      634336 :             IF( EQ_16( st_ivas->nchan_transport, 1 ) )
    3016             :             {
    3017             :                 Word32 w_en_norm_fx, f_scale_fx;
    3018             :                 Word16 q_w_en_norm_fx;
    3019      166952 :                 IF( active_w )
    3020             :                 {
    3021      166952 :                     IF( dtx_vad == 0 )
    3022             :                     {
    3023         888 :                         f_scale_fx = IVAS_ACTIVEW_DM_F_SCALE_DTX_FX; /*Q31*/
    3024         888 :                         move32();
    3025             :                     }
    3026             :                     ELSE
    3027             :                     {
    3028      166064 :                         IF( active_w_vlbr )
    3029             :                         {
    3030       66320 :                             f_scale_fx = IVAS_ACTIVEW_DM_F_SCALE_VLBR_FX; /*Q31*/
    3031       66320 :                             move32();
    3032             :                         }
    3033             :                         ELSE
    3034             :                         {
    3035       99744 :                             f_scale_fx = IVAS_ACTIVEW_DM_F_SCALE_FX; /*Q31*/
    3036       99744 :                             move32();
    3037             :                         }
    3038             :                     }
    3039             :                 }
    3040             :                 ELSE
    3041             :                 {
    3042           0 :                     f_scale_fx = 0;
    3043           0 :                     move32();
    3044             :                 }
    3045             : 
    3046      166952 :                 Word32 temp_result = Mpy_32_32( Mpy_32_32( f_scale_fx, g_pred_fx ), g_pred_fx ); /*Q31 - q_g_pred*/
    3047      166952 :                 temp_result = L_sub( L_shr( ONE_IN_Q31, q_g_pred ), temp_result );
    3048             : 
    3049      166952 :                 w_en_norm_fx = Mpy_32_32( temp_result, temp_result ); /*q_w_en_norm_fx*/
    3050      166952 :                 q_w_en_norm_fx = add( q_g_pred, q_g_pred );
    3051             : 
    3052      166952 :                 Pd_fx[0] = hMdDec->spar_md.band_coeffs[band].P_re_fx[1]; /*Q22*/
    3053      166952 :                 move32();
    3054      166952 :                 Pd_fx[1] = hMdDec->spar_md.band_coeffs[band].P_re_fx[0]; /*Q22*/
    3055      166952 :                 move32();
    3056      166952 :                 Pd_fx[2] = hMdDec->spar_md.band_coeffs[band].P_re_fx[2]; /*Q22*/
    3057      166952 :                 move32();
    3058             : 
    3059      166952 :                 en_ratio_fx = L_add( L_add( Mpy_32_32( PR_fx[0], PR_fx[0] ), Mpy_32_32( PR_fx[1], PR_fx[1] ) ), Mpy_32_32( PR_fx[2], PR_fx[2] ) );        // 22+22-31 = 13
    3060      166952 :                 Word32 Pd_temp_res = L_add( L_add( Mpy_32_32( Pd_fx[0], Pd_fx[0] ), Mpy_32_32( Pd_fx[1], Pd_fx[1] ) ), Mpy_32_32( Pd_fx[2], Pd_fx[2] ) ); // q = 22+22-31 = 13
    3061             : 
    3062      166952 :                 res_pow_fx = L_add( L_shr( w_en_norm_fx, sub( sub( 31, q_w_en_norm_fx ), 13 ) ), L_add( en_ratio_fx, Pd_temp_res ) ); /*Q13*/
    3063             : 
    3064      166952 :                 res_pow_fx = L_shr( res_pow_fx, 1 ); /*Q13*/
    3065             : 
    3066      166952 :                 hMdDec->spar_md.en_ratio_slow_fx[band] = L_add( Mpy_32_32( 1610612736 /*0.75f in Q31*/, hMdDec->spar_md.en_ratio_slow_fx[band] ), Mpy_32_32( 536870912 /*0.25f in Q31*/, en_ratio_fx ) ); /*Q13*/
    3067      166952 :                 move32();
    3068             : 
    3069      166952 :                 hMdDec->spar_md.ref_pow_slow_fx[band] = L_add( Mpy_32_32( 1610612736 /*0.75f in Q31*/, hMdDec->spar_md.ref_pow_slow_fx[band] ), Mpy_32_32( 536870912 /*0.25f in Q31*/, res_pow_fx ) ); /*Q13*/
    3070      166952 :                 move32();
    3071             : 
    3072      166952 :                 en_ratio_q = 31 - 13;
    3073      166952 :                 move16();
    3074      166952 :                 en_ratio_fx = Sqrt32( hMdDec->spar_md.en_ratio_slow_fx[band], &en_ratio_q ); /*Q31 - en_ratio_q*/
    3075      166952 :                 IF( en_ratio_q < 0 )
    3076             :                 {
    3077       74609 :                     en_ratio_fx = L_shr( en_ratio_fx, negate( en_ratio_q ) ); /*Q31*/
    3078       74609 :                     en_ratio_q = 0;
    3079       74609 :                     move16();
    3080             :                 }
    3081      166952 :                 Word32 en_ratio_fx_scaled = L_shr( en_ratio_fx, ( sub( sub( 31, en_ratio_q ), 13 ) ) ); /*Q13*/
    3082      166952 :                 IF( GT_32( en_ratio_fx_scaled, hMdDec->spar_md.ref_pow_slow_fx[band] ) )
    3083             :                 {
    3084       37122 :                     diffuseness_fx[band] = 0;
    3085       37122 :                     move32();
    3086             :                 }
    3087      129830 :                 ELSE IF( en_ratio_fx_scaled == 0 )
    3088             :                 {
    3089        2587 :                     diffuseness_fx[band] = ONE_IN_Q30; /*1.0f in Q30*/
    3090        2587 :                     move32();
    3091             :                 }
    3092      127243 :                 ELSE IF( EQ_32( en_ratio_fx_scaled, hMdDec->spar_md.ref_pow_slow_fx[band] ) )
    3093             :                 {
    3094          54 :                     diffuseness_fx[band] = ONE_IN_Q30; /*1.0f in Q30*/
    3095          54 :                     move32();
    3096             :                 }
    3097             :                 ELSE
    3098             :                 {
    3099      127189 :                     en_ratio_fx = divide3232( en_ratio_fx_scaled, L_add( hMdDec->spar_md.ref_pow_slow_fx[band], EPSILON_FX ) ); /*Q15*/
    3100      127189 :                     en_ratio_fx = L_shl( en_ratio_fx, 15 );                                                                     /*Q30*/
    3101      127189 :                     diffuseness_fx[band] = L_sub( ONE_IN_Q30, en_ratio_fx );
    3102      127189 :                     move32();
    3103             :                 }
    3104             :             }
    3105             :             ELSE
    3106             :             {
    3107      467384 :                 en_ratio_fx = L_add( L_add( Mpy_32_32( PR_fx[0], PR_fx[0] ), Mpy_32_32( PR_fx[1], PR_fx[1] ) ), Mpy_32_32( PR_fx[2], PR_fx[2] ) ); /*Q13*/
    3108             : 
    3109      467384 :                 hMdDec->spar_md.en_ratio_slow_fx[band] = L_add( Mpy_32_32( 1610612736 /*0.75f in Q31*/, hMdDec->spar_md.en_ratio_slow_fx[band] ), Mpy_32_32( 536870912 /*0.25f in Q31*/, en_ratio_fx ) );
    3110      467384 :                 move32();
    3111             : 
    3112      467384 :                 en_ratio_q = 31 - 13;
    3113      467384 :                 move16();
    3114      467384 :                 en_ratio_fx = Sqrt32( hMdDec->spar_md.en_ratio_slow_fx[band], &en_ratio_q ); /*Q31 - en_ratio_q*/
    3115      467384 :                 IF( en_ratio_q < 0 )
    3116             :                 {
    3117      200512 :                     en_ratio_fx = L_shr( en_ratio_fx, ( -en_ratio_q ) ); /*Q31*/
    3118      200512 :                     en_ratio_q = 0;
    3119      200512 :                     move16();
    3120             :                 }
    3121      467384 :                 Word32 en_ratio_fx_scaled = L_shr( en_ratio_fx, 1 ); /*Q30*/
    3122      467384 :                 IF( GT_32( en_ratio_fx_scaled, ONE_IN_Q30 ) )
    3123             :                 {
    3124           0 :                     diffuseness_fx[band] = 0;
    3125           0 :                     move32();
    3126             :                 }
    3127             :                 ELSE
    3128             :                 {
    3129      467384 :                     diffuseness_fx[band] = L_sub( ONE_IN_Q30, en_ratio_fx_scaled ); /*Q30*/
    3130      467384 :                     move32();
    3131             :                 }
    3132             :             }
    3133             :         }
    3134             : 
    3135      713628 :         FOR( band = start_band; band < end_band; band++ )
    3136             :         {
    3137             :             Word16 azi_dith, ele_dith;
    3138      634336 :             tmp_write_idx_param_band = hDirAC->spar_to_dirac_write_idx;
    3139      634336 :             move16();
    3140             : 
    3141      634336 :             en_ratio_fx = L_sub( ONE_IN_Q30, diffuseness_fx[band] ); /*Q30*/
    3142             : 
    3143      634336 :             masa_sq_fx( L_sub( ONE_IN_Q30, en_ratio_fx ), diffuseness_thresholds_fx, DIRAC_DIFFUSE_LEVELS );
    3144             : 
    3145             : 
    3146      634336 :             qmf_band_start = band_grouping[band]; /*Q0*/
    3147      634336 :             move16();
    3148      634336 :             qmf_band_end = band_grouping[band + 1]; /*Q0*/
    3149      634336 :             move16();
    3150             : 
    3151     3171680 :             FOR( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
    3152             :             {
    3153             :                 Word16 ts_start, ts_end, ts;
    3154             : 
    3155     2537344 :                 ts_start = DirAC_block_grouping[block]; /*Q0*/
    3156     2537344 :                 move16();
    3157     2537344 :                 ts_end = DirAC_block_grouping[block + 1];
    3158     2537344 :                 move16();
    3159     6026192 :                 FOR( b = qmf_band_start; b < qmf_band_end; b++ ) /*Q0*/
    3160             :                 {
    3161             : 
    3162     3488848 :                     azi_dith = azi[band]; /*Q0*/
    3163     3488848 :                     move16();
    3164     3488848 :                     ele_dith = ele[band]; /*Q0*/
    3165     3488848 :                     move16();
    3166             : 
    3167             : 
    3168     3488848 :                     hSpatParamRendCom->energy_ratio1_fx[block][b] = en_ratio_fx; /*Q30*/
    3169     3488848 :                     move32();
    3170     3488848 :                     tmp_write_idx_band = tmp_write_idx_param_band; /*Q0*/
    3171     3488848 :                     move16();
    3172             : 
    3173     3488848 :                     IF( hDirAC->hConfig->dec_param_estim == FALSE )
    3174             :                     {
    3175     1593504 :                         hSpatParamRendCom->elevation[tmp_write_idx_band][b] = ele_dith; /*Q0*/
    3176     1593504 :                         move16();
    3177     1593504 :                         hSpatParamRendCom->azimuth[tmp_write_idx_band][b] = azi_dith; /*Q0*/
    3178     1593504 :                         move16();
    3179             : 
    3180     1593504 :                         hSpatParamRendCom->diffuseness_vector_fx[tmp_write_idx_band][b] = diffuseness_fx[band]; /*Q30*/
    3181     1593504 :                         move32();
    3182             :                     }
    3183             :                     ELSE
    3184             :                     {
    3185     9476720 :                         FOR( ts = ts_start; ts < ts_end; ts++ )
    3186             :                         {
    3187     7581376 :                             hSpatParamRendCom->elevation[tmp_write_idx_band][b] = ele_dith; /*Q0*/
    3188     7581376 :                             move16();
    3189     7581376 :                             hSpatParamRendCom->azimuth[tmp_write_idx_band][b] = azi_dith; /*Q0*/
    3190     7581376 :                             move16();
    3191             : 
    3192     7581376 :                             hSpatParamRendCom->diffuseness_vector_fx[tmp_write_idx_band][b] = diffuseness_fx[band]; /*Q30*/
    3193     7581376 :                             move32();
    3194     7581376 :                             tmp_write_idx_band = add( tmp_write_idx_band, 1 ) % hSpatParamRendCom->dirac_md_buffer_length; /*Q0*/
    3195     7581376 :                             move16();
    3196             :                         }
    3197             :                     }
    3198             :                 }
    3199     2537344 :                 tmp_write_idx_param_band = add( tmp_write_idx_param_band, num_slots_in_subfr ) % hSpatParamRendCom->dirac_md_buffer_length;
    3200     2537344 :                 move16();
    3201             :             }
    3202             :         }
    3203             : 
    3204             :         /* update buffer write index */
    3205       79292 :         IF( hDirAC->hConfig->dec_param_estim == FALSE )
    3206             :         {
    3207       36216 :             hDirAC->spar_to_dirac_write_idx = add( hDirAC->spar_to_dirac_write_idx, MAX_PARAM_SPATIAL_SUBFRAMES ) % hSpatParamRendCom->dirac_md_buffer_length; /*Q0*/
    3208       36216 :             move16();
    3209             :         }
    3210             :         ELSE
    3211             :         {
    3212       43076 :             hDirAC->spar_to_dirac_write_idx = add( hDirAC->spar_to_dirac_write_idx, CLDFB_NO_COL_MAX ) % hSpatParamRendCom->dirac_md_buffer_length; /*Q0*/
    3213       43076 :             move16();
    3214             :         }
    3215             :     }
    3216             :     ELSE
    3217             :     {
    3218       51748 :         band = end_band;
    3219       51748 :         move16();
    3220             :     }
    3221             : 
    3222             :     /*read DirAC metadata, convert DirAC to SPAR*/
    3223      632992 :     FOR( ; band < idiv1616( num_bands_out, bw ); band++ )
    3224             :     {
    3225             :         Word16 dirac_band_idx;
    3226             : 
    3227      501952 :         dirac_band_idx = sub( dirac_to_spar_md_bands[band], enc_param_start_band ); /*Q0*/
    3228             : 
    3229      501952 :         num_subframes = MAX_PARAM_SPATIAL_SUBFRAMES;
    3230      501952 :         move16();
    3231      501952 :         if ( st_ivas->hQMetaData->useLowerRes )
    3232             :         {
    3233       43860 :             num_subframes = 1;
    3234       43860 :             move16();
    3235             :         }
    3236             : 
    3237     2378180 :         FOR( block = 0; block < num_subframes; block++ )
    3238             :         {
    3239             : 
    3240     1876228 :             IF( st_ivas->hQMetaData->q_direction->band_data[dirac_band_idx].azimuth_fx[block] < 0 )
    3241             :             {
    3242      584532 :                 st_ivas->hQMetaData->q_direction->band_data[dirac_band_idx].azimuth_fx[block] =
    3243      292266 :                     L_add( L_shl( 360, 22 ), st_ivas->hQMetaData->q_direction->band_data[dirac_band_idx].azimuth_fx[block] ); /*Q22*/
    3244      292266 :                 move32();
    3245             :             }
    3246             : 
    3247     1876228 :             azi_dirac_fx[band][block] = st_ivas->hQMetaData->q_direction->band_data[dirac_band_idx].azimuth_fx[block]; /*Q22*/
    3248     1876228 :             move32();
    3249     1876228 :             ele_dirac_fx[band][block] = st_ivas->hQMetaData->q_direction->band_data[dirac_band_idx].elevation_fx[block]; /*Q22*/
    3250     1876228 :             move32();
    3251             :         }
    3252             : 
    3253      501952 :         diffuseness_fx[band] = L_sub( ONE_IN_Q30, st_ivas->hQMetaData->q_direction->band_data[dirac_band_idx].energy_ratio_fx[0] ); /*Q30*/
    3254      501952 :         move32();
    3255             :     }
    3256             : 
    3257             :     /* DirAC MD averaged over 4 subframes and converted to SPAR format similar to encoder processing */
    3258      131040 :     IF( GT_16( hMdDec->spar_md_cfg.nchan_transport, 1 ) )
    3259             :     {
    3260             :         Word16 order;
    3261       93446 :         IF( hMdDec->spar_hoa_md_flag )
    3262             :         {
    3263       10949 :             order = 1;
    3264       10949 :             move16();
    3265             :         }
    3266             :         ELSE
    3267             :         {
    3268       82497 :             order = sba_order_internal;
    3269       82497 :             move16();
    3270             :         }
    3271       93446 :         ivas_get_spar_md_from_dirac_fx( azi_dirac_fx, ele_dirac_fx, diffuseness_fx, 1, NULL, NULL, &hMdDec->spar_md, &hMdDec->spar_md_cfg, end_band, num_bands_out, order, dtx_vad, NULL, st_ivas->hQMetaData->useLowerRes, active_w_vlbr, dyn_active_w_flag );
    3272             : 
    3273             :         /* temporarily copy frame-wise prediction coefficients in DirAC bands*/
    3274      373784 :         FOR( pred_idx = 0; pred_idx < FOA_CHANNELS - 1; pred_idx++ )
    3275             :         {
    3276     1401690 :             FOR( band = SPAR_DIRAC_SPLIT_START_BAND; band < IVAS_MAX_NUM_BANDS; band++ )
    3277             :             {
    3278     1121352 :                 pred_re_20ms_fx[band][pred_idx] = hMdDec->spar_md.band_coeffs[band].pred_re_fx[pred_idx]; /*Q22*/
    3279     1121352 :                 move32();
    3280             :             }
    3281             :         }
    3282             :     }
    3283             : 
    3284             :     Word16 num_md_sub_frames;
    3285      131040 :     num_md_sub_frames = ivas_get_spar_dec_md_num_subframes( sba_order_internal, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->last_active_ivas_total_brate );
    3286             : 
    3287             :     Word16 order;
    3288      131040 :     IF( hMdDec->spar_hoa_md_flag )
    3289             :     {
    3290       10949 :         order = 1;
    3291       10949 :         move16();
    3292             :     }
    3293             :     ELSE
    3294             :     {
    3295      120091 :         order = sba_order_internal;
    3296      120091 :         move16();
    3297             :     }
    3298      131040 :     ivas_get_spar_md_from_dirac_fx( azi_dirac_fx, ele_dirac_fx, diffuseness_fx, num_md_sub_frames, NULL, NULL, &hMdDec->spar_md, &hMdDec->spar_md_cfg, end_band, idiv1616( num_bands_out, bw ), order, dtx_vad, NULL, st_ivas->hQMetaData->useLowerRes, active_w_vlbr, dyn_active_w_flag );
    3299             : 
    3300      131040 :     test();
    3301      131040 :     IF( st_ivas->hQMetaData->useLowerRes && dtx_vad )
    3302             :     {
    3303       54715 :         FOR( band = SPAR_DIRAC_SPLIT_START_BAND; band < IVAS_MAX_NUM_BANDS; band++ )
    3304             :         {
    3305       43772 :             FOR( block = 1; block < num_md_sub_frames; block++ )
    3306             :             {
    3307           0 :                 FOR( i = 0; i < FOA_CHANNELS - 1; i++ ) /* pred coefficient index (index 0, 1, 2 predicts Y, Z, X respectively) */
    3308             :                 {
    3309           0 :                     hMdDec->spar_md.band_coeffs[( band + ( block * IVAS_MAX_NUM_BANDS ) )].pred_re_fx[i] = hMdDec->spar_md.band_coeffs[band].pred_re_fx[i]; /*Q22*/
    3310           0 :                     move32();
    3311             :                 }
    3312           0 :                 FOR( i = 0; i < FOA_CHANNELS - 1; i++ ) /* pred coefficient index (index 0, 1, 2 predicts Y, Z, X respectively) */
    3313             :                 {
    3314           0 :                     hMdDec->spar_md.band_coeffs[( band + ( block * IVAS_MAX_NUM_BANDS ) )].P_re_fx[i] = hMdDec->spar_md.band_coeffs[band].P_re_fx[i]; /*Q22*/
    3315           0 :                     move32();
    3316             :                 }
    3317             :             }
    3318             :         }
    3319             :     }
    3320             : 
    3321             :     /* expand DirAC TC 20ms MD for residual channels to all subframes*/
    3322      622305 :     FOR( block = 0; block < num_md_sub_frames; block++ )
    3323             :     {
    3324     2456325 :         FOR( band = SPAR_DIRAC_SPLIT_START_BAND; band < IVAS_MAX_NUM_BANDS; band++ )
    3325             :         {
    3326     7860240 :             FOR( pred_idx = 0; pred_idx < FOA_CHANNELS - 1; pred_idx++ ) /* pred coefficient index (index 0, 1, 2 predicts Y, Z, X respectively) */
    3327             :             {
    3328     5895180 :                 IF( ivas_is_res_channel( add( pred_idx, 1 ), hMdDec->spar_md_cfg.nchan_transport ) )
    3329             :                 {
    3330             :                     /* use 20ms coefficients only for residual channels */
    3331     2833824 :                     hMdDec->spar_md.band_coeffs[( band + ( block * IVAS_MAX_NUM_BANDS ) )].pred_re_fx[pred_idx] = pred_re_20ms_fx[band][pred_idx]; /*Q22*/
    3332     2833824 :                     move32();
    3333             :                 }
    3334             :             }
    3335             :         }
    3336             :     }
    3337             : 
    3338      632992 :     FOR( b = i_mult( end_band, bw ); b < num_bands_out; b++ )
    3339             :     {
    3340      501952 :         hMdDec->valid_bands[b] = 1;
    3341      501952 :         move16();
    3342             :     }
    3343             : 
    3344      131040 :     return;
    3345             : }

Generated by: LCOV version 1.14