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

Generated by: LCOV version 1.14