LCOV - code coverage report
Current view: top level - lib_enc - ivas_mc_param_enc_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 574a190e3c6896c6c4ed10d7f23649709a0c4347 Lines: 850 882 96.4 %
Date: 2025-06-27 02:59:36 Functions: 14 14 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             : // helper macros to convert the 64 bitt accumulators into the 48 bit float format
      34             : #define CONVERT_CY( x_64, y_fx, y_e )              \
      35             :     {                                              \
      36             :         Word16 norm;                               \
      37             :         norm = W_norm( x_64 );                     \
      38             :         y_fx = W_extract_h( W_shl( x_64, norm ) ); \
      39             :         y_e = sub( sub62gb, norm );                \
      40             :     }
      41             : #define CONVERT_DMX( x_64, y_fx, y_e )             \
      42             :     {                                              \
      43             :         Word16 norm;                               \
      44             :         norm = W_norm( x_64 );                     \
      45             :         y_fx = W_extract_h( W_shl( x_64, norm ) ); \
      46             :         y_e = sub( sub35gb, norm );                \
      47             :     }
      48             : #include <math.h>
      49             : #include <assert.h>
      50             : #include "options.h"
      51             : #include "cnst.h"
      52             : #include "rom_enc.h"
      53             : #include "ivas_rom_enc.h"
      54             : #include "rom_com.h"
      55             : #include "prot_fx.h"
      56             : #include "ivas_prot_fx.h"
      57             : #include "ivas_cnst.h"
      58             : #include "ivas_rom_com.h"
      59             : #include "wmc_auto.h"
      60             : 
      61             : #include "prot_fx_enc.h"
      62             : 
      63             : /*-------------------------------------------------------------------------
      64             :  * Local function prototypes
      65             :  *------------------------------------------------------------------------*/
      66             : 
      67             : static void ivas_param_mc_write_bs_fx( const PARAM_MC_ENC_HANDLE hParamMC, Word16 *ILD_idx, Word16 *ICC_idx, UWord16 bit_buffer[PARAM_MC_MAX_BITS], Word16 *bit_pos );
      68             : 
      69             : static void ivas_param_mc_dec2bin_fx( const Word16 val, const Word16 N, UWord16 bits[PARAM_MC_MAX_BITS] );
      70             : 
      71             : static void ivas_param_mc_encode_parameter_fx( Word16 *idx_in, HANDLE_IVAS_PARAM_MC_METADATA hMetadataPMC, HANDLE_PARAM_MC_PARAMETER_CODING_INFO hParameterCodingInfo, const Word16 nbands, const Word16 band_step, const Word16 map_size_wo_lfe, const Word16 map_size, UWord16 bit_buffer[PARAM_MC_MAX_BITS], Word16 *bit_pos );
      72             : 
      73             : static void ivas_param_mc_range_encoder_fx( const Word16 *seq_in, const Word16 num_symbols, const UWord16 *cum_freq, const UWord16 *sym_freq, const UWord16 tot_shift, const Word16 max_nb_bits, UWord16 *bit_buffer, Word16 *bit_pos );
      74             : 
      75             : 
      76             : #define ATTACKTHRESHOLD_E 4
      77             : static void ivas_param_mc_quantize_ilds_fx( PARAM_MC_ENC_HANDLE hParamMC, Word32 Cy_fx[MAX_CICP_CHANNELS][MAX_CICP_CHANNELS], Word16 Cy_e[MAX_CICP_CHANNELS][MAX_CICP_CHANNELS], Word32 Cx_fx[PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS], Word16 Cx_e[PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS], const Word16 freq_idx, const Word16 nchan_input, const Word16 nchan_transport, Word16 *ILD_idx_out, Word16 ILD_q[PARAM_MC_SZ_ILD_MAP] );
      78             : 
      79             : static void ivas_param_mc_parameter_quantizer_fx( const Word32 *x, const Word16 *x_e, const Word16 L, const Word16 sz_quantizer, const Word16 *quantizer_fx, const Word16 Q_quant, Word16 *quant_idx, Word16 *y );
      80             : 
      81             : static void ivas_param_mc_quantize_iccs_fx( PARAM_MC_ENC_HANDLE hParamMC, Word32 Cy_fx[MAX_CICP_CHANNELS][MAX_CICP_CHANNELS], Word16 Cy_e[MAX_CICP_CHANNELS][MAX_CICP_CHANNELS], const Word16 freq_idx, const Word16 nchan_input, Word16 *ICC_idx_out );
      82             : 
      83             : static void ivas_param_mc_dmx_fx( PARAM_MC_ENC_HANDLE hParamMC, Word32 *data_f_fx[], Word32 data_dmx_fx[][L_FRAME48k], const Word16 input_frame, const Word16 nchan_input, const Word16 nchan_transport );
      84             : 
      85             : static void ivas_param_mc_transient_detection_fx( PARAM_MC_ENC_HANDLE hParamMC, TRAN_DET_HANDLE hTranDet, Word16 *bAttackPresent, Word16 *attackIdx );
      86             : 
      87             : static void ivas_param_mc_param_est_enc_fx( PARAM_MC_ENC_HANDLE hParamMC, Word32 *data_f[], Word32 Cy_sum_fx[][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS], Word16 Cy_sum_e[][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS], Word32 Cx_sum_fx[][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS], Word16 Cx_sum_e[][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS], const Word16 input_frame, const Word16 nchan_input, const Word16 nchan_transport );
      88             : 
      89             : 
      90             : /*-------------------------------------------------------------------------
      91             :  * ivas_param_mc_enc_open()
      92             :  *
      93             :  * Initialize Parametric MC encoder handle
      94             :  *------------------------------------------------------------------------*/
      95             : 
      96         258 : ivas_error ivas_param_mc_enc_open_fx(
      97             :     Encoder_Struct *st_ivas /* i/o: IVAS encoder handle          */
      98             : )
      99             : {
     100             :     Word16 i;
     101             :     IVAS_FB_CFG *fb_cfg;
     102             :     PARAM_MC_ENC_HANDLE hParamMC;
     103             :     UWord16 config_index;
     104             :     MC_LS_SETUP mc_input_setup;
     105             :     Word16 max_bwidth, nchan_inp;
     106             :     Word16 tmp1, tmp2;
     107             :     Word32 input_Fs, ivas_total_brate;
     108             :     ivas_error error;
     109             : 
     110         258 :     error = IVAS_ERR_OK;
     111         258 :     move16();
     112             : 
     113             :     /* Sanity Checks */
     114         258 :     IF( ( hParamMC = (PARAM_MC_ENC_HANDLE) malloc( sizeof( PARAM_MC_ENC_DATA ) ) ) == NULL )
     115             :     {
     116           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Paramtric MC\n" ) );
     117             :     }
     118             : 
     119         258 :     mc_input_setup = st_ivas->hEncoderConfig->mc_input_setup;
     120         258 :     move32();
     121         258 :     max_bwidth = st_ivas->hEncoderConfig->max_bwidth;
     122         258 :     move16();
     123         258 :     input_Fs = st_ivas->hEncoderConfig->input_Fs;
     124         258 :     move32();
     125         258 :     nchan_inp = st_ivas->hEncoderConfig->nchan_inp;
     126         258 :     move16();
     127         258 :     ivas_total_brate = st_ivas->hEncoderConfig->ivas_total_brate;
     128         258 :     move32();
     129             : 
     130             :     /* Preparing Config */
     131         258 :     hParamMC->lfe_index = LFE_CHANNEL;
     132         258 :     move16();
     133         258 :     st_ivas->nchan_transport = ivas_param_mc_getNumTransportChannels_fx( ivas_total_brate, mc_input_setup );
     134         258 :     move16();
     135             : 
     136             :     /* get configuration index */
     137         258 :     config_index = ivas_param_mc_get_configuration_index_fx( mc_input_setup, ivas_total_brate );
     138             : 
     139             :     /* set core coder dependent on the number of transport channels */
     140         258 :     SWITCH( st_ivas->nchan_transport )
     141             :     {
     142          17 :         case 4:
     143             :         case 3:
     144          17 :             st_ivas->nCPE = 2;
     145          17 :             move16();
     146          17 :             st_ivas->nSCE = 0;
     147          17 :             move16();
     148          17 :             st_ivas->hEncoderConfig->element_mode_init = IVAS_CPE_MDCT;
     149          17 :             move16();
     150          17 :             BREAK;
     151         241 :         case 2:
     152         241 :             st_ivas->nCPE = 1;
     153         241 :             move16();
     154         241 :             st_ivas->nSCE = 0;
     155         241 :             move16();
     156         241 :             st_ivas->hEncoderConfig->element_mode_init = IVAS_CPE_MDCT;
     157         241 :             move16();
     158         241 :             BREAK;
     159             :     }
     160             : 
     161             :     /* get dmx factors */
     162         258 :     hParamMC->dmx_factors_fx = ivas_param_mc_conf[config_index].dmx_fac_fx; // Q31
     163             : 
     164             :     /* set FB config. */
     165         258 :     IF( NE_32( ( error = ivas_fb_set_cfg( &fb_cfg, MC_FORMAT, nchan_inp, 0, 0, input_Fs, 0 ) ), IVAS_ERR_OK ) )
     166             :     {
     167           0 :         return error;
     168             :     }
     169             : 
     170             :     /* Allocate and initialize FB mixer handle */
     171         258 :     IF( NE_32( ( error = ivas_FB_mixer_open_fx( &( hParamMC->hFbMixer ), input_Fs, fb_cfg, 0 ) ), IVAS_ERR_OK ) )
     172             :     {
     173           0 :         return error;
     174             :     }
     175             : 
     176             :     /* open/init parameter coding */
     177         258 :     ivas_param_mc_metadata_open_fx( mc_input_setup, ivas_total_brate, &hParamMC->hMetadataPMC );
     178             : 
     179             :     /* Band Grouping */
     180         258 :     IF( EQ_16( hParamMC->hMetadataPMC.num_parameter_bands, 20 ) )
     181             :     {
     182           3 :         Copy( param_mc_band_grouping_20, hParamMC->band_grouping, 20 + 1 );
     183             :     }
     184         255 :     ELSE IF( EQ_16( hParamMC->hMetadataPMC.num_parameter_bands, 14 ) )
     185             :     {
     186         119 :         Copy( param_mc_band_grouping_14, hParamMC->band_grouping, 14 + 1 );
     187             :     }
     188         136 :     ELSE IF( EQ_16( hParamMC->hMetadataPMC.num_parameter_bands, 10 ) )
     189             :     {
     190         136 :         Copy( param_mc_band_grouping_10, hParamMC->band_grouping, 10 + 1 );
     191             :     }
     192             :     ELSE
     193             :     {
     194           0 :         assert( 0 && "nbands must be 20, 14, or 10!" );
     195             :     }
     196             : 
     197             :     /* set max parameter band for abs cov */
     198         258 :     i = 0;
     199         258 :     move16();
     200        2314 :     WHILE( hParamMC->band_grouping[i] <= PARAM_MC_MAX_BAND_ABS_COV_ENC )
     201             :     {
     202        2056 :         hParamMC->max_param_band_abs_cov = i;
     203        2056 :         move16();
     204        2056 :         i = add( i, 1 );
     205             :     }
     206             : 
     207             :     /* parameter band grouping: 60 band CLDFB to 240 band MDFT resolution */
     208        3602 :     FOR( i = 0; i < hParamMC->hMetadataPMC.num_parameter_bands + 1; i++ )
     209             :     {
     210        3344 :         hParamMC->band_grouping[i] = i_mult( hParamMC->band_grouping[i], PARAM_MC_CLDFB_TO_MDFT_FAC );
     211        3344 :         move16();
     212             :     }
     213             : 
     214             :     /* set correct coded band width */
     215         258 :     hParamMC->hMetadataPMC.coded_bwidth = max_bwidth;
     216         258 :     move16();
     217         258 :     hParamMC->hMetadataPMC.last_coded_bwidth = max_bwidth;
     218         258 :     move16();
     219         258 :     ivas_param_mc_set_coded_bands_fx( &hParamMC->hMetadataPMC );
     220             : 
     221             :     /* initialize offset for transient detection */
     222         258 :     tmp1 = NS2SA_FX2( input_Fs, DELAY_DIRAC_ENC_CMP_NS );
     223         258 :     move16();
     224         258 :     tmp2 = NS2SA_FX2( input_Fs, 2 * DIRAC_SLOT_NS );
     225         258 :     move16();
     226         258 :     tmp1 = idiv1616( sub( add( tmp1, tmp2 ), 1 ), tmp2 );
     227         258 :     hParamMC->transient_detector_delay = sub( ( NSUBBLOCKS_SHIFT + 1 ) + NSUBBLOCKS + 1, tmp1 );
     228         258 :     move16();
     229             : 
     230             :     /* Init total/dmx ener factors */
     231         258 :     set32_fx( hParamMC->ener_fac_fx, 0, PARAM_MC_MAX_PARAMETER_BANDS ); // Q21
     232             : 
     233             :     /* init previous ILDs */
     234        5418 :     FOR( i = 0; i < PARAM_MC_MAX_PARAMETER_BANDS; i++ )
     235             :     {
     236        5160 :         set32_fx( hParamMC->prev_ilds_fx[i], 0, PARAM_MC_SZ_ILD_MAP ); // Q21
     237             :     }
     238             : 
     239         258 :     st_ivas->hParamMC = hParamMC;
     240             : 
     241         258 :     return error;
     242             : }
     243             : 
     244             : 
     245             : /*-------------------------------------------------------------------------
     246             :  * ivas_param_mc_enc_reconfig()
     247             :  *
     248             :  * Reconfigure Parametric MC encoder
     249             :  *------------------------------------------------------------------------*/
     250             : 
     251          60 : ivas_error ivas_param_mc_enc_reconfig_fx(
     252             :     Encoder_Struct *st_ivas /* i/o: IVAS encoder handle          */
     253             : )
     254             : {
     255             :     Word16 i;
     256             :     PARAM_MC_ENC_HANDLE hParamMC;
     257             :     UWord16 config_index;
     258             :     MC_LS_SETUP mc_input_setup;
     259             :     Word16 max_bwidth;
     260             :     Word16 tmp1, tmp2;
     261             :     Word32 input_Fs, ivas_total_brate;
     262             :     ivas_error error;
     263             : 
     264          60 :     error = IVAS_ERR_OK;
     265          60 :     move16();
     266             : 
     267          60 :     mc_input_setup = st_ivas->hEncoderConfig->mc_input_setup;
     268          60 :     move32();
     269          60 :     max_bwidth = st_ivas->hEncoderConfig->max_bwidth;
     270          60 :     move16();
     271          60 :     input_Fs = st_ivas->hEncoderConfig->input_Fs;
     272          60 :     move32();
     273          60 :     ivas_total_brate = st_ivas->hEncoderConfig->ivas_total_brate;
     274          60 :     move32();
     275          60 :     hParamMC = st_ivas->hParamMC;
     276             : 
     277             :     /* Preparing Config */
     278          60 :     st_ivas->nchan_transport = ivas_param_mc_getNumTransportChannels_fx( ivas_total_brate, mc_input_setup );
     279          60 :     move16();
     280             : 
     281             :     /* get configuration index */
     282          60 :     config_index = ivas_param_mc_get_configuration_index_fx( mc_input_setup, ivas_total_brate );
     283             : 
     284             :     /* set core coder dependent on the number of transport channels */
     285          60 :     SWITCH( st_ivas->nchan_transport )
     286             :     {
     287           0 :         case 4:
     288             :         case 3:
     289           0 :             st_ivas->nCPE = 2;
     290           0 :             move16();
     291           0 :             st_ivas->nSCE = 0;
     292           0 :             move16();
     293           0 :             st_ivas->hEncoderConfig->element_mode_init = IVAS_CPE_MDCT;
     294           0 :             move16();
     295           0 :             BREAK;
     296          60 :         case 2:
     297          60 :             st_ivas->nCPE = 1;
     298          60 :             move16();
     299          60 :             st_ivas->nSCE = 0;
     300          60 :             move16();
     301          60 :             st_ivas->hEncoderConfig->element_mode_init = IVAS_CPE_MDCT;
     302          60 :             move16();
     303          60 :             BREAK;
     304             :     }
     305             : 
     306             :     /* get dmx factors */
     307          60 :     hParamMC->dmx_factors_fx = ivas_param_mc_conf[config_index].dmx_fac_fx; // Q31
     308             : 
     309             :     /* open/init parameter coding */
     310          60 :     ivas_param_mc_metadata_open_fx( mc_input_setup, ivas_total_brate, &hParamMC->hMetadataPMC );
     311             : 
     312             :     /* Band Grouping */
     313          60 :     IF( EQ_16( hParamMC->hMetadataPMC.num_parameter_bands, 20 ) )
     314             :     {
     315           0 :         Copy( param_mc_band_grouping_20, hParamMC->band_grouping, 20 + 1 );
     316             :     }
     317          60 :     ELSE IF( EQ_16( hParamMC->hMetadataPMC.num_parameter_bands, 14 ) )
     318             :     {
     319          30 :         Copy( param_mc_band_grouping_14, hParamMC->band_grouping, 14 + 1 );
     320             :     }
     321          30 :     ELSE IF( EQ_16( hParamMC->hMetadataPMC.num_parameter_bands, 10 ) )
     322             :     {
     323          30 :         Copy( param_mc_band_grouping_10, hParamMC->band_grouping, 10 + 1 );
     324             :     }
     325             :     ELSE
     326             :     {
     327           0 :         assert( 0 && "nbands must be 20, 14, or 10!" );
     328             :     }
     329             : 
     330             :     /* set max parameter band for abs cov */
     331          60 :     i = 0;
     332          60 :     move16();
     333         540 :     WHILE( hParamMC->band_grouping[i] <= PARAM_MC_MAX_BAND_ABS_COV_ENC )
     334             :     {
     335         480 :         hParamMC->max_param_band_abs_cov = i;
     336         480 :         move16();
     337         480 :         i = add( i, 1 );
     338             :     }
     339             : 
     340             :     /* parameter band grouping: 60 band CLDFB to 240 band MDFT resolution */
     341         840 :     FOR( i = 0; i < hParamMC->hMetadataPMC.num_parameter_bands + 1; i++ )
     342             :     {
     343         780 :         hParamMC->band_grouping[i] = i_mult( hParamMC->band_grouping[i], PARAM_MC_CLDFB_TO_MDFT_FAC );
     344         780 :         move16();
     345             :     }
     346             : 
     347             :     /* set correct coded band width */
     348          60 :     hParamMC->hMetadataPMC.coded_bwidth = max_bwidth;
     349          60 :     move16();
     350          60 :     hParamMC->hMetadataPMC.last_coded_bwidth = max_bwidth;
     351          60 :     move16();
     352          60 :     ivas_param_mc_set_coded_bands_fx( &hParamMC->hMetadataPMC );
     353             : 
     354             :     /* initialize offset for transient detection */
     355          60 :     tmp1 = NS2SA_FX2( input_Fs, DELAY_DIRAC_ENC_CMP_NS );
     356          60 :     move16();
     357          60 :     tmp2 = NS2SA_FX2( input_Fs, 2 * DIRAC_SLOT_NS );
     358          60 :     move16();
     359          60 :     tmp1 = idiv1616( sub( add( tmp1, tmp2 ), 1 ), tmp2 );
     360          60 :     hParamMC->transient_detector_delay = sub( ( NSUBBLOCKS_SHIFT + 1 ) + NSUBBLOCKS + 1, tmp1 );
     361          60 :     move16();
     362             : 
     363             :     /* Init total/dmx ener factors */
     364          60 :     set32_fx( hParamMC->ener_fac_fx, 0, PARAM_MC_MAX_PARAMETER_BANDS ); // Q21
     365             : 
     366             : 
     367          60 :     return error;
     368             : }
     369             : 
     370             : 
     371             : /*-------------------------------------------------------------------------
     372             :  * ivas_param_mc_enc_close()
     373             :  *
     374             :  * Close Parametric MC encoder handle
     375             :  *------------------------------------------------------------------------*/
     376             : 
     377        1164 : void ivas_param_mc_enc_close_fx(
     378             :     PARAM_MC_ENC_HANDLE *hParamMC, /* i/o: Parametric MC encoder handle        */
     379             :     const Word32 sampling_rate )
     380             : {
     381        1164 :     test();
     382        1164 :     IF( hParamMC == NULL || *hParamMC == NULL )
     383             :     {
     384         906 :         return;
     385             :     }
     386             : 
     387         258 :     ivas_FB_mixer_close_fx( &( *hParamMC )->hFbMixer, sampling_rate, 0 );
     388             : 
     389         258 :     free( ( *hParamMC ) );
     390         258 :     ( *hParamMC ) = NULL;
     391             : 
     392         258 :     return;
     393             : }
     394             : 
     395             : 
     396             : /*-------------------------------------------------------------------------
     397             :  * ivas_param_mc_enc()
     398             :  *
     399             :  * Parametric MC Encoder main encoding function
     400             :  *------------------------------------------------------------------------*/
     401             : 
     402        9960 : void ivas_param_mc_enc_fx(
     403             :     Encoder_Struct *st_ivas,   /* i/o: IVAS Encoder handle                */
     404             :     BSTR_ENC_HANDLE hMetaData, /* i/o: IVAS Metadata bitstream handle     */
     405             :     Word32 *data_f_fx[],       /* i/o: input/transport MC data       Q11  */
     406             :     const Word16 input_frame   /* i  : input frame length                 */
     407             : )
     408             : {
     409             :     Word16 k;
     410             :     Word16 ILD_idx[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_SZ_ILD_MAP];
     411             :     Word16 ICC_idx[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_SZ_ICC_MAP];
     412             :     UWord16 bit_buffer[PARAM_MC_MAX_BITS];
     413             :     Word16 bit_pos;
     414             :     Word16 band_step;
     415             :     Word16 data_f_fx16[L_FRAME48k];
     416             :     Word32 data_dmx_fx[PARAM_MC_MAX_TRANSPORT_CHANS][L_FRAME48k];
     417             :     Word16 data_dmx_fx16[PARAM_MC_MAX_TRANSPORT_CHANS][L_FRAME48k];
     418             :     Word32 Cy_sum_fx[PARAM_MC_MAX_PARAMETER_BANDS][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS];
     419             :     Word16 Cy_sum_e[PARAM_MC_MAX_PARAMETER_BANDS][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS];
     420             :     Word32 Cx_sum_fx[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS];
     421             :     Word16 Cx_sum_e[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS];
     422             :     Word16 ILD_q_fx[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_SZ_ILD_MAP];
     423             :     Word16 ch;
     424             :     Word16 band;
     425             :     PARAM_MC_ENC_HANDLE hParamMC;
     426             :     Word16 nchan_inp;
     427             : 
     428        9960 :     push_wmops( "param_mc_enc" );
     429             : 
     430             :     /* initializations */
     431        9960 :     hParamMC = st_ivas->hParamMC;
     432        9960 :     bit_pos = 0;
     433        9960 :     move16();
     434        9960 :     band_step = 1;
     435        9960 :     move16();
     436        9960 :     nchan_inp = st_ivas->hEncoderConfig->nchan_inp;
     437        9960 :     move16();
     438             : 
     439      209160 :     FOR( band = 0; band < PARAM_MC_MAX_PARAMETER_BANDS; band++ )
     440             :     {
     441     3386400 :         FOR( ch = 0; ch < MAX_CICP_CHANNELS; ch++ )
     442             :         {
     443     3187200 :             set32_fx( Cy_sum_fx[band][ch], 0, MAX_CICP_CHANNELS );
     444     3187200 :             set16_fx( Cy_sum_e[band][ch], 0, MAX_CICP_CHANNELS );
     445             :         }
     446      796800 :         FOR( ch = 0; ch < PARAM_MC_MAX_TRANSPORT_CHANS; ch++ )
     447             :         {
     448      597600 :             set32_fx( Cx_sum_fx[band][ch], 0, PARAM_MC_MAX_TRANSPORT_CHANS );
     449      597600 :             set16_fx( Cx_sum_e[band][ch], 0, PARAM_MC_MAX_TRANSPORT_CHANS );
     450             :         }
     451             :     }
     452             : 
     453        9960 :     set16_fx( ILD_idx, 0, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_SZ_ILD_MAP );
     454        9960 :     set16_fx( ICC_idx, 0, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_SZ_ICC_MAP );
     455             : 
     456             :     /* update parameter frame index */
     457        9960 :     hParamMC->hMetadataPMC.param_frame_idx = add( hParamMC->hMetadataPMC.param_frame_idx, 1 ) % PARAM_MC_PARAMETER_FRAMES;
     458        9960 :     move16();
     459             : 
     460             :     /* DMX generation*/
     461        9960 :     ivas_param_mc_dmx_fx( hParamMC, data_f_fx, data_dmx_fx, input_frame, nchan_inp, st_ivas->nchan_transport );
     462             : 
     463             :     /* Transient Detector */
     464        9960 :     SWITCH( st_ivas->nchan_transport )
     465             :     {
     466        9960 :         case 3:
     467             :         case 2:
     468             :         case 4:
     469             :         {
     470             :             Word16 q_data_dmx_fx16;
     471             :             Word16 bAttackPresent[PARAM_MC_MAX_TRANSPORT_CHANS];
     472             :             Word16 attackIdx[PARAM_MC_MAX_TRANSPORT_CHANS];
     473             : 
     474        9960 :             set16_fx( attackIdx, -1, PARAM_MC_MAX_TRANSPORT_CHANS );
     475        9960 :             set16_fx( bAttackPresent, 0, PARAM_MC_MAX_TRANSPORT_CHANS );
     476             : 
     477       29990 :             FOR( ch = 0; ch < st_ivas->nchan_transport; ch++ )
     478             :             {
     479       20030 :                 Word16 cpe_idx = shr( ch, 1 );
     480             : 
     481       20030 :                 q_data_dmx_fx16 = sub( L_norm_arr( data_dmx_fx[ch], input_frame ), 16 );
     482       20030 :                 Copy_Scale_sig_32_16( data_dmx_fx[ch], data_dmx_fx16[ch], input_frame, q_data_dmx_fx16 ); // Q11 -> Q(q_data_dmx_fx16 + 11)
     483       20030 :                 q_data_dmx_fx16 = add( q_data_dmx_fx16, Q11 );
     484             : 
     485       20030 :                 RunTransientDetection_ivas_fx( data_dmx_fx16[ch], input_frame, st_ivas->hCPE[cpe_idx]->hCoreCoder[ch - cpe_idx * CPE_CHANNELS]->hTranDet, q_data_dmx_fx16 );
     486             : 
     487       20030 :                 ivas_param_mc_transient_detection_fx( hParamMC, st_ivas->hCPE[cpe_idx]->hCoreCoder[ch - cpe_idx * CPE_CHANNELS]->hTranDet, &bAttackPresent[ch], &attackIdx[ch] );
     488             :             }
     489             : 
     490             :             /* if more than one attack, use the earlier */
     491        9960 :             hParamMC->hMetadataPMC.bAttackPresent = 0;
     492        9960 :             move16();
     493        9960 :             hParamMC->hMetadataPMC.attackIndex = 16;
     494        9960 :             move16();
     495             : 
     496       29990 :             FOR( ch = 0; ch < st_ivas->nchan_transport; ch++ )
     497             :             {
     498       20030 :                 hParamMC->hMetadataPMC.bAttackPresent = s_max( hParamMC->hMetadataPMC.bAttackPresent, bAttackPresent[ch] );
     499       20030 :                 move16();
     500             :             }
     501             : 
     502        9960 :             IF( hParamMC->hMetadataPMC.bAttackPresent )
     503             :             {
     504        1440 :                 FOR( ch = 0; ch < st_ivas->nchan_transport; ch++ )
     505             :                 {
     506         970 :                     hParamMC->hMetadataPMC.attackIndex = s_min( hParamMC->hMetadataPMC.attackIndex, attackIdx[ch] );
     507         970 :                     move16();
     508             :                 }
     509             :             }
     510             :             ELSE
     511             :             {
     512        9490 :                 hParamMC->hMetadataPMC.attackIndex = 0;
     513        9490 :                 move16();
     514             :             }
     515             :         }
     516        9960 :             BREAK;
     517             :     }
     518             : 
     519             :     /* Encoding */
     520             :     /* parameter estimation*/
     521        9960 :     ivas_param_mc_param_est_enc_fx( hParamMC, data_f_fx, Cy_sum_fx, Cy_sum_e, Cx_sum_fx, Cx_sum_e, input_frame, nchan_inp, st_ivas->nchan_transport );
     522             : 
     523        9960 :     IF( hParamMC->hMetadataPMC.bAttackPresent )
     524             :     {
     525         470 :         band_step = PARAM_MC_TRANSIENT_BAND_STEP;
     526         470 :         move16();
     527             :     }
     528             :     ELSE
     529             :     {
     530        9490 :         band_step = 1;
     531        9490 :         move16();
     532             :     }
     533             : 
     534             : 
     535             :     /* ILD parameter quantization */
     536      138827 :     FOR( k = 0; k < hParamMC->hMetadataPMC.nbands_coded; k += band_step )
     537             :     {
     538      128867 :         ivas_param_mc_quantize_ilds_fx( hParamMC, Cy_sum_fx[k], Cy_sum_e[k], Cx_sum_fx[k], Cx_sum_e[k], k, nchan_inp, st_ivas->nchan_transport, ILD_idx, ILD_q_fx[k] );
     539             :     }
     540             : 
     541             :     /* ICC parameter quantization */
     542      138827 :     FOR( k = 0; k < hParamMC->hMetadataPMC.nbands_coded; k += band_step )
     543             :     {
     544      128867 :         ivas_param_mc_quantize_iccs_fx( hParamMC, Cy_sum_fx[k], Cy_sum_e[k], k, nchan_inp, ICC_idx );
     545             :     }
     546             : 
     547             :     /* time domain DMX generation*/
     548             :     /* just copy data_dmx generated above, contains already the downmix */
     549       29990 :     FOR( ch = 0; ch < st_ivas->nchan_transport; ch++ )
     550             :     {
     551       20030 :         Copy32( data_dmx_fx[ch], data_f_fx[ch], input_frame ); // q_data_dmx_fx16
     552             :     }
     553             : 
     554             :     /* we have to run the transient detector on the second channel of the last CPE if we
     555             :        have an odd number of transport channels */
     556        9960 :     IF( GT_16( st_ivas->nchan_transport, 2 ) )
     557             :     {
     558         220 :         FOR( ; ch < st_ivas->nCPE * CPE_CHANNELS; ch++ )
     559             :         {
     560         110 :             Word16 cpe_idx = shr( ch, 1 );
     561             : 
     562         110 :             set32_fx( data_f_fx[ch], 0, input_frame ); // Q11
     563         110 :             set16_fx( data_f_fx16, 0, input_frame );   // Q11
     564             : 
     565         110 :             RunTransientDetection_ivas_fx( data_f_fx16, input_frame, st_ivas->hCPE[cpe_idx]->hCoreCoder[ch - cpe_idx * CPE_CHANNELS]->hTranDet, 0 );
     566             :         }
     567             :     }
     568             : 
     569             :     /* write Parametric MC side info bitstream into temporary buffer*/
     570        9960 :     ivas_param_mc_write_bs_fx( hParamMC, ILD_idx, ICC_idx, bit_buffer, &bit_pos );
     571             : 
     572             :     /* push the Parametric MC side info from the temporary buffer into the medatdata bitstream*/
     573        9960 :     push_next_bits( hMetaData, bit_buffer, bit_pos );
     574             : 
     575             :     /* updates */
     576        9960 :     hParamMC->hMetadataPMC.last_coded_bwidth = hParamMC->hMetadataPMC.coded_bwidth;
     577        9960 :     move16();
     578             : 
     579        9960 :     pop_wmops();
     580             : 
     581        9960 :     return;
     582             : }
     583             : 
     584             : 
     585             : /*****************************************************************************************/
     586             : /* local functions                                                                       */
     587             : /*****************************************************************************************/
     588             : 
     589             : /*-------------------------------------------------------------------------
     590             :  * ivas_param_mc_dmx()
     591             :  *
     592             :  * Computes the time domain down mix signal
     593             :  *------------------------------------------------------------------------*/
     594             : 
     595        9960 : static void ivas_param_mc_dmx_fx(
     596             :     PARAM_MC_ENC_HANDLE hParamMC,     /* i/o: Parametric MC encoder handle     */
     597             :     Word32 *data_f_fx[],              /* i  : Input frame                  Q_x    */
     598             :     Word32 data_dmx_fx[][L_FRAME48k], /* o  : Down mixed frame              Q_x - 11   */
     599             :     const Word16 input_frame,         /* i  : Input frame length               */
     600             :     const Word16 nchan_input,         /* i  : number of input channels         */
     601             :     const Word16 nchan_transport      /* i  : number of transport channels     */
     602             : )
     603             : {
     604             :     Word16 i;
     605             :     const Word16 *idx;
     606             :     Word16 dmx_ch;
     607             :     Word16 inp_ch;
     608             :     const Word32 *p_dmx_fac_fx;
     609             : 
     610        9960 :     idx = Param_MC_index;
     611     9462760 :     FOR( i = 0; i < input_frame; i++ )
     612             :     {
     613     9452800 :         p_dmx_fac_fx = hParamMC->dmx_factors_fx;
     614    28464000 :         FOR( dmx_ch = 0; dmx_ch < nchan_transport; dmx_ch++ )
     615             :         {
     616    19011200 :             Word32 *dmx_sample_fx = &data_dmx_fx[idx[dmx_ch]][i];
     617    19011200 :             *dmx_sample_fx = 0;
     618    19011200 :             move16();
     619   136515200 :             FOR( inp_ch = 0; inp_ch < nchan_input; inp_ch++ )
     620             :             {
     621   117504000 :                 ( *dmx_sample_fx ) = Madd_32_32( ( *dmx_sample_fx ), data_f_fx[idx[inp_ch]][i], ( *( p_dmx_fac_fx++ ) ) ); // Q_x - 11
     622   117504000 :                 move16();
     623             :             }
     624             :         }
     625             :     }
     626             : 
     627        9960 :     return;
     628             : }
     629             : 
     630             : 
     631             : /*-------------------------------------------------------------------------
     632             :  * ivas_param_mc_param_est_enc()
     633             :  *
     634             :  * run the CLDFB analysis on the input signal
     635             :  * estimate the input and down mix covariances
     636             :  *------------------------------------------------------------------------*/
     637             : 
     638        9960 : static void ivas_param_mc_param_est_enc_fx(
     639             :     PARAM_MC_ENC_HANDLE hParamMC,                                                   /* i/o: Parametric MC encoder handle               */
     640             :     Word32 *data_f_fx[],                                                            /* i  : Input frame in the time domain         Q11 */
     641             :     Word32 Cy_sum_fx[][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS],                       /* o  : Covariance matrix for the original frame   Cy_sum_e*/
     642             :     Word16 Cy_sum_e[][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS],                        /* o  : Covariance matrix for the original frame   */
     643             :     Word32 Cx_sum_fx[][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS], /* o  : Covariance matrix for the downmixed frame  Cx_sum_e*/
     644             :     Word16 Cx_sum_e[][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS],  /* o  : Covariance matrix for the downmixed frame  */
     645             :     const Word16 input_frame,                                                       /* i  : Input frame length                         */
     646             :     const Word16 nchan_input,                                                       /* i  : number of input channels         */
     647             :     const Word16 nchan_transport                                                    /* i  : number of transport channels     */
     648             : )
     649             : {
     650             :     Word16 i, cur_cldfb_band, cur_param_band, ch_idx1, ch_idx2, inp_ch;
     651             :     Word16 ts;
     652             :     Word16 l_ts;
     653             :     Word16 num_time_slots;
     654             :     Word16 num_parameter_bands;
     655             :     Word16 brange[2];
     656             :     Word16 band_step;
     657        9960 :     const Word16 *map_ls = Param_MC_index; /* Loudspeakers mapping */
     658             :     Word16 idx_ls;
     659             :     Word16 start_ts;
     660             : 
     661             :     Word32 *pcm_in_fx[MAX_CICP_CHANNELS];
     662             :     Word32 slot_frame_f_real_fx[MAX_CICP_CHANNELS][DIRAC_NO_FB_BANDS_MAX]; /* Output of the MDFT FB - real part */
     663             :     Word32 slot_frame_f_imag_fx[MAX_CICP_CHANNELS][DIRAC_NO_FB_BANDS_MAX]; /* Output of the MDFT FB - imag part */
     664             :     Word32 *p_slot_frame_f_real_fx[MAX_CICP_CHANNELS];                     /* Output of the MDFT FB - real part */
     665             :     Word32 *p_slot_frame_f_imag_fx[MAX_CICP_CHANNELS];                     /* Output of the MDFT FB - imag part */
     666             : 
     667             : #ifdef MERGE_REQUEST_1472_SPEEDUP_ivas_mc_param_enc_fx_NONBE
     668             :     Word64 dmx_real_64[PARAM_MC_MAX_TRANSPORT_CHANS];
     669             :     Word64 dmx_imag_64[PARAM_MC_MAX_TRANSPORT_CHANS];
     670             : #else
     671             :     Word32 dmx_real_fx[PARAM_MC_MAX_TRANSPORT_CHANS]; /* Downmix channel - Real Part */
     672             :     Word16 dmx_real_e[PARAM_MC_MAX_TRANSPORT_CHANS];  /* Downmix channel - Real Part */
     673             :     Word32 dmx_imag_fx[PARAM_MC_MAX_TRANSPORT_CHANS]; /* Downmix channel - Imag Part */
     674             :     Word16 dmx_imag_e[PARAM_MC_MAX_TRANSPORT_CHANS];  /* Downmix channel - Imag Part */
     675             : #endif
     676             :     Word32 a_fx, b_fx, c_fx, d_fx; /* Tmp complex values */
     677             :     Word16 a_e, b_e, c_e, d_e;     /* Tmp complex values */
     678             :     Word64 Cy_sum_real_64[PARAM_MC_MAX_PARAMETER_BANDS][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS];
     679             :     Word64 Cy_sum_imag_64[PARAM_MC_MAX_PARAM_BAND_ABS_COV_ENC][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS];
     680             :     Word16 sub62gb;
     681             :     Word16 sub35gb;
     682             :     Word32 Cx_sum_imag_fx[PARAM_MC_MAX_PARAM_BAND_ABS_COV_ENC][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS];
     683             :     Word16 Cx_sum_imag_e[PARAM_MC_MAX_PARAM_BAND_ABS_COV_ENC][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS];
     684             :     Word32 real_part_fx, imag_part_fx;
     685             :     Word16 real_part_e, imag_part_e;
     686             :     const Word32 *p_dmx_fac_fx;
     687             :     Word32 L_tmp;
     688             :     Word16 tmp_e;
     689             : 
     690        9960 :     push_wmops( "param_mc_prm_est" );
     691             : 
     692             :     /* initializations */
     693        9960 :     l_ts = extract_l( Mpy_32_16_1( input_frame, INV_PARAM_MC_MDFT_NO_SLOTS_FX ) );
     694        9960 :     num_time_slots = PARAM_MC_MDFT_NO_SLOTS;
     695        9960 :     move16();
     696        9960 :     IF( hParamMC->hMetadataPMC.bAttackPresent )
     697             :     {
     698         470 :         start_ts = hParamMC->hMetadataPMC.attackIndex;
     699         470 :         move16();
     700             :     }
     701             :     ELSE
     702             :     {
     703        9490 :         start_ts = 0;
     704        9490 :         move16();
     705             :     }
     706        9960 :     num_parameter_bands = hParamMC->hMetadataPMC.nbands_coded;
     707        9960 :     move16();
     708        9960 :     band_step = 1;
     709        9960 :     move16();
     710      209160 :     FOR( cur_param_band = 0; cur_param_band < PARAM_MC_MAX_PARAMETER_BANDS; cur_param_band++ )
     711             :     {
     712     3386400 :         FOR( ch_idx1 = 0; ch_idx1 < MAX_CICP_CHANNELS; ch_idx1++ )
     713             :         {
     714     3187200 :             set64_fx( Cy_sum_real_64[cur_param_band][ch_idx1], 0, MAX_CICP_CHANNELS );
     715             :         }
     716             :     }
     717             : 
     718      109560 :     FOR( cur_param_band = 0; cur_param_band < PARAM_MC_MAX_PARAM_BAND_ABS_COV_ENC; cur_param_band++ )
     719             :     {
     720     1693200 :         FOR( ch_idx1 = 0; ch_idx1 < MAX_CICP_CHANNELS; ch_idx1++ )
     721             :         {
     722     1593600 :             set64_fx( Cy_sum_imag_64[cur_param_band][ch_idx1], 0, MAX_CICP_CHANNELS );
     723             :         }
     724             : 
     725      398400 :         FOR( ch_idx1 = 0; ch_idx1 < PARAM_MC_MAX_TRANSPORT_CHANS; ch_idx1++ )
     726             :         {
     727      298800 :             set32_fx( Cx_sum_imag_fx[cur_param_band][ch_idx1], 0, PARAM_MC_MAX_TRANSPORT_CHANS );
     728      298800 :             set16_fx( Cx_sum_imag_e[cur_param_band][ch_idx1], 0, PARAM_MC_MAX_TRANSPORT_CHANS );
     729             :         }
     730             :     }
     731             : 
     732             :     /* Copy current frame to memory for delay compensation */
     733       71240 :     FOR( i = 0; i < nchan_input; i++ )
     734             :     {
     735       61280 :         idx_ls = map_ls[i];
     736       61280 :         move16();
     737       61280 :         pcm_in_fx[i] = data_f_fx[idx_ls];
     738       61280 :         p_slot_frame_f_real_fx[i] = &slot_frame_f_real_fx[i][0];
     739       61280 :         p_slot_frame_f_imag_fx[i] = &slot_frame_f_imag_fx[i][0];
     740             :     }
     741             : 
     742       11545 :     FOR( ts = 0; ts < start_ts; ts++ )
     743             :     {
     744        1585 :         ivas_fb_mixer_update_prior_input_fx( hParamMC->hFbMixer, pcm_in_fx, l_ts, hParamMC->hFbMixer->fb_cfg->num_in_chans );
     745       11949 :         FOR( i = 0; i < nchan_input; i++ )
     746             :         {
     747       10364 :             pcm_in_fx[i] += l_ts;
     748             :         }
     749             :     }
     750             : 
     751        9960 :     Word16 gb = find_guarded_bits_fx( l_ts );
     752             : #ifndef MERGE_REQUEST_1472_SPEEDUP_ivas_mc_param_enc_fx_NONBE
     753             :     Word16 add20gb = add( 20, gb );
     754             : #endif
     755             : 
     756        9960 :     sub35gb = sub( 32, sub( 11, find_guarded_bits_fx( l_ts ) ) );           // 31 - (((11 - gb) + 31 + norm) - 32)
     757        9960 :     sub62gb = sub( 63, shl( sub( 11, find_guarded_bits_fx( l_ts ) ), 1 ) ); // 31 - ((2*(11 - gb) + norm) - 32)
     758             : 
     759       88055 :     FOR( ts = start_ts; ts < num_time_slots; ts++ )
     760             :     {
     761       78095 :         ivas_fb_mixer_get_windowed_fr_fx( hParamMC->hFbMixer, pcm_in_fx, p_slot_frame_f_real_fx, p_slot_frame_f_imag_fx, l_ts, l_ts, hParamMC->hFbMixer->fb_cfg->num_in_chans, gb );
     762       78095 :         ivas_fb_mixer_update_prior_input_fx( hParamMC->hFbMixer, pcm_in_fx, l_ts, hParamMC->hFbMixer->fb_cfg->num_in_chans );
     763             : 
     764             :         /* slot_frame_f buffer Q = 11 - gb : exponent = 20 + gb */
     765             : 
     766      557971 :         FOR( i = 0; i < nchan_input; i++ )
     767             :         {
     768      479876 :             pcm_in_fx[i] += l_ts;
     769      479876 :             move32();
     770             :         }
     771             :         /* Computing the downmix */
     772      674617 :         FOR( cur_param_band = 0; cur_param_band < hParamMC->max_param_band_abs_cov; cur_param_band++ )
     773             :         {
     774      596522 :             brange[0] = hParamMC->band_grouping[cur_param_band];
     775      596522 :             move16();
     776      596522 :             brange[1] = hParamMC->band_grouping[cur_param_band + 1];
     777      596522 :             move16();
     778             : 
     779     2158422 :             FOR( cur_cldfb_band = brange[0]; cur_cldfb_band < brange[1]; cur_cldfb_band++ )
     780             :             {
     781             :                 /* Cx for DMX */
     782             :                 /* Real Part */
     783     1561900 :                 p_dmx_fac_fx = hParamMC->dmx_factors_fx;
     784             : 
     785     4701460 :                 FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 )
     786             :                 {
     787             : #ifdef MERGE_REQUEST_1472_SPEEDUP_ivas_mc_param_enc_fx_NONBE
     788             :                     Word64 real_64;
     789             :                     Word64 imag_64;
     790             : 
     791     3139560 :                     real_64 = 0;
     792     3139560 :                     imag_64 = 0;
     793     3139560 :                     move64();
     794     3139560 :                     move64();
     795    22506440 :                     FOR( inp_ch = 0; inp_ch < nchan_input; inp_ch++ )
     796             :                     {
     797    19366880 :                         real_64 = W_add( real_64, W_mult0_32_32( slot_frame_f_real_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) ) );
     798    19366880 :                         imag_64 = W_add( imag_64, W_mult0_32_32( slot_frame_f_imag_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) ) );
     799    19366880 :                         p_dmx_fac_fx++;
     800             :                     }
     801     3139560 :                     dmx_real_64[ch_idx1] = real_64;
     802     3139560 :                     dmx_imag_64[ch_idx1] = imag_64;
     803     3139560 :                     move64();
     804     3139560 :                     move64();
     805             : 
     806             : #else
     807             :                     Word32 real_fx = L_add( 0, 0 );
     808             :                     Word16 real_e = add( 0, 0 );
     809             :                     Word32 imag_fx = L_add( 0, 0 );
     810             :                     Word16 imag_e = add( 0, 0 );
     811             :                     FOR( inp_ch = 0; inp_ch < nchan_input; inp_ch++ )
     812             :                     {
     813             :                         L_tmp = Mpy_32_32( slot_frame_f_real_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) );
     814             :                         real_fx = BASOP_Util_Add_Mant32Exp( real_fx, real_e, L_tmp, add20gb, &real_e );
     815             :                         L_tmp = Mpy_32_32( slot_frame_f_imag_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) );
     816             :                         imag_fx = BASOP_Util_Add_Mant32Exp( imag_fx, imag_e, L_tmp, add20gb, &imag_e );
     817             :                         p_dmx_fac_fx++;
     818             :                     }
     819             :                     dmx_real_fx[ch_idx1] = real_fx;
     820             :                     dmx_real_e[ch_idx1] = real_e;
     821             :                     dmx_imag_fx[ch_idx1] = imag_fx;
     822             :                     dmx_imag_e[ch_idx1] = imag_e;
     823             :                     move32();
     824             :                     move16();
     825             :                     move32();
     826             :                     move16();
     827             : 
     828             : #endif
     829             :                 }
     830             : 
     831             :                 /* Cx for transport channels */
     832     4701460 :                 FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 )
     833             :                 {
     834             : #ifdef MERGE_REQUEST_1472_SPEEDUP_ivas_mc_param_enc_fx_NONBE
     835     3139560 :                     CONVERT_DMX( dmx_real_64[ch_idx1], a_fx, a_e );
     836     3139560 :                     CONVERT_DMX( dmx_imag_64[ch_idx1], b_fx, b_e );
     837             : #endif
     838     9465960 :                     FOR( ch_idx2 = 0; ch_idx2 < nchan_transport; ++ch_idx2 )
     839             :                     {
     840             : #ifdef MERGE_REQUEST_1472_SPEEDUP_ivas_mc_param_enc_fx_NONBE
     841     6326400 :                         CONVERT_DMX( dmx_real_64[ch_idx2], c_fx, c_e );
     842     6326400 :                         CONVERT_DMX( dmx_imag_64[ch_idx2], d_fx, d_e );
     843             : #else
     844             :                         a_fx = dmx_real_fx[ch_idx1];
     845             :                         move32();
     846             :                         a_e = dmx_real_e[ch_idx1];
     847             :                         move16();
     848             :                         b_fx = dmx_imag_fx[ch_idx1];
     849             :                         move32();
     850             :                         b_e = dmx_imag_e[ch_idx1];
     851             :                         move16();
     852             :                         c_fx = dmx_real_fx[ch_idx2];
     853             :                         move32();
     854             :                         c_e = dmx_real_e[ch_idx2];
     855             :                         move16();
     856             :                         d_fx = dmx_imag_fx[ch_idx2];
     857             :                         move32();
     858             :                         d_e = dmx_imag_e[ch_idx2];
     859             :                         move16();
     860             : #endif
     861             : 
     862             :                         /* (a-ib)(c+id) = ac + bd + i(ad-bc) */
     863     6326400 :                         L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, c_fx ), add( a_e, c_e ), Mpy_32_32( b_fx, d_fx ), add( b_e, d_e ), &tmp_e );
     864    12652800 :                         Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cx_sum_e[cur_param_band][ch_idx1][ch_idx2],
     865     6326400 :                                                                                                 L_tmp, tmp_e, &Cx_sum_e[cur_param_band][ch_idx1][ch_idx2] );
     866     6326400 :                         move32();
     867     6326400 :                         L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, d_fx ), add( a_e, d_e ), L_negate( Mpy_32_32( b_fx, c_fx ) ), add( b_e, c_e ), &tmp_e );
     868    12652800 :                         Cx_sum_imag_fx[cur_param_band][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cx_sum_imag_fx[cur_param_band][ch_idx1][ch_idx2], Cx_sum_imag_e[cur_param_band][ch_idx1][ch_idx2],
     869     6326400 :                                                                                                      L_tmp, tmp_e, &Cx_sum_imag_e[cur_param_band][ch_idx1][ch_idx2] );
     870     6326400 :                         move32();
     871             :                     }
     872             :                 }
     873    11159420 :                 FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 )
     874             :                 {
     875     9597520 :                     a_fx = slot_frame_f_real_fx[ch_idx1][cur_cldfb_band];
     876     9597520 :                     b_fx = slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band];
     877     9597520 :                     move32();
     878    44230600 :                     FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 )
     879             :                     {
     880    34633080 :                         c_fx = slot_frame_f_real_fx[ch_idx2][cur_cldfb_band];
     881    34633080 :                         d_fx = slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band];
     882    34633080 :                         move32();
     883             :                         // Conjugated complex multiplication (a-ib)(c+id) = ac+bd + i(ad-bc)
     884    34633080 :                         Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2] = W_add( Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2],
     885             :                                                                                   W_add( W_mult0_32_32( a_fx, c_fx ), W_mult0_32_32( b_fx, d_fx ) ) );
     886    34633080 :                         move64();
     887    34633080 :                         Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2] = W_add( Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2],
     888             :                                                                                   W_sub( W_mult0_32_32( a_fx, d_fx ), W_mult0_32_32( b_fx, c_fx ) ) );
     889    34633080 :                         move64();
     890             :                     }
     891             :                 }
     892             :             }
     893             :         }
     894             : 
     895      516302 :         FOR( ; cur_param_band < num_parameter_bands; cur_param_band++ )
     896             :         {
     897      438207 :             brange[0] = hParamMC->band_grouping[cur_param_band];
     898      438207 :             move16();
     899      438207 :             brange[1] = hParamMC->band_grouping[cur_param_band + 1];
     900      438207 :             move16();
     901             : 
     902     8145427 :             FOR( cur_cldfb_band = brange[0]; cur_cldfb_band < brange[1]; cur_cldfb_band++ )
     903             :             {
     904             :                 /* Cx for DMX */
     905             :                 /* Real Part */
     906     7707220 :                 p_dmx_fac_fx = hParamMC->dmx_factors_fx; // Q31
     907             : 
     908    23200460 :                 FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 )
     909             :                 {
     910             : #ifdef MERGE_REQUEST_1472_SPEEDUP_ivas_mc_param_enc_fx_NONBE
     911             :                     Word64 real_64;
     912             :                     Word64 imag_64;
     913             : 
     914    15493240 :                     real_64 = 0;
     915    15493240 :                     imag_64 = 0;
     916    15493240 :                     move64();
     917    15493240 :                     move64();
     918             : 
     919   111100280 :                     FOR( inp_ch = 0; inp_ch < nchan_input; inp_ch++ )
     920             :                     {
     921    95607040 :                         real_64 = W_add( real_64, W_mult0_32_32( slot_frame_f_real_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) ) );
     922    95607040 :                         imag_64 = W_add( imag_64, W_mult0_32_32( slot_frame_f_imag_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) ) );
     923    95607040 :                         p_dmx_fac_fx++;
     924             :                     }
     925    15493240 :                     dmx_real_64[ch_idx1] = real_64;
     926    15493240 :                     dmx_imag_64[ch_idx1] = imag_64;
     927    15493240 :                     move64();
     928    15493240 :                     move64();
     929             : #else
     930             :                     Word32 real_fx = L_add( 0, 0 );
     931             :                     Word16 real_e = 0;
     932             :                     move16();
     933             :                     Word32 imag_fx = L_add( 0, 0 );
     934             :                     Word16 imag_e = 0;
     935             :                     move16();
     936             : 
     937             :                     FOR( inp_ch = 0; inp_ch < nchan_input; inp_ch++ )
     938             :                     {
     939             :                         L_tmp = Mpy_32_32( slot_frame_f_real_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) );
     940             :                         real_fx = BASOP_Util_Add_Mant32Exp( real_fx, real_e, L_tmp, add20gb, &real_e );
     941             :                         L_tmp = Mpy_32_32( slot_frame_f_imag_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) );
     942             :                         imag_fx = BASOP_Util_Add_Mant32Exp( imag_fx, imag_e, L_tmp, add20gb, &imag_e );
     943             :                         p_dmx_fac_fx++;
     944             :                     }
     945             :                     dmx_real_fx[ch_idx1] = real_fx;
     946             :                     move32();
     947             :                     dmx_real_e[ch_idx1] = real_e;
     948             :                     move16();
     949             :                     dmx_imag_fx[ch_idx1] = imag_fx;
     950             :                     move32();
     951             :                     dmx_imag_e[ch_idx1] = imag_e;
     952             :                     move16();
     953             : 
     954             : #endif
     955             :                 }
     956             : 
     957             :                 /* Cx for transport channels */
     958    23200460 :                 FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 )
     959             :                 {
     960             : #ifdef MERGE_REQUEST_1472_SPEEDUP_ivas_mc_param_enc_fx_NONBE
     961    15493240 :                     CONVERT_DMX( dmx_real_64[ch_idx1], a_fx, a_e );
     962    15493240 :                     CONVERT_DMX( dmx_imag_64[ch_idx1], b_fx, b_e );
     963             : #else
     964             :                     a_fx = dmx_real_fx[ch_idx1];
     965             :                     move32();
     966             :                     a_e = dmx_real_e[ch_idx1];
     967             :                     move16();
     968             :                     b_fx = dmx_imag_fx[ch_idx1];
     969             :                     move32();
     970             :                     b_e = dmx_imag_e[ch_idx1];
     971             :                     move16();
     972             : 
     973             : #endif
     974    46716120 :                     FOR( ch_idx2 = 0; ch_idx2 < nchan_transport; ++ch_idx2 )
     975             :                     {
     976             : #ifdef MERGE_REQUEST_1472_SPEEDUP_ivas_mc_param_enc_fx_NONBE
     977    31222880 :                         CONVERT_DMX( dmx_real_64[ch_idx2], c_fx, c_e );
     978    31222880 :                         CONVERT_DMX( dmx_imag_64[ch_idx2], d_fx, d_e );
     979             : 
     980             :                         /* (a-ib)(c+id) = ac + bd + i(ad-bc) */
     981    31222880 :                         L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, c_fx ), add( a_e, c_e ), Mpy_32_32( b_fx, d_fx ), add( b_e, d_e ), &tmp_e );
     982    62445760 :                         Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cx_sum_e[cur_param_band][ch_idx1][ch_idx2], L_tmp, tmp_e,
     983    31222880 :                                                                                                 &Cx_sum_e[cur_param_band][ch_idx1][ch_idx2] );
     984             : #else
     985             :                         /* (a-ib)(c+id) = ac + bd + i(ad-bc) */
     986             :                         L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, dmx_real_fx[ch_idx2] ), add( a_e, dmx_real_e[ch_idx2] ), Mpy_32_32( b_fx, dmx_imag_fx[ch_idx2] ), add( b_e, dmx_imag_e[ch_idx2] ), &tmp_e );
     987             :                         Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cx_sum_e[cur_param_band][ch_idx1][ch_idx2], L_tmp, tmp_e,
     988             :                                                                                                 &Cx_sum_e[cur_param_band][ch_idx1][ch_idx2] );
     989             : #endif
     990    31222880 :                         move32();
     991             :                     }
     992             :                 }
     993             : 
     994             :                 /* Cy for input channels */
     995    55081140 :                 FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 )
     996             :                 {
     997             : #ifdef IMPROVE_HIGH_COMPLEXITY_PARAM_MC_PRM_EST_NONBE
     998             :                     a_e = norm_l( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band] );
     999             :                     a_fx = L_shl( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band], a_e );
    1000             :                     a_e = sub( add20gb, a_e );
    1001             :                     if ( a_fx == 0 )
    1002             :                     {
    1003             :                         a_e = 0;
    1004             :                         move16();
    1005             :                     }
    1006             :                     b_e = norm_l( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band] );
    1007             :                     b_fx = L_shl( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band], b_e );
    1008             :                     b_e = sub( add20gb, b_e );
    1009             :                     if ( b_fx == 0 )
    1010             :                     {
    1011             :                         b_e = 0;
    1012             :                         move16();
    1013             :                     }
    1014             : #endif
    1015    47373920 :                     a_fx = slot_frame_f_real_fx[ch_idx1][cur_cldfb_band];
    1016    47373920 :                     b_fx = slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band];
    1017    47373920 :                     move32();
    1018    47373920 :                     move32();
    1019   218391440 :                     FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 )
    1020             :                     {
    1021   171017520 :                         c_fx = slot_frame_f_real_fx[ch_idx2][cur_cldfb_band];
    1022   171017520 :                         d_fx = slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band];
    1023   171017520 :                         move32();
    1024   171017520 :                         move32();
    1025             :                         // Conjugated complex multiplication (a-ib)(c+id) = ac+bd + i(ad-bc)
    1026   171017520 :                         Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2] = W_add( Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2],
    1027             :                                                                                   W_add( W_mult0_32_32( a_fx, c_fx ), W_mult0_32_32( b_fx, d_fx ) ) );
    1028   171017520 :                         move64();
    1029             :                     }
    1030             :                 }
    1031             :             }
    1032             :         }
    1033             :     }
    1034             : 
    1035             :     /* make sure energy and correlation is zero above the relevant LFE bands for LFE
    1036             :      * avoids wrong energy in case of band combining at transients */
    1037        9960 :     IF( hParamMC->lfe_index >= 0 )
    1038             :     {
    1039       76040 :         FOR( cur_param_band = PARAM_MC_MAX_BAND_LFE; cur_param_band < hParamMC->max_param_band_abs_cov; cur_param_band++ )
    1040             :         {
    1041      473120 :             FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 )
    1042             :             {
    1043      407040 :                 Cy_sum_real_64[cur_param_band][hParamMC->lfe_index][ch_idx1] = 0;
    1044      407040 :                 move64();
    1045      407040 :                 Cy_sum_real_64[cur_param_band][ch_idx1][hParamMC->lfe_index] = 0;
    1046      407040 :                 move64();
    1047      407040 :                 Cy_sum_imag_64[cur_param_band][hParamMC->lfe_index][ch_idx1] = 0;
    1048      407040 :                 move64();
    1049      407040 :                 Cy_sum_imag_64[cur_param_band][ch_idx1][hParamMC->lfe_index] = 0;
    1050      407040 :                 move64();
    1051             :             }
    1052             :         }
    1053             : 
    1054       65800 :         FOR( ; cur_param_band < num_parameter_bands; cur_param_band++ )
    1055             :         {
    1056      400040 :             FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 )
    1057             :             {
    1058      344200 :                 Cy_sum_real_64[cur_param_band][hParamMC->lfe_index][ch_idx1] = 0;
    1059      344200 :                 move64();
    1060      344200 :                 Cy_sum_real_64[cur_param_band][ch_idx1][hParamMC->lfe_index] = 0;
    1061      344200 :                 move64();
    1062             :             }
    1063             :         }
    1064             :     }
    1065             : 
    1066        9960 :     IF( !hParamMC->hMetadataPMC.bAttackPresent )
    1067             :     {
    1068             :         const PARAM_MC_ILD_MAPPING *h_ild_mapping;
    1069             :         Word16 ild_attack;
    1070        9490 :         ild_attack = 0;
    1071        9490 :         move16();
    1072        9490 :         h_ild_mapping = hParamMC->hMetadataPMC.ild_mapping_conf;
    1073             :         /* create ILDs for to non transmitted parameter bands (only lower half) */
    1074       72545 :         FOR( cur_param_band = 0; cur_param_band < hParamMC->hMetadataPMC.num_parameter_bands / 2; cur_param_band++ )
    1075             :         {
    1076             :             Word32 ILD_fx[PARAM_MC_SZ_ILD_MAP];
    1077             :             Word16 k;
    1078             :             Word16 num_ilds_to_code;
    1079             : 
    1080       63055 :             IF( GE_16( cur_param_band, PARAM_MC_MAX_BAND_LFE ) )
    1081             :             {
    1082       53565 :                 num_ilds_to_code = hParamMC->hMetadataPMC.ild_mapping_conf->ild_map_size_wo_lfe;
    1083       53565 :                 move16();
    1084             :             }
    1085             :             ELSE
    1086             :             {
    1087        9490 :                 num_ilds_to_code = hParamMC->hMetadataPMC.ild_mapping_conf->ild_map_size_lfe;
    1088        9490 :                 move16();
    1089             :             }
    1090       63055 :             IF( NE_16( hParamMC->hMetadataPMC.param_frame_idx, hParamMC->hMetadataPMC.coding_band_mapping[cur_param_band] ) )
    1091             :             {
    1092             :                 Word32 Nrg_fx[MAX_CICP_CHANNELS];
    1093             :                 Word16 Nrg_e[MAX_CICP_CHANNELS];
    1094             : 
    1095             :                 /* get ICLDs */
    1096      224693 :                 FOR( k = 0; k < nchan_input; ++k )
    1097             :                 {
    1098      193248 :                     CONVERT_CY( Cy_sum_real_64[cur_param_band][k][k], Nrg_fx[k], Nrg_e[k] );
    1099      193248 :                     move32();
    1100      193248 :                     move16();
    1101             :                 }
    1102      197669 :                 FOR( k = 0; k < num_ilds_to_code; ++k )
    1103             :                 {
    1104      166224 :                     Word32 ref_ener_fx = 0;
    1105      166224 :                     move32();
    1106      166224 :                     Word16 ref_ener_e = 0;
    1107      166224 :                     move16();
    1108             :                     Word16 ref_channel_cnt;
    1109             :                     Word16 ref_channel_idx;
    1110             : 
    1111      368226 :                     FOR( ref_channel_cnt = 0; ref_channel_cnt < h_ild_mapping->num_ref_channels[k]; ref_channel_cnt++ )
    1112             :                     {
    1113      202002 :                         ref_channel_idx = h_ild_mapping->ref_channel_idx[k][ref_channel_cnt];
    1114      202002 :                         move16();
    1115      202002 :                         ref_ener_fx = BASOP_Util_Add_Mant32Exp( ref_ener_fx, ref_ener_e, Cx_sum_fx[cur_param_band][ref_channel_idx][ref_channel_idx], // ref_ener_e
    1116      202002 :                                                                 Cx_sum_e[cur_param_band][ref_channel_idx][ref_channel_idx], &ref_ener_e );
    1117             :                     }
    1118      166224 :                     L_tmp = Mpy_32_16_1( ref_ener_fx, hParamMC->hMetadataPMC.ild_factors_fx[k] );
    1119      166224 :                     L_tmp = L_deposit_h( BASOP_Util_Divide3232_Scale( Nrg_fx[h_ild_mapping->ild_index[k]], L_add( L_tmp, EPSILLON_FX ), &tmp_e ) );
    1120             : 
    1121      166224 :                     tmp_e = add( sub( Nrg_e[h_ild_mapping->ild_index[k]], ref_ener_e ), tmp_e );
    1122             : 
    1123             :                     /*1342177280 = 10 in Q27*/
    1124      166224 :                     ILD_fx[k] = Mpy_32_32( 1342177280, BASOP_Util_Log10( L_tmp, tmp_e ) ); // Q25 + Q27 - Q31 = Q21
    1125      166224 :                     move32();
    1126             : 
    1127      166224 :                     if ( GT_32( L_sub( hParamMC->prev_ilds_fx[cur_param_band][k], ILD_fx[k] ), param_mc_ild_diff_threshold_fx[cur_param_band] ) )
    1128             :                     {
    1129         301 :                         ild_attack = add( ild_attack, 1 );
    1130             :                     }
    1131             :                 }
    1132             :             }
    1133             :         }
    1134             :         /* check if the ILDs change too much -> go into transient mode... */
    1135        9490 :         if ( GT_16( ild_attack, PARAM_MC_NUM_ATTACK_ILD_THRESH ) )
    1136             :         {
    1137           0 :             hParamMC->hMetadataPMC.bAttackPresent = 1;
    1138           0 :             move16();
    1139             :         }
    1140             :     }
    1141             : 
    1142             : 
    1143        9960 :     IF( hParamMC->hMetadataPMC.bAttackPresent )
    1144             :     {
    1145             :         /* combine bands */
    1146        2229 :         FOR( cur_param_band = 1; cur_param_band < hParamMC->max_param_band_abs_cov; cur_param_band += 2 )
    1147             :         {
    1148        5404 :             FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 )
    1149             :             {
    1150       11316 :                 FOR( ch_idx2 = 0; ch_idx2 < nchan_transport; ++ch_idx2 )
    1151             :                 {
    1152       15342 :                     Cx_sum_fx[cur_param_band - 1][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cx_sum_fx[cur_param_band - 1][ch_idx1][ch_idx2], Cx_sum_e[cur_param_band - 1][ch_idx1][ch_idx2],
    1153        7671 :                                                                                                 Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cx_sum_e[cur_param_band][ch_idx1][ch_idx2],
    1154        7671 :                                                                                                 &Cx_sum_e[cur_param_band - 1][ch_idx1][ch_idx2] );
    1155        7671 :                     move32();
    1156       15342 :                     Cx_sum_imag_fx[cur_param_band - 1][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cx_sum_imag_fx[cur_param_band - 1][ch_idx1][ch_idx2], Cx_sum_imag_e[cur_param_band - 1][ch_idx1][ch_idx2],
    1157        7671 :                                                                                                      Cx_sum_imag_fx[cur_param_band][ch_idx1][ch_idx2], Cx_sum_imag_e[cur_param_band][ch_idx1][ch_idx2],
    1158        7671 :                                                                                                      &Cx_sum_imag_e[cur_param_band - 1][ch_idx1][ch_idx2] );
    1159        7671 :                     move32();
    1160             :                 }
    1161             :             }
    1162             : 
    1163       13417 :             FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 )
    1164             :             {
    1165       57981 :                 FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 )
    1166             :                 {
    1167       46323 :                     Cy_sum_real_64[cur_param_band - 1][ch_idx1][ch_idx2] = W_add( Cy_sum_real_64[cur_param_band - 1][ch_idx1][ch_idx2], Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2] );
    1168       46323 :                     move64();
    1169       46323 :                     Cy_sum_imag_64[cur_param_band - 1][ch_idx1][ch_idx2] = W_add( Cy_sum_imag_64[cur_param_band - 1][ch_idx1][ch_idx2], Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2] );
    1170       46323 :                     move64();
    1171             :                 }
    1172             :             }
    1173             :         }
    1174             : 
    1175        1724 :         FOR( ; cur_param_band < num_parameter_bands; cur_param_band += 2 )
    1176             :         {
    1177        1254 :             IF( LT_16( cur_param_band, num_parameter_bands ) )
    1178             :             {
    1179        3866 :                 FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 )
    1180             :                 {
    1181        8148 :                     FOR( ch_idx2 = 0; ch_idx2 < nchan_transport; ++ch_idx2 )
    1182             :                     {
    1183       11072 :                         Cx_sum_fx[cur_param_band - 1][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cx_sum_fx[cur_param_band - 1][ch_idx1][ch_idx2], Cx_sum_e[cur_param_band - 1][ch_idx1][ch_idx2],
    1184        5536 :                                                                                                     Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cx_sum_e[cur_param_band][ch_idx1][ch_idx2],
    1185        5536 :                                                                                                     &Cx_sum_e[cur_param_band - 1][ch_idx1][ch_idx2] );
    1186        5536 :                         move32();
    1187             :                     }
    1188             :                 }
    1189             : 
    1190        9618 :                 FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 )
    1191             :                 {
    1192       41826 :                     FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 )
    1193             :                     {
    1194       33462 :                         Cy_sum_real_64[cur_param_band - 1][ch_idx1][ch_idx2] = W_add( Cy_sum_real_64[cur_param_band - 1][ch_idx1][ch_idx2], Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2] );
    1195             :                     }
    1196             :                 }
    1197             :             }
    1198             :         }
    1199             : 
    1200         470 :         band_step = 2;
    1201         470 :         move16();
    1202             :     }
    1203             :     {
    1204             :         // convert the 64 bit fixpoint back into the 48 bit float format
    1205      209160 :         FOR( cur_param_band = 0; cur_param_band < PARAM_MC_MAX_PARAMETER_BANDS; cur_param_band++ )
    1206             :         {
    1207     3386400 :             FOR( ch_idx1 = 0; ch_idx1 < MAX_CICP_CHANNELS; ch_idx1++ )
    1208             :             {
    1209    54182400 :                 FOR( ch_idx2 = 0; ch_idx2 < MAX_CICP_CHANNELS; ch_idx2++ )
    1210             :                 {
    1211    50995200 :                     CONVERT_CY( Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2], Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cy_sum_e[cur_param_band][ch_idx1][ch_idx2] );
    1212    50995200 :                     move32();
    1213    50995200 :                     move16();
    1214             :                 }
    1215             :             }
    1216             :         }
    1217             :     }
    1218             : 
    1219             :     /* map complex covariances to real values */
    1220       84241 :     FOR( cur_param_band = 0; cur_param_band < hParamMC->max_param_band_abs_cov; cur_param_band += band_step )
    1221             :     {
    1222             :         /* Cx for transport channels */
    1223      223656 :         FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ch_idx1++ )
    1224             :         {
    1225      450564 :             FOR( ch_idx2 = 0; ch_idx2 < nchan_transport; ch_idx2++ )
    1226             :             {
    1227      301189 :                 real_part_fx = Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2];
    1228      301189 :                 move32();
    1229      301189 :                 real_part_e = Cx_sum_e[cur_param_band][ch_idx1][ch_idx2];
    1230      301189 :                 move16();
    1231      301189 :                 imag_part_fx = Cx_sum_imag_fx[cur_param_band][ch_idx1][ch_idx2];
    1232      301189 :                 move32();
    1233      301189 :                 imag_part_e = Cx_sum_imag_e[cur_param_band][ch_idx1][ch_idx2];
    1234      301189 :                 move16();
    1235             : 
    1236      301189 :                 real_part_fx = Mpy_32_32( real_part_fx, real_part_fx );
    1237      301189 :                 imag_part_fx = Mpy_32_32( imag_part_fx, imag_part_fx );
    1238      301189 :                 L_tmp = BASOP_Util_Add_Mant32Exp( real_part_fx, shl( real_part_e, 1 ), imag_part_fx, shl( imag_part_e, 1 ), &tmp_e );
    1239             : 
    1240             :                 /* (a-ib)(c+id) = ac + bd + i(ad-bc) */
    1241      301189 :                 L_tmp = Sqrt32( L_tmp, &tmp_e );
    1242      301189 :                 Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2] = L_tmp;
    1243      301189 :                 move32();
    1244      301189 :                 Cx_sum_e[cur_param_band][ch_idx1][ch_idx2] = tmp_e;
    1245      301189 :                 move16();
    1246             :             }
    1247             :         }
    1248             : 
    1249             :         /* Cy for transport channels */
    1250      530943 :         FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ch_idx1++ )
    1251             :         {
    1252     2105459 :             FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ch_idx2++ )
    1253             :             {
    1254     1648797 :                 CONVERT_CY( Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2], imag_part_fx, imag_part_e );
    1255     1648797 :                 move32();
    1256     1648797 :                 move16();
    1257     1648797 :                 real_part_fx = Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2];
    1258     1648797 :                 move32();
    1259     1648797 :                 real_part_e = Cy_sum_e[cur_param_band][ch_idx1][ch_idx2];
    1260     1648797 :                 move16();
    1261     1648797 :                 real_part_fx = Mpy_32_32( real_part_fx, real_part_fx );
    1262     1648797 :                 imag_part_fx = Mpy_32_32( imag_part_fx, imag_part_fx );
    1263             : 
    1264     1648797 :                 L_tmp = BASOP_Util_Add_Mant32Exp( real_part_fx, shl( real_part_e, 1 ), imag_part_fx, shl( imag_part_e, 1 ), &tmp_e );
    1265     1648797 :                 L_tmp = Sqrt32( L_tmp, &tmp_e );
    1266             : 
    1267     1648797 :                 Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2] = L_tmp;
    1268     1648797 :                 move32();
    1269     1648797 :                 Cy_sum_e[cur_param_band][ch_idx1][ch_idx2] = tmp_e;
    1270     1648797 :                 move16();
    1271             :             }
    1272             :         }
    1273             :     }
    1274             : 
    1275        9960 :     IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( Cy_sum_fx[0][LFE_CHANNEL][LFE_CHANNEL], Cy_sum_e[0][LFE_CHANNEL][LFE_CHANNEL], PARAM_MC_LFE_ON_THRESH_FX, 31 ), -1 ) )
    1276             :     {
    1277        8904 :         hParamMC->hMetadataPMC.lfe_on = 0;
    1278        8904 :         move16();
    1279             :     }
    1280             :     ELSE
    1281             :     {
    1282        1056 :         hParamMC->hMetadataPMC.lfe_on = 1;
    1283        1056 :         move16();
    1284             :     }
    1285             : 
    1286        9960 :     pop_wmops();
    1287             : 
    1288        9960 :     return;
    1289             : }
    1290             : 
    1291             : /*-------------------------------------------------------------------------
    1292             :  * ivas_param_mc_quantize_ilds()
    1293             :  *
    1294             :  * Quantize the ILD parameters
    1295             :  *------------------------------------------------------------------------*/
    1296             : 
    1297      128867 : static void ivas_param_mc_quantize_ilds_fx(
    1298             :     PARAM_MC_ENC_HANDLE hParamMC,                                             /* i/o: Parametric MC encoder handle    */
    1299             :     Word32 Cy_fx[MAX_CICP_CHANNELS][MAX_CICP_CHANNELS],                       /* i  : Covariance matrix of the input  */
    1300             :     Word16 Cy_e[MAX_CICP_CHANNELS][MAX_CICP_CHANNELS],                        /* i  : Covariance matrix of the input  */
    1301             :     Word32 Cx_fx[PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS], /* i  : Covariance matrix of the dmx    */
    1302             :     Word16 Cx_e[PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS],  /* i  : Covariance matrix of the dmx    */
    1303             :     const Word16 freq_idx,                                                    /* i  : frequency index being processed */
    1304             :     const Word16 nchan_input,                                                 /* i  : number of input channels        */
    1305             :     const Word16 nchan_transport,                                             /* i  : number of transport channels    */
    1306             :     Word16 *ILD_idx_out,                                                      /* o  : ILD indices  */
    1307             :     Word16 ILD_q[PARAM_MC_SZ_ILD_MAP]                                         /* o  : Quanzited ILD matrix            */
    1308             : )
    1309             : {
    1310             :     Word16 i, k;
    1311             :     Word16 Ny;
    1312             :     Word16 num_ilds_to_code;
    1313             :     Word16 ild_map_size;
    1314             :     Word32 Nrg_fx[MAX_CICP_CHANNELS];
    1315             :     Word16 Nrg_e[MAX_CICP_CHANNELS];
    1316             :     Word32 ILD_fx[PARAM_MC_SZ_ILD_MAP];
    1317             :     Word16 ILD_e[PARAM_MC_SZ_ILD_MAP];
    1318             :     const PARAM_MC_ILD_MAPPING *h_ild_mapping;
    1319             :     Word32 tot_ener_fx, dmx_ener_fx, ener_fac_fx, delta_fac_fx;
    1320             :     Word16 tot_ener_e, dmx_ener_e;
    1321             :     Word16 ILD_idx[PARAM_MC_SZ_ILD_MAP];
    1322             :     Word32 L_tmp;
    1323             :     Word16 tmp_e;
    1324             : 
    1325      128867 :     push_wmops( "param_mc_prm_q" );
    1326             : 
    1327             :     /* Initialization */
    1328      128867 :     set32_fx( Nrg_fx, 0, MAX_CICP_CHANNELS );
    1329      128867 :     set32_fx( ILD_fx, 0, PARAM_MC_SZ_ILD_MAP );
    1330             : 
    1331      128867 :     Ny = nchan_input;
    1332      128867 :     move16();
    1333             : 
    1334      128867 :     h_ild_mapping = hParamMC->hMetadataPMC.ild_mapping_conf;
    1335      128867 :     ild_map_size = hParamMC->hMetadataPMC.ild_mapping_conf->ild_map_size_lfe;
    1336      128867 :     move16();
    1337      128867 :     IF( GE_16( freq_idx, PARAM_MC_MAX_BAND_LFE ) )
    1338             :     {
    1339      118907 :         num_ilds_to_code = hParamMC->hMetadataPMC.ild_mapping_conf->ild_map_size_wo_lfe;
    1340      118907 :         move16();
    1341             :     }
    1342             :     ELSE
    1343             :     {
    1344        9960 :         num_ilds_to_code = hParamMC->hMetadataPMC.ild_mapping_conf->ild_map_size_lfe;
    1345        9960 :         move16();
    1346             :     }
    1347             : 
    1348             :     /* Downsampling */
    1349      128867 :     test();
    1350      128867 :     IF( ( hParamMC->hMetadataPMC.bAttackPresent == 0 ) && NE_16( hParamMC->hMetadataPMC.param_frame_idx, hParamMC->hMetadataPMC.coding_band_mapping[freq_idx] ) )
    1351             :     {
    1352       62884 :         pop_wmops();
    1353             : 
    1354       62884 :         return;
    1355             :     }
    1356             : 
    1357             :     /* get ICLDs */
    1358      472515 :     FOR( k = 0; k < Ny; ++k )
    1359             :     {
    1360      406532 :         Nrg_fx[k] = Cy_fx[k][k];
    1361      406532 :         move32();
    1362      406532 :         Nrg_e[k] = Cy_e[k][k];
    1363      406532 :         move16();
    1364             :     }
    1365             : 
    1366             :     /* limit ILDs if DMX energy is lower than sum of channel energies */
    1367       65983 :     tot_ener_fx = 0;
    1368       65983 :     move32();
    1369       65983 :     tot_ener_e = 0;
    1370       65983 :     move16();
    1371       65983 :     dmx_ener_fx = 0;
    1372       65983 :     move32();
    1373       65983 :     dmx_ener_e = 0;
    1374       65983 :     move16();
    1375             : 
    1376      472515 :     FOR( k = 0; k < ild_map_size; k++ )
    1377             :     {
    1378      406532 :         test();
    1379      406532 :         IF( NE_16( k, hParamMC->lfe_index ) || hParamMC->hMetadataPMC.lfe_on )
    1380             :         {
    1381      347750 :             tot_ener_fx = BASOP_Util_Add_Mant32Exp( tot_ener_fx, tot_ener_e, Nrg_fx[k], Nrg_e[k], &tot_ener_e );
    1382             :         }
    1383             :     }
    1384             : 
    1385      198816 :     FOR( k = 0; k < nchan_transport; k++ )
    1386             :     {
    1387      132833 :         dmx_ener_fx = BASOP_Util_Add_Mant32Exp( dmx_ener_fx, dmx_ener_e, Cx_fx[k][k], Cx_e[k][k], &dmx_ener_e );
    1388             :     }
    1389             :     /*ener_fac = 10.0f * log10f( ( tot_ener + EPSILON ) / ( dmx_ener + EPSILON ) )*/
    1390       65983 :     IF( tot_ener_fx == 0 )
    1391             :     {
    1392           0 :         tot_ener_fx = 9223; // 1e-15(EPSILON) in Q63
    1393           0 :         tot_ener_e = -32;
    1394           0 :         move32();
    1395           0 :         move16();
    1396             :     }
    1397       65983 :     IF( dmx_ener_fx == 0 )
    1398             :     {
    1399           0 :         dmx_ener_fx = 9223; // 1e-15(EPSILON) in Q63
    1400           0 :         dmx_ener_e = -32;
    1401           0 :         move32();
    1402           0 :         move16();
    1403             :     }
    1404             : 
    1405       65983 :     L_tmp = L_deposit_h( BASOP_Util_Divide3232_Scale( tot_ener_fx, dmx_ener_fx, &tmp_e ) );
    1406       65983 :     tmp_e = add( sub( tot_ener_e, dmx_ener_e ), tmp_e );
    1407       65983 :     ener_fac_fx = BASOP_Util_Log10( L_tmp, tmp_e );     // Q25
    1408             :                                                         /*10 in Q21 = 1342177280*/
    1409       65983 :     ener_fac_fx = Mpy_32_32( 1342177280, ener_fac_fx ); // Q25 + Q27 - Q31 = Q21;
    1410             : 
    1411       65983 :     IF( GT_32( ener_fac_fx, PARAM_MC_ENER_LIMIT_INTRAFRAME_FX_Q21 ) )
    1412             :     {
    1413          15 :         L_tmp = L_sub( ener_fac_fx, PARAM_MC_ENER_LIMIT_INTRAFRAME_FX_Q21 - ONE_IN_Q21 ); // Q21
    1414          15 :         L_tmp = BASOP_Util_Loge( L_tmp, 31 - Q21 );                                       // Q25
    1415             :         /*0.3 in Q31 = 644245094*/
    1416          15 :         L_tmp = L_sub( L_shr( Mpy_32_32( 644245094, L_tmp ), 4 ), L_sub( ener_fac_fx, PARAM_MC_ENER_LIMIT_INTRAFRAME_FX_Q21 ) );
    1417             :         /*0.1 in Q31 = 214748365*/
    1418          15 :         L_tmp = Mpy_32_32( L_tmp, 214748365 );
    1419          15 :         L_tmp = BASOP_util_Pow2( Mpy_32_32( L_tmp, LOG2_10_Q29 ), 31 - 19, &tmp_e );
    1420             : 
    1421             :         /*v_multc( Nrg, limit_fac, Nrg, num_ilds_to_code );*/
    1422         105 :         FOR( i = 0; i < num_ilds_to_code; i++ )
    1423             :         {
    1424          90 :             Nrg_fx[i] = Mpy_32_32( Nrg_fx[i], L_tmp );
    1425          90 :             move32();
    1426          90 :             Nrg_e[i] = add( tmp_e, Nrg_e[i] );
    1427          90 :             move16();
    1428          90 :             Nrg_fx[i] = BASOP_Util_Add_Mant32Exp( Nrg_fx[i], Nrg_e[i], 0, 0, &Nrg_e[i] );
    1429          90 :             move32();
    1430             :         }
    1431             :     }
    1432             : 
    1433             :     /* limit ILD jumps in non-tranient frames */
    1434       65983 :     tot_ener_fx = 0;
    1435       65983 :     move32();
    1436       65983 :     dmx_ener_fx = 0;
    1437       65983 :     move32();
    1438             : 
    1439      472515 :     FOR( k = 0; k < ild_map_size; k++ )
    1440             :     {
    1441      406532 :         test();
    1442      406532 :         IF( NE_16( k, hParamMC->lfe_index ) || hParamMC->hMetadataPMC.lfe_on )
    1443             :         {
    1444      347750 :             tot_ener_fx = BASOP_Util_Add_Mant32Exp( tot_ener_fx, tot_ener_e, Nrg_fx[k], Nrg_e[k], &tot_ener_e );
    1445             :         }
    1446             :     }
    1447             : 
    1448      198816 :     FOR( k = 0; k < nchan_transport; k++ )
    1449             :     {
    1450      132833 :         dmx_ener_fx = BASOP_Util_Add_Mant32Exp( dmx_ener_fx, dmx_ener_e, Cx_fx[k][k], Cx_e[k][k], &dmx_ener_e );
    1451             :     }
    1452             :     /* ener_fac = 10.0f * log10f( ( tot_ener + EPSILON ) / ( dmx_ener + EPSILON ) ); */
    1453       65983 :     IF( tot_ener_fx == 0 )
    1454             :     {
    1455           0 :         tot_ener_fx = 9223; // 1e-15(EPSILON) in Q63
    1456           0 :         tot_ener_e = -32;
    1457           0 :         move32();
    1458           0 :         move16();
    1459             :     }
    1460       65983 :     IF( dmx_ener_fx == 0 )
    1461             :     {
    1462           0 :         dmx_ener_fx = 9223; // 1e-15(EPSILON) in Q63
    1463           0 :         dmx_ener_e = -32;
    1464           0 :         move32();
    1465           0 :         move16();
    1466             :     }
    1467             : 
    1468       65983 :     L_tmp = L_deposit_h( BASOP_Util_Divide3232_Scale( tot_ener_fx, dmx_ener_fx, &tmp_e ) );
    1469       65983 :     tmp_e = add( sub( tot_ener_e, dmx_ener_e ), tmp_e );
    1470       65983 :     ener_fac_fx = BASOP_Util_Log10( L_tmp, tmp_e );     // Q25
    1471             :                                                         /*10 in Q21 = 1342177280*/
    1472       65983 :     ener_fac_fx = Mpy_32_32( 1342177280, ener_fac_fx ); // Q25 + Q27 - Q31 = Q21;
    1473       65983 :     delta_fac_fx = L_sub( ener_fac_fx, hParamMC->ener_fac_fx[freq_idx] );
    1474             : 
    1475       65983 :     test();
    1476       65983 :     test();
    1477       65983 :     IF( !hParamMC->hMetadataPMC.bAttackPresent && GT_32( delta_fac_fx, PARAM_MC_ENER_LIMIT_INTERFRAME_FX_Q21 ) && LT_32( delta_fac_fx, PARAM_MC_ENER_LIMIT_MAX_DELTA_FAC_FX_Q21 ) )
    1478             :     {
    1479         390 :         L_tmp = L_sub( delta_fac_fx, PARAM_MC_ENER_LIMIT_INTERFRAME_FX_Q21 - ONE_IN_Q21 ); // Q21
    1480         390 :         L_tmp = BASOP_Util_Loge( L_tmp, 31 - Q21 );                                        // Q25
    1481             :                                                                                            /*0.3 in Q31 = 644245094*/
    1482         390 :         L_tmp = L_sub( L_shr( Mpy_32_32( 644245094, L_tmp ), 4 ), L_sub( delta_fac_fx, PARAM_MC_ENER_LIMIT_INTERFRAME_FX_Q21 ) );
    1483             :         /*0.1 in Q31 = 214748365*/
    1484         390 :         L_tmp = Mpy_32_32( L_tmp, 214748365 );
    1485         390 :         L_tmp = BASOP_util_Pow2( Mpy_32_32( L_tmp, LOG2_10_Q29 ), 31 - 19, &tmp_e );
    1486             : 
    1487        2446 :         FOR( i = 0; i < num_ilds_to_code; i++ )
    1488             :         {
    1489        2056 :             Nrg_fx[i] = Mpy_32_32( Nrg_fx[i], L_tmp );
    1490        2056 :             move32();
    1491        2056 :             Nrg_e[i] = add( tmp_e, Nrg_e[i] );
    1492        2056 :             move16();
    1493        2056 :             Nrg_fx[i] = BASOP_Util_Add_Mant32Exp( Nrg_fx[i], Nrg_e[i], 0, 0, &Nrg_e[i] );
    1494        2056 :             move32();
    1495             :         }
    1496             : 
    1497             :         /*10 in Q21 = 1342177280*/
    1498         390 :         ener_fac_fx = L_add( ener_fac_fx, Mpy_32_32( 1342177280, BASOP_Util_Log10( L_tmp, tmp_e ) ) );
    1499             :     }
    1500             : 
    1501       65983 :     hParamMC->ener_fac_fx[freq_idx] = ener_fac_fx; // Q21
    1502       65983 :     move32();
    1503             : 
    1504             :     /* update also combined bands ener_fac when in transient frame */
    1505       65983 :     test();
    1506       65983 :     if ( hParamMC->hMetadataPMC.bAttackPresent && LT_16( add( freq_idx, 1 ), hParamMC->hMetadataPMC.nbands_coded ) )
    1507             :     {
    1508        3013 :         hParamMC->ener_fac_fx[freq_idx + 1] = ener_fac_fx; // Q21
    1509        3013 :         move32();
    1510             :     }
    1511             : 
    1512      410968 :     FOR( k = 0; k < num_ilds_to_code; ++k )
    1513             :     {
    1514      344985 :         Word32 ref_ener_fx = 0;
    1515      344985 :         move32();
    1516      344985 :         Word16 ref_ener_e = 0;
    1517      344985 :         move16();
    1518             :         Word16 ref_channel_cnt;
    1519             :         Word16 ref_channel_idx;
    1520             : 
    1521      760257 :         FOR( ref_channel_cnt = 0; ref_channel_cnt < h_ild_mapping->num_ref_channels[k]; ref_channel_cnt++ )
    1522             :         {
    1523      415272 :             ref_channel_idx = h_ild_mapping->ref_channel_idx[k][ref_channel_cnt];
    1524      415272 :             move16();
    1525      415272 :             ref_ener_fx = BASOP_Util_Add_Mant32Exp( ref_ener_fx, ref_ener_e, Cx_fx[ref_channel_idx][ref_channel_idx], Cx_e[ref_channel_idx][ref_channel_idx], &ref_ener_e );
    1526             :         }
    1527      344985 :         ref_ener_fx = Mpy_32_16_1( ref_ener_fx, hParamMC->hMetadataPMC.ild_factors_fx[k] );
    1528      344985 :         L_tmp = L_deposit_h( BASOP_Util_Divide3232_Scale( Nrg_fx[h_ild_mapping->ild_index[k]], L_add( ref_ener_fx, EPSILLON_FX ), &tmp_e ) );
    1529      344985 :         tmp_e = add( sub( Nrg_e[h_ild_mapping->ild_index[k]], ref_ener_e ), tmp_e );
    1530             :         /*10 in Q21 = 1342177280*/
    1531      344985 :         ILD_fx[k] = Mpy_32_32( 1342177280, BASOP_Util_Log10( L_tmp, tmp_e ) ); // Q21
    1532      344985 :         move32();
    1533      344985 :         ILD_e[k] = 31 - 21;
    1534      344985 :         move16();
    1535      344985 :         hParamMC->prev_ilds_fx[freq_idx][k] = ILD_fx[k];
    1536      344985 :         move32();
    1537      344985 :         test();
    1538      344985 :         IF( hParamMC->hMetadataPMC.bAttackPresent && LT_16( add( freq_idx, 1 ), hParamMC->hMetadataPMC.nbands_coded ) )
    1539             :         {
    1540       17278 :             hParamMC->prev_ilds_fx[freq_idx + 1][k] = ILD_fx[k];
    1541       17278 :             move32();
    1542             :         }
    1543             :     }
    1544             : 
    1545             : 
    1546             :     /* quantize parameters */
    1547       65983 :     ivas_param_mc_parameter_quantizer_fx( ILD_fx, ILD_e, num_ilds_to_code, hParamMC->hMetadataPMC.ild_coding.quantizer_size, hParamMC->hMetadataPMC.ild_coding.quantizer_fx, Q8, ILD_idx, ILD_q );
    1548             : 
    1549             :     /* Save current quantized ICLDs */
    1550       65983 :     Copy( ILD_idx, ILD_idx_out + freq_idx * ild_map_size, num_ilds_to_code );
    1551             : 
    1552       65983 :     pop_wmops();
    1553             : 
    1554       65983 :     return;
    1555             : }
    1556             : 
    1557             : 
    1558             : /*-------------------------------------------------------------------------
    1559             :  * ivas_param_mc_quantize_iccs()
    1560             :  *
    1561             :  * Quantize the ILD parameters
    1562             :  *------------------------------------------------------------------------*/
    1563             : 
    1564      128867 : static void ivas_param_mc_quantize_iccs_fx(
    1565             :     PARAM_MC_ENC_HANDLE hParamMC,                       /* i/o: Parametric MC encoder handle    */
    1566             :     Word32 Cy_fx[MAX_CICP_CHANNELS][MAX_CICP_CHANNELS], /* i  : Covariance matrix of the input  */
    1567             :     Word16 Cy_e[MAX_CICP_CHANNELS][MAX_CICP_CHANNELS],  /* i  : Covariance matrix of the input  */
    1568             :     const Word16 freq_idx,                              /* i  : frequency index being processed */
    1569             :     const Word16 nchan_input,                           /* i  : number of input channels        */
    1570             :     Word16 *ICC_idx_out                                 /* o  : quantizer indices               */
    1571             : )
    1572             : {
    1573             :     Word16 i, k;
    1574             :     Word16 Ny;
    1575             :     Word16 num_iccs_to_code;
    1576             :     Word16 icc_map_size;
    1577             :     Word16 tmp_map[2];
    1578             :     Word16 ICC_idx[PARAM_MC_SZ_ICC_MAP];
    1579             : 
    1580             :     /* Initialization */
    1581             :     Word32 a_fx;
    1582             :     Word32 Nrg_fx[MAX_CICP_CHANNELS];
    1583             :     Word16 Nrg_e;
    1584             :     Word32 ICC_vect_fx[PARAM_MC_SZ_ICC_MAP];
    1585             :     Word16 ICC_vect_e[PARAM_MC_SZ_ICC_MAP];
    1586             :     Word16 ICC_vect_q_fx[PARAM_MC_SZ_ICC_MAP];
    1587             : 
    1588      128867 :     set32_fx( Nrg_fx, 0, MAX_CICP_CHANNELS );
    1589      128867 :     set32_fx( ICC_vect_fx, 0, PARAM_MC_SZ_ICC_MAP );
    1590      128867 :     set16_fx( ICC_vect_q_fx, 0, PARAM_MC_SZ_ICC_MAP );
    1591             : 
    1592             : 
    1593      128867 :     Ny = nchan_input;
    1594      128867 :     move16();
    1595             : 
    1596             :     /* Downsampling */
    1597      128867 :     test();
    1598      128867 :     IF( ( hParamMC->hMetadataPMC.bAttackPresent == 0 ) && NE_16( hParamMC->hMetadataPMC.param_frame_idx, hParamMC->hMetadataPMC.coding_band_mapping[freq_idx] ) )
    1599             :     {
    1600       62884 :         return;
    1601             :     }
    1602             : 
    1603       65983 :     icc_map_size = hParamMC->hMetadataPMC.icc_mapping_conf->icc_map_size_lfe;
    1604       65983 :     move16();
    1605       65983 :     num_iccs_to_code = icc_map_size;
    1606       65983 :     move16();
    1607             : 
    1608       65983 :     if ( GE_16( freq_idx, PARAM_MC_MAX_BAND_LFE ) )
    1609             :     {
    1610       60746 :         num_iccs_to_code = hParamMC->hMetadataPMC.icc_mapping_conf->icc_map_size_wo_lfe;
    1611       60746 :         move16();
    1612             :     }
    1613             : 
    1614             :     /* Get ICC matrix from Cy */
    1615      472515 :     FOR( k = 0; k < Ny; ++k )
    1616             :     {
    1617      406532 :         Nrg_fx[k] = Cy_fx[k][k];
    1618      406532 :         move32();
    1619      406532 :         Nrg_e = Cy_e[k][k];
    1620      406532 :         move16();
    1621      406532 :         a_fx = ISqrt32( L_add( Nrg_fx[k], EPSILLON_FX ), &Nrg_e );
    1622             : 
    1623     1878650 :         FOR( i = k; i < Ny; ++i )
    1624             :         {
    1625     1472118 :             Cy_fx[k][i] = Mpy_32_32( Cy_fx[k][i], a_fx );
    1626     1472118 :             move32();
    1627     1472118 :             Cy_fx[k][i] = BASOP_Util_Add_Mant32Exp( Cy_fx[k][i], add( Cy_e[k][i], Nrg_e ), 0, 0, &Cy_e[k][i] );
    1628     1472118 :             move32();
    1629             :         }
    1630             : 
    1631     1878650 :         FOR( i = 0; i <= k; i++ )
    1632             :         {
    1633     1472118 :             Cy_fx[i][k] = Mpy_32_32( Cy_fx[i][k], a_fx );
    1634     1472118 :             move32();
    1635     1472118 :             Cy_fx[i][k] = BASOP_Util_Add_Mant32Exp( Cy_fx[i][k], add( Cy_e[i][k], Nrg_e ), 0, 0, &Cy_e[i][k] );
    1636     1472118 :             move32();
    1637             :         }
    1638             :     }
    1639             : 
    1640             :     /* set ICCs for zero channels to 1 to avoid artifacts in the decoded signal */
    1641      472515 :     FOR( k = 0; k < Ny; ++k )
    1642             :     {
    1643      406532 :         IF( Nrg_fx[k] == 0 )
    1644             :         {
    1645      252840 :             FOR( i = k; i < Ny; ++i )
    1646             :             {
    1647      192072 :                 Cy_fx[k][i] = ONE_IN_Q31;
    1648      192072 :                 move32();
    1649      192072 :                 Cy_e[k][i] = 0;
    1650      192072 :                 move16();
    1651             :             }
    1652             : 
    1653      303840 :             FOR( i = 0; i <= k; ++i )
    1654             :             {
    1655      243072 :                 Cy_fx[i][k] = ONE_IN_Q31;
    1656      243072 :                 move32();
    1657      243072 :                 Cy_e[i][k] = 0;
    1658      243072 :                 move16();
    1659             :             }
    1660             :         }
    1661             :     }
    1662             : 
    1663             :     /* Reduce set of parameters and quantize them */
    1664      345786 :     FOR( k = 0; k < num_iccs_to_code; ++k )
    1665             :     {
    1666      279803 :         tmp_map[0] = hParamMC->hMetadataPMC.icc_mapping_conf->icc_mapping[k][0];
    1667      279803 :         move16();
    1668      279803 :         tmp_map[1] = hParamMC->hMetadataPMC.icc_mapping_conf->icc_mapping[k][1];
    1669      279803 :         move16();
    1670      279803 :         ICC_vect_fx[k] = Cy_fx[tmp_map[0]][tmp_map[1]];
    1671      279803 :         move32();
    1672      279803 :         ICC_vect_e[k] = Cy_e[tmp_map[0]][tmp_map[1]];
    1673      279803 :         move16();
    1674             :     }
    1675             : 
    1676             :     /* Quantization */
    1677       65983 :     ivas_param_mc_parameter_quantizer_fx( ICC_vect_fx, ICC_vect_e, num_iccs_to_code, hParamMC->hMetadataPMC.icc_coding.quantizer_size, hParamMC->hMetadataPMC.icc_coding.quantizer_fx, Q15, ICC_idx, ICC_vect_q_fx );
    1678             : 
    1679             :     /* Save current quantized ICCs */
    1680       65983 :     Copy( ICC_idx, ICC_idx_out + freq_idx * icc_map_size, num_iccs_to_code );
    1681             : 
    1682       65983 :     return;
    1683             : }
    1684             : 
    1685             : 
    1686             : /*-------------------------------------------------------------------------
    1687             :  * ivas_param_mc_parameter_quantizer()
    1688             :  *
    1689             :  * Parameter Quantization
    1690             :  *------------------------------------------------------------------------*/
    1691             : 
    1692      131966 : static void ivas_param_mc_parameter_quantizer_fx(
    1693             :     const Word32 *x,            /* i  : input sequence            */
    1694             :     const Word16 *x_e,          /* i  : input sequence            */
    1695             :     const Word16 L,             /* i  : input length              */
    1696             :     const Word16 sz_quantizer,  /* i  : quantizer size            */
    1697             :     const Word16 *quantizer_fx, /* i  : quantizer table   Q_quant */
    1698             :     const Word16 Q_quant,       /* i  : quantizer table           */
    1699             :     Word16 *quant_idx,          /* o  : quant indices             */
    1700             :     Word16 *y_fx                /* o  : output sequence   Q_quant */
    1701             : )
    1702             : {
    1703             :     Word16 idx, i;
    1704             :     Word16 idx_min;
    1705             :     Word32 tmp_min_fx;
    1706             :     Word16 tmp_min_e;
    1707             :     Word32 tmp_val;
    1708             :     Word16 tmp_e;
    1709             : 
    1710      131966 :     set16_fx( y_fx, 0, L );
    1711      131966 :     idx_min = 0;
    1712      131966 :     move16();
    1713             : 
    1714      756754 :     FOR( idx = 0; idx < L; ++idx )
    1715             :     {
    1716      624788 :         tmp_min_fx = 1000;
    1717      624788 :         move32();
    1718      624788 :         tmp_min_e = 31;
    1719      624788 :         move16();
    1720             : 
    1721     8382972 :         FOR( i = 0; i < sz_quantizer; ++i )
    1722             :         {
    1723     7758184 :             tmp_val = BASOP_Util_Add_Mant32Exp( x[idx], x_e[idx], L_negate( L_deposit_h( quantizer_fx[i] ) ), sub( 15, Q_quant ), &tmp_e );
    1724     7758184 :             tmp_val = L_abs( tmp_val );
    1725     7758184 :             IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( tmp_val, tmp_e, tmp_min_fx, tmp_min_e ), -1 ) )
    1726             :             {
    1727     4084081 :                 tmp_min_fx = tmp_val;
    1728     4084081 :                 move32();
    1729     4084081 :                 tmp_min_e = tmp_e;
    1730     4084081 :                 move16();
    1731     4084081 :                 idx_min = i;
    1732     4084081 :                 move16();
    1733             :             }
    1734             :         }
    1735             : 
    1736      624788 :         y_fx[idx] = quantizer_fx[idx_min];
    1737      624788 :         move32();
    1738      624788 :         quant_idx[idx] = idx_min;
    1739      624788 :         move16();
    1740             :     }
    1741             : 
    1742      131966 :     return;
    1743             : }
    1744             : 
    1745             : 
    1746             : /*-------------------------------------------------------------------------
    1747             :  * ivas_param_mc_transient_detection()
    1748             :  *
    1749             :  * Detect if the current frame has a transient
    1750             :  *------------------------------------------------------------------------*/
    1751             : 
    1752       20030 : static void ivas_param_mc_transient_detection_fx(
    1753             :     PARAM_MC_ENC_HANDLE hParamMC, /* i  : Parametric MC encoder handle                                      */
    1754             :     TRAN_DET_HANDLE hTranDet,     /* i  : Transient detector handle from core coder for a transport channel */
    1755             :     Word16 *pbIsAttackPresent,    /* o  : Flag for indicating a found transient                             */
    1756             :     Word16 *pAttackIndex          /* o  : Attack position (0 if no attack)                                  */
    1757             : )
    1758             : {
    1759             :     Word16 i;
    1760             :     Word16 bIsAttackPresent, attackIndex;
    1761             :     Word32 *pSubblockNrg_fx;
    1762             :     Word32 *pAccSubblockNrg_fx;
    1763             :     Word16 attackRatioThreshold_fx;
    1764             : 
    1765       20030 :     push_wmops( "param_mc_trn_det" );
    1766             : 
    1767       20030 :     attackRatioThreshold_fx = hTranDet->transientDetector.attackRatioThreshold;
    1768       20030 :     pSubblockNrg_fx = &hTranDet->subblockEnergies.subblockNrg[hParamMC->transient_detector_delay];       // Q(-1)
    1769       20030 :     pAccSubblockNrg_fx = &hTranDet->subblockEnergies.accSubblockNrg[hParamMC->transient_detector_delay]; // Q(-1)
    1770             : 
    1771       20030 :     bIsAttackPresent = FALSE;
    1772       20030 :     move16();
    1773       20030 :     attackIndex = 16;
    1774       20030 :     move16();
    1775             : 
    1776             :     /* Search for the last attack in the subblocks,
    1777             :      * if we had an attack very late in the last frame,
    1778             :      * make the current frame also a transient one... */
    1779       20030 :     test();
    1780       20030 :     IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg_fx[-1], 32, Mpy_32_16_1( pAccSubblockNrg_fx[-1], attackRatioThreshold_fx ), ( 32 + ATTACKTHRESHOLD_E ) ), 1 ) ||
    1781             :         EQ_16( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg_fx[-2], 32, Mpy_32_16_1( pAccSubblockNrg_fx[-2], attackRatioThreshold_fx ), ( 32 + ATTACKTHRESHOLD_E ) ), 1 ) )
    1782             :     {
    1783          69 :         bIsAttackPresent = TRUE;
    1784          69 :         move16();
    1785          69 :         attackIndex = 0;
    1786          69 :         move16();
    1787             :     }
    1788             : 
    1789      180270 :     FOR( i = 0; i < NSUBBLOCKS; i++ ){
    1790      160240 :         IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg_fx[i], 32, Mpy_32_16_1( pAccSubblockNrg_fx[i], attackRatioThreshold_fx ), ( 32 + ATTACKTHRESHOLD_E ) ), 1 ) ){
    1791         754 :             bIsAttackPresent = TRUE;
    1792         754 :     move16();
    1793         754 :     attackIndex = i;
    1794         754 :     move16();
    1795             : }
    1796             : }
    1797             : 
    1798             : /* avoid post-echos on click sounds (very short transients) due to TNS aliasing */
    1799       20030 : *pAttackIndex = attackIndex;
    1800       20030 : move16();
    1801       20030 : *pbIsAttackPresent = bIsAttackPresent;
    1802       20030 : move16();
    1803             : 
    1804       20030 : pop_wmops();
    1805             : 
    1806       20030 : return;
    1807             : }
    1808             : 
    1809             : /*-------------------------------------------------------------------------
    1810             :  * ivas_param_mc_entropy_encoder()
    1811             :  *
    1812             :  * Write the metadata bitstream
    1813             :  *------------------------------------------------------------------------*/
    1814             : 
    1815        9960 : static void ivas_param_mc_write_bs_fx(
    1816             :     const PARAM_MC_ENC_HANDLE hParamMC,    /* i/o: Parametric MC encoder Handle   */
    1817             :     Word16 *ILD_idx,                       /* i  : ILD quantizer indices sequence */
    1818             :     Word16 *ICC_idx,                       /* i  : ICC quantizer indices sequence */
    1819             :     UWord16 bit_buffer[PARAM_MC_MAX_BITS], /* o  : Output bit buffer              */
    1820             :     Word16 *bit_pos                        /* o  : Number of bits used            */
    1821             : )
    1822             : {
    1823             :     Word16 i, pos;
    1824             :     Word16 nbands;
    1825             :     Word16 band_step;
    1826             :     /*buffers are not getting used in the function*/
    1827             :     // Word16 seq_tmp[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_SZ_ILD_MAP];
    1828             :     // float seq_tmp_uni[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_SZ_ILD_MAP];
    1829             :     Word16 icc_map_size_wo_lfe;
    1830             :     Word16 icc_map_size;
    1831             :     Word16 ild_map_size_wo_lfe;
    1832             :     Word16 ild_map_size;
    1833             : 
    1834        9960 :     push_wmops( "param_mc_prm_enc" );
    1835             : 
    1836             :     /* Init */
    1837             :     /*buffers are not getting used in the function */
    1838             :     // set_zero( seq_tmp_uni, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_SZ_ILD_MAP );
    1839             :     // set_s( seq_tmp, 0, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_SZ_ILD_MAP );
    1840        9960 :     nbands = hParamMC->hMetadataPMC.nbands_in_param_frame[hParamMC->hMetadataPMC.param_frame_idx];
    1841        9960 :     move16();
    1842        9960 :     icc_map_size_wo_lfe = hParamMC->hMetadataPMC.icc_mapping_conf->icc_map_size_wo_lfe;
    1843        9960 :     move16();
    1844        9960 :     icc_map_size = hParamMC->hMetadataPMC.icc_mapping_conf->icc_map_size_lfe;
    1845        9960 :     move16();
    1846        9960 :     ild_map_size_wo_lfe = hParamMC->hMetadataPMC.ild_mapping_conf->ild_map_size_wo_lfe;
    1847        9960 :     move16();
    1848        9960 :     ild_map_size = hParamMC->hMetadataPMC.ild_mapping_conf->ild_map_size_lfe;
    1849        9960 :     move16();
    1850             : 
    1851             :     /*-----------------------------------------------------------------*
    1852             :      * Signaling bits
    1853             :      *-----------------------------------------------------------------*/
    1854             : 
    1855             :     /* reserved bit */
    1856        9960 :     bit_buffer[( *bit_pos )++] = hParamMC->hMetadataPMC.lfe_on;
    1857        9960 :     move16();
    1858             : 
    1859             :     /* write coded band width */
    1860        9960 :     i = hParamMC->hMetadataPMC.coded_bwidth;
    1861        9960 :     move16();
    1862       29880 :     FOR( pos = 0; pos < 2; pos++ )
    1863             :     {
    1864       19920 :         bit_buffer[( *bit_pos )++] = (UWord16) s_and( shr( i, pos ), 1 );
    1865       19920 :         move16();
    1866             :     }
    1867             : 
    1868             :     /* write param frame indicator */
    1869        9960 :     bit_buffer[( *bit_pos )++] = hParamMC->hMetadataPMC.param_frame_idx;
    1870        9960 :     move16();
    1871             : 
    1872             :     /* write transient frame indicator */
    1873        9960 :     bit_buffer[( *bit_pos )++] = hParamMC->hMetadataPMC.bAttackPresent;
    1874        9960 :     move16();
    1875             : 
    1876        9960 :     band_step = 1;
    1877        9960 :     move16();
    1878        9960 :     IF( hParamMC->hMetadataPMC.bAttackPresent )
    1879             :     {
    1880         470 :         band_step = PARAM_MC_TRANSIENT_BAND_STEP;
    1881         470 :         move16();
    1882        1880 :         FOR( pos = 2; pos >= 0; --pos )
    1883             :         {
    1884        1410 :             bit_buffer[( *bit_pos )++] = (UWord16) s_and( shr( hParamMC->hMetadataPMC.attackIndex, pos ), 1 );
    1885        1410 :             move16();
    1886             :         }
    1887         470 :         IF( ( hParamMC->hMetadataPMC.nbands_coded % band_step ) )
    1888             :         {
    1889          42 :             nbands = add( idiv1616( hParamMC->hMetadataPMC.nbands_coded, band_step ), 1 );
    1890             :         }
    1891             :         ELSE
    1892             :         {
    1893         428 :             nbands = add( idiv1616( hParamMC->hMetadataPMC.nbands_coded, band_step ), 0 );
    1894             :         }
    1895             :     }
    1896             : 
    1897        9960 :     ivas_param_mc_encode_parameter_fx( ICC_idx, &hParamMC->hMetadataPMC, &hParamMC->hMetadataPMC.icc_coding,
    1898             :                                        nbands, band_step, icc_map_size_wo_lfe, icc_map_size, bit_buffer, bit_pos );
    1899             : 
    1900        9960 :     ivas_param_mc_encode_parameter_fx( ILD_idx, &hParamMC->hMetadataPMC, &hParamMC->hMetadataPMC.ild_coding,
    1901             :                                        nbands, band_step, ild_map_size_wo_lfe, ild_map_size, bit_buffer, bit_pos );
    1902        9960 :     pop_wmops();
    1903             : 
    1904        9960 :     return;
    1905             : }
    1906             : 
    1907             : 
    1908             : /*-------------------------------------------------------------------------
    1909             :  * ivas_param_mc_encode_parameter_fx()
    1910             :  *
    1911             :  * (entropy) encode a sequence of parameter indices
    1912             :  *------------------------------------------------------------------------*/
    1913             : 
    1914       19920 : static void ivas_param_mc_encode_parameter_fx(
    1915             :     Word16 *quant_idx,                                          /* i  : indices sequence to encode              */
    1916             :     HANDLE_IVAS_PARAM_MC_METADATA hMetadataPMC,                 /* i  : Parametric MC metadata handle           */
    1917             :     HANDLE_PARAM_MC_PARAMETER_CODING_INFO hParameterCodingInfo, /* i  : parameter quantization and coding info  */
    1918             :     const Word16 nbands,                                        /* i  : number of parameter bands to encode     */
    1919             :     const Word16 band_step,                                     /* i  : parameter band step                     */
    1920             :     const Word16 map_size_wo_lfe,                               /* i  : number of parameters per band (w/o LFE) */
    1921             :     const Word16 map_size,                                      /* i  : number of parameters per band           */
    1922             :     UWord16 bit_buffer[PARAM_MC_MAX_BITS],                      /* o  : Output bit buffer                       */
    1923             :     Word16 *bit_pos                                             /* o  : Number of bits used                     */
    1924             : )
    1925             : {
    1926             :     Word16 sz_seq;
    1927             :     Word16 idx_prev;
    1928             :     Word16 idx_offset;
    1929             :     Word16 bit_cnt_uni;
    1930             :     Word16 bit_cnt_range;
    1931             :     Word16 bit_cnt_range_diff;
    1932             :     Word16 bit_cnt_range_min;
    1933             :     Word16 bit_pos_tmp;
    1934             :     Word16 i, j;
    1935             :     Word16 idx;
    1936             :     Word16 seq_delta[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE];
    1937             :     Word16 seq[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE];
    1938             :     UWord16 tmp_bit_buffer[PARAM_MC_MAX_BITS];
    1939             :     UWord16 tmp_bit_buffer_diff[PARAM_MC_MAX_BITS];
    1940             : 
    1941             :     /* Inits */
    1942       19920 :     sz_seq = i_mult( nbands, ( map_size_wo_lfe ) );
    1943             : 
    1944             :     /* Computing Delta Sequence */
    1945       19920 :     idx_prev = sub( add( shr( hParameterCodingInfo->quantizer_size, 1 ), hParameterCodingInfo->quantizer_size % 2 ), 1 );
    1946       19920 :     idx_offset = sub( hParameterCodingInfo->quantizer_size, 1 );
    1947             : 
    1948      112490 :     FOR( j = 0; j < map_size_wo_lfe; ++j )
    1949             :     {
    1950       92570 :         Word16 coding_band = 0;
    1951       92570 :         move16();
    1952             : 
    1953     1289476 :         FOR( i = 0; i < hMetadataPMC->nbands_coded; i += band_step )
    1954             :         {
    1955     1196906 :             test();
    1956     1196906 :             IF( hMetadataPMC->bAttackPresent || EQ_16( hMetadataPMC->param_frame_idx, hMetadataPMC->coding_band_mapping[i] ) )
    1957             :             {
    1958      614248 :                 idx = quant_idx[i * map_size + j];
    1959      614248 :                 move16();
    1960      614248 :                 seq[coding_band + j * nbands] = idx;
    1961      614248 :                 move16();
    1962      614248 :                 seq_delta[coding_band + j * nbands] = add( sub( idx, idx_prev ), idx_offset );
    1963      614248 :                 move16();
    1964      614248 :                 idx_prev = idx;
    1965      614248 :                 move16();
    1966      614248 :                 coding_band = add( coding_band, 1 );
    1967             :             }
    1968             :         }
    1969             :     }
    1970             : 
    1971             :     /* LFE */
    1972       19920 :     IF( hMetadataPMC->lfe_on )
    1973             :     {
    1974        4224 :         FOR( i = 0; i < PARAM_MC_MAX_BAND_LFE; i += band_step )
    1975             :         {
    1976        2112 :             test();
    1977        2112 :             IF( hMetadataPMC->bAttackPresent || EQ_16( hMetadataPMC->param_frame_idx, hMetadataPMC->coding_band_mapping[i] ) )
    1978             :             {
    1979             :                 /* LFE ICC/ILDs are always the last ones in coding band 0 */
    1980             :                 Word16 n_lfe_idx, k;
    1981        1158 :                 n_lfe_idx = sub( map_size, map_size_wo_lfe );
    1982        2382 :                 FOR( k = 0; k < n_lfe_idx; k++ )
    1983             :                 {
    1984        1224 :                     idx = quant_idx[( i + 1 ) * map_size - n_lfe_idx + k];
    1985        1224 :                     move16();
    1986        1224 :                     seq[sz_seq] = idx;
    1987        1224 :                     move16();
    1988        1224 :                     seq_delta[sz_seq] = add( sub( idx, idx_prev ), idx_offset );
    1989        1224 :                     move16();
    1990        1224 :                     idx_prev = idx;
    1991        1224 :                     move16();
    1992        1224 :                     sz_seq = add( sz_seq, 1 );
    1993             :                 }
    1994             :             }
    1995             :         }
    1996             :     }
    1997             : 
    1998             : 
    1999       19920 :     bit_cnt_uni = sub( i_mult( sz_seq, hParameterCodingInfo->uni_bits ), 1 ); /* -1 for the additional diff/direct signaling bit for the range encoder*/
    2000             : 
    2001             :     /* code the direct index sequence */
    2002       19920 :     ivas_param_mc_range_encoder_fx( seq, sz_seq, hParameterCodingInfo->cum_freq, hParameterCodingInfo->sym_freq, PARAM_MC_RANGE_CODER_TOT_SHIFT, bit_cnt_uni, &tmp_bit_buffer[0], &bit_cnt_range );
    2003             : 
    2004             :     /* Coding the delta index sequence */
    2005       19920 :     ivas_param_mc_range_encoder_fx( seq_delta, sz_seq, hParameterCodingInfo->cum_freq_delta, hParameterCodingInfo->sym_freq_delta, PARAM_MC_RANGE_CODER_TOT_SHIFT, bit_cnt_uni, &tmp_bit_buffer_diff[0], &bit_cnt_range_diff );
    2006             : 
    2007       19920 :     bit_cnt_range_min = s_min( bit_cnt_range, bit_cnt_range_diff );
    2008             : 
    2009             :     /* uniform fallback */
    2010       19920 :     IF( GT_16( bit_cnt_range_min, bit_cnt_uni ) )
    2011             :     {
    2012             :         /* Uniform coding is used */
    2013         460 :         bit_buffer[( *bit_pos )++] = 0;
    2014         460 :         move16();
    2015         460 :         bit_pos_tmp = 0;
    2016         460 :         move16();
    2017             : 
    2018       12537 :         FOR( i = 0; i < sz_seq; ++i )
    2019             :         {
    2020       12077 :             ivas_param_mc_dec2bin_fx( seq[i], hParameterCodingInfo->uni_bits, &bit_buffer[*( bit_pos ) + bit_pos_tmp] );
    2021       12077 :             bit_pos_tmp = add( bit_pos_tmp, hParameterCodingInfo->uni_bits );
    2022             :         }
    2023         460 :         *bit_pos = add( *bit_pos, bit_pos_tmp );
    2024             :     }
    2025             :     ELSE
    2026             :     {
    2027             :         /* Range Coding is used */
    2028       19460 :         bit_buffer[( *bit_pos )++] = 1;
    2029       19460 :         move16();
    2030       19460 :         IF( bit_cnt_range_diff < bit_cnt_range )
    2031             :         {
    2032       19214 :             bit_buffer[( *bit_pos )++] = 1;
    2033       19214 :             move16();
    2034     1323964 :             FOR( i = 0; i < bit_cnt_range_diff; i++ )
    2035             :             {
    2036     1304750 :                 bit_buffer[( *bit_pos )++] = tmp_bit_buffer_diff[i];
    2037     1304750 :                 move16();
    2038             :             }
    2039             :         }
    2040             :         ELSE
    2041             :         {
    2042         246 :             bit_buffer[( *bit_pos )++] = 0;
    2043         246 :             move16();
    2044       14787 :             FOR( i = 0; i < bit_cnt_range; i++ )
    2045             :             {
    2046       14541 :                 bit_buffer[( *bit_pos )++] = tmp_bit_buffer[i];
    2047       14541 :                 move16();
    2048             :             }
    2049             :         }
    2050             :     }
    2051             : 
    2052       19920 :     return;
    2053             : }
    2054             : 
    2055             : 
    2056             : /*-------------------------------------------------------------------------
    2057             :  * ivas_param_mc_dec2bin()
    2058             :  *
    2059             :  * Decimal to binary routine
    2060             :  *------------------------------------------------------------------------*/
    2061             : 
    2062       12077 : static void ivas_param_mc_dec2bin_fx(
    2063             :     const Word16 val,                 /* i  : value to encode                       */
    2064             :     const Word16 N,                   /* i  : number of bits for encoding the value */
    2065             :     UWord16 bits[PARAM_MC_MAX_BITS] ) /* o  : encoded bits buffer                   */
    2066             : {
    2067             :     Word16 idx;
    2068             : 
    2069       12077 :     idx = 0;
    2070       12077 :     move16();
    2071             :     /* convert value to bitstream, MSB first */
    2072       48308 :     FOR( idx = 0; idx < N; idx++ )
    2073             :     {
    2074       36231 :         bits[idx] = (UWord16) s_and( shr( val, sub( sub( N, 1 ), idx ) ), 1 );
    2075       36231 :         move16();
    2076             :     }
    2077             : 
    2078       12077 :     return;
    2079             : }
    2080             : 
    2081             : 
    2082             : /*-------------------------------------------------------------------*
    2083             :  * ivas_param_mc_range_encoder()
    2084             :  *
    2085             :  * Parametric MC Range encoder
    2086             :  *-------------------------------------------------------------------*/
    2087             : 
    2088       39840 : static void ivas_param_mc_range_encoder_fx(
    2089             :     const Word16 *seq_in,     /* i  : input sequence                     */
    2090             :     const Word16 num_symbols, /* i  : Number of symbole to encode        */
    2091             :     const UWord16 *cum_freq,  /* i  : cumulated frequencies              */
    2092             :     const UWord16 *sym_freq,  /* i  : symbol frequencies                 */
    2093             :     const UWord16 tot_shift,  /* i  : max cumulative freq as power of 2  */
    2094             :     const Word16 max_nb_bits, /* i  : Maximum number of bits allowed     */
    2095             :     UWord16 *bit_buffer,      /* o  : output bit buffer                  */
    2096             :     Word16 *bit_pos           /* o  : number of bits used                */
    2097             : )
    2098             : {
    2099             :     RangeUniEncState rc_st_enc;
    2100             :     Word16 rc_tot_bits; /* No. of bits returned by range coder */
    2101             :     Word16 i;
    2102             :     UWord8 k, byte;
    2103             :     UWord16 *bits;
    2104             : 
    2105             :     /* Initialize range encoder */
    2106       39840 :     rc_uni_enc_init_fx( &rc_st_enc );
    2107             : 
    2108             :     /* Main loop over the length of the sequence */
    2109     1212542 :     FOR( i = 0; i < num_symbols; ++i )
    2110             :     {
    2111     1182531 :         rc_uni_enc_encode_symbol_fastS_fx( &rc_st_enc, (UWord16) seq_in[i], cum_freq, sym_freq, tot_shift );
    2112             : 
    2113     1182531 :         IF( GT_16( rc_uni_enc_virtual_finish_fx( &rc_st_enc ), max_nb_bits ) )
    2114             :         {
    2115             :             /* we alread have exceeded the maximum number of bits allowed, i.e. the uniform fallback */
    2116        9829 :             *bit_pos = MAX_BITS_PER_FRAME;
    2117        9829 :             return;
    2118             :         }
    2119             :     }
    2120             : 
    2121             :     /* Finish range encoder */
    2122       30011 :     rc_tot_bits = rc_uni_enc_finish_fx( &rc_st_enc ); /* No. of bits consumed by range coder */
    2123             : 
    2124             :     /* Push range coded bits from byte_buffer to bitstream */
    2125             : 
    2126             :     /* 1) Push all complete bytes, one byte at a time */
    2127      327773 :     FOR( i = 0; i < ( rc_tot_bits >> 3 ); ++i )
    2128             :     {
    2129             :         /* use rc_st_enc.byte_buffer */
    2130      297762 :         bits = &bit_buffer[i << 3];
    2131             : 
    2132      297762 :         byte = rc_st_enc.byte_buffer[i];
    2133      297762 :         move16();
    2134             : 
    2135      297762 :         bits[0] = (UWord16) s_and( shr( (Word16) byte, 7 ), 1 );
    2136      297762 :         move16();
    2137      297762 :         bits[1] = (UWord16) s_and( shr( (Word16) byte, 6 ), 1 );
    2138      297762 :         move16();
    2139      297762 :         bits[2] = (UWord16) s_and( shr( (Word16) byte, 5 ), 1 );
    2140      297762 :         move16();
    2141      297762 :         bits[3] = (UWord16) s_and( shr( (Word16) byte, 4 ), 1 );
    2142      297762 :         move16();
    2143      297762 :         bits[4] = (UWord16) s_and( shr( (Word16) byte, 3 ), 1 );
    2144      297762 :         move16();
    2145      297762 :         bits[5] = (UWord16) s_and( shr( (Word16) byte, 2 ), 1 );
    2146      297762 :         move16();
    2147      297762 :         bits[6] = (UWord16) s_and( shr( (Word16) byte, 1 ), 1 );
    2148      297762 :         move16();
    2149      297762 :         bits[7] = (UWord16) s_and( (Word16) byte, 1 );
    2150      297762 :         move16();
    2151             :     }
    2152             : 
    2153             :     /* 2) Push remaining bits */
    2154       30011 :     IF( s_and( rc_tot_bits, 7 ) != 0 )
    2155             :     {
    2156       26397 :         UWord8 rem_bits = (UWord8) s_and( rc_tot_bits, 7 );
    2157             : 
    2158       26397 :         bits = &bit_buffer[( i << 3 )];
    2159       26397 :         byte = rc_st_enc.byte_buffer[i];
    2160       26397 :         move16();
    2161             : 
    2162      130887 :         FOR( k = 0; k < rem_bits; k++ )
    2163             :         {
    2164      104490 :             bits[k] = (UWord16) s_and( shr( (Word16) byte, sub( 7, k ) ), 1 );
    2165      104490 :             move16();
    2166             :         }
    2167             :     }
    2168             : 
    2169             :     /* Update output number of bits */
    2170       30011 :     *bit_pos = rc_tot_bits;
    2171       30011 :     move16();
    2172             : 
    2173       30011 :     return;
    2174             : }

Generated by: LCOV version 1.14