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 @ e95243e9e67ddeb69dddf129509de1b3d95b402e Lines: 850 882 96.4 %
Date: 2025-09-14 03:13:15 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         279 : 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         279 :     error = IVAS_ERR_OK;
     111         279 :     move16();
     112             : 
     113             :     /* Sanity Checks */
     114         279 :     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         279 :     mc_input_setup = st_ivas->hEncoderConfig->mc_input_setup;
     120         279 :     move32();
     121         279 :     max_bwidth = st_ivas->hEncoderConfig->max_bwidth;
     122         279 :     move16();
     123         279 :     input_Fs = st_ivas->hEncoderConfig->input_Fs;
     124         279 :     move32();
     125         279 :     nchan_inp = st_ivas->hEncoderConfig->nchan_inp;
     126         279 :     move16();
     127         279 :     ivas_total_brate = st_ivas->hEncoderConfig->ivas_total_brate;
     128         279 :     move32();
     129             : 
     130             :     /* Preparing Config */
     131         279 :     hParamMC->lfe_index = LFE_CHANNEL;
     132         279 :     move16();
     133         279 :     st_ivas->nchan_transport = ivas_param_mc_getNumTransportChannels_fx( ivas_total_brate, mc_input_setup );
     134         279 :     move16();
     135             : 
     136             :     /* get configuration index */
     137         279 :     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         279 :     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         262 :         case 2:
     152         262 :             st_ivas->nCPE = 1;
     153         262 :             move16();
     154         262 :             st_ivas->nSCE = 0;
     155         262 :             move16();
     156         262 :             st_ivas->hEncoderConfig->element_mode_init = IVAS_CPE_MDCT;
     157         262 :             move16();
     158         262 :             BREAK;
     159             :     }
     160             : 
     161             :     /* get dmx factors */
     162         279 :     hParamMC->dmx_factors_fx = ivas_param_mc_conf[config_index].dmx_fac_fx; // Q31
     163             : 
     164             :     /* set FB config. */
     165         279 :     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         279 :     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         279 :     ivas_param_mc_metadata_open_fx( mc_input_setup, ivas_total_brate, &hParamMC->hMetadataPMC );
     178             : 
     179             :     /* Band Grouping */
     180         279 :     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         276 :     ELSE IF( EQ_16( hParamMC->hMetadataPMC.num_parameter_bands, 14 ) )
     185             :     {
     186         135 :         Copy( param_mc_band_grouping_14, hParamMC->band_grouping, 14 + 1 );
     187             :     }
     188         141 :     ELSE IF( EQ_16( hParamMC->hMetadataPMC.num_parameter_bands, 10 ) )
     189             :     {
     190         141 :         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         279 :     i = 0;
     199         279 :     move16();
     200        2514 :     WHILE( hParamMC->band_grouping[i] <= PARAM_MC_MAX_BAND_ABS_COV_ENC )
     201             :     {
     202        2235 :         hParamMC->max_param_band_abs_cov = i;
     203        2235 :         move16();
     204        2235 :         i = add( i, 1 );
     205             :     }
     206             : 
     207             :     /* parameter band grouping: 60 band CLDFB to 240 band MDFT resolution */
     208        3918 :     FOR( i = 0; i < hParamMC->hMetadataPMC.num_parameter_bands + 1; i++ )
     209             :     {
     210        3639 :         hParamMC->band_grouping[i] = i_mult( hParamMC->band_grouping[i], PARAM_MC_CLDFB_TO_MDFT_FAC );
     211        3639 :         move16();
     212             :     }
     213             : 
     214             :     /* set correct coded band width */
     215         279 :     hParamMC->hMetadataPMC.coded_bwidth = max_bwidth;
     216         279 :     move16();
     217         279 :     hParamMC->hMetadataPMC.last_coded_bwidth = max_bwidth;
     218         279 :     move16();
     219         279 :     ivas_param_mc_set_coded_bands_fx( &hParamMC->hMetadataPMC );
     220             : 
     221             :     /* initialize offset for transient detection */
     222         279 :     tmp1 = NS2SA_FX2( input_Fs, DELAY_DIRAC_ENC_CMP_NS );
     223         279 :     move16();
     224         279 :     tmp2 = NS2SA_FX2( input_Fs, 2 * DIRAC_SLOT_NS );
     225         279 :     move16();
     226         279 :     tmp1 = idiv1616( sub( add( tmp1, tmp2 ), 1 ), tmp2 );
     227         279 :     hParamMC->transient_detector_delay = sub( ( NSUBBLOCKS_SHIFT + 1 ) + NSUBBLOCKS + 1, tmp1 );
     228         279 :     move16();
     229             : 
     230             :     /* Init total/dmx ener factors */
     231         279 :     set32_fx( hParamMC->ener_fac_fx, 0, PARAM_MC_MAX_PARAMETER_BANDS ); // Q21
     232             : 
     233             :     /* init previous ILDs */
     234        5859 :     FOR( i = 0; i < PARAM_MC_MAX_PARAMETER_BANDS; i++ )
     235             :     {
     236        5580 :         set32_fx( hParamMC->prev_ilds_fx[i], 0, PARAM_MC_SZ_ILD_MAP ); // Q21
     237             :     }
     238             : 
     239         279 :     st_ivas->hParamMC = hParamMC;
     240             : 
     241         279 :     return error;
     242             : }
     243             : 
     244             : 
     245             : /*-------------------------------------------------------------------------
     246             :  * ivas_param_mc_enc_reconfig()
     247             :  *
     248             :  * Reconfigure Parametric MC encoder
     249             :  *------------------------------------------------------------------------*/
     250             : 
     251          65 : 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          65 :     error = IVAS_ERR_OK;
     265          65 :     move16();
     266             : 
     267          65 :     mc_input_setup = st_ivas->hEncoderConfig->mc_input_setup;
     268          65 :     move32();
     269          65 :     max_bwidth = st_ivas->hEncoderConfig->max_bwidth;
     270          65 :     move16();
     271          65 :     input_Fs = st_ivas->hEncoderConfig->input_Fs;
     272          65 :     move32();
     273          65 :     ivas_total_brate = st_ivas->hEncoderConfig->ivas_total_brate;
     274          65 :     move32();
     275          65 :     hParamMC = st_ivas->hParamMC;
     276             : 
     277             :     /* Preparing Config */
     278          65 :     st_ivas->nchan_transport = ivas_param_mc_getNumTransportChannels_fx( ivas_total_brate, mc_input_setup );
     279          65 :     move16();
     280             : 
     281             :     /* get configuration index */
     282          65 :     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          65 :     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          65 :         case 2:
     297          65 :             st_ivas->nCPE = 1;
     298          65 :             move16();
     299          65 :             st_ivas->nSCE = 0;
     300          65 :             move16();
     301          65 :             st_ivas->hEncoderConfig->element_mode_init = IVAS_CPE_MDCT;
     302          65 :             move16();
     303          65 :             BREAK;
     304             :     }
     305             : 
     306             :     /* get dmx factors */
     307          65 :     hParamMC->dmx_factors_fx = ivas_param_mc_conf[config_index].dmx_fac_fx; // Q31
     308             : 
     309             :     /* open/init parameter coding */
     310          65 :     ivas_param_mc_metadata_open_fx( mc_input_setup, ivas_total_brate, &hParamMC->hMetadataPMC );
     311             : 
     312             :     /* Band Grouping */
     313          65 :     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          65 :     ELSE IF( EQ_16( hParamMC->hMetadataPMC.num_parameter_bands, 14 ) )
     318             :     {
     319          34 :         Copy( param_mc_band_grouping_14, hParamMC->band_grouping, 14 + 1 );
     320             :     }
     321          31 :     ELSE IF( EQ_16( hParamMC->hMetadataPMC.num_parameter_bands, 10 ) )
     322             :     {
     323          31 :         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          65 :     i = 0;
     332          65 :     move16();
     333         588 :     WHILE( hParamMC->band_grouping[i] <= PARAM_MC_MAX_BAND_ABS_COV_ENC )
     334             :     {
     335         523 :         hParamMC->max_param_band_abs_cov = i;
     336         523 :         move16();
     337         523 :         i = add( i, 1 );
     338             :     }
     339             : 
     340             :     /* parameter band grouping: 60 band CLDFB to 240 band MDFT resolution */
     341         916 :     FOR( i = 0; i < hParamMC->hMetadataPMC.num_parameter_bands + 1; i++ )
     342             :     {
     343         851 :         hParamMC->band_grouping[i] = i_mult( hParamMC->band_grouping[i], PARAM_MC_CLDFB_TO_MDFT_FAC );
     344         851 :         move16();
     345             :     }
     346             : 
     347             :     /* set correct coded band width */
     348          65 :     hParamMC->hMetadataPMC.coded_bwidth = max_bwidth;
     349          65 :     move16();
     350          65 :     hParamMC->hMetadataPMC.last_coded_bwidth = max_bwidth;
     351          65 :     move16();
     352          65 :     ivas_param_mc_set_coded_bands_fx( &hParamMC->hMetadataPMC );
     353             : 
     354             :     /* initialize offset for transient detection */
     355          65 :     tmp1 = NS2SA_FX2( input_Fs, DELAY_DIRAC_ENC_CMP_NS );
     356          65 :     move16();
     357          65 :     tmp2 = NS2SA_FX2( input_Fs, 2 * DIRAC_SLOT_NS );
     358          65 :     move16();
     359          65 :     tmp1 = idiv1616( sub( add( tmp1, tmp2 ), 1 ), tmp2 );
     360          65 :     hParamMC->transient_detector_delay = sub( ( NSUBBLOCKS_SHIFT + 1 ) + NSUBBLOCKS + 1, tmp1 );
     361          65 :     move16();
     362             : 
     363             :     /* Init total/dmx ener factors */
     364          65 :     set32_fx( hParamMC->ener_fac_fx, 0, PARAM_MC_MAX_PARAMETER_BANDS ); // Q21
     365             : 
     366             : 
     367          65 :     return error;
     368             : }
     369             : 
     370             : 
     371             : /*-------------------------------------------------------------------------
     372             :  * ivas_param_mc_enc_close()
     373             :  *
     374             :  * Close Parametric MC encoder handle
     375             :  *------------------------------------------------------------------------*/
     376             : 
     377        1210 : 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        1210 :     test();
     382        1210 :     IF( hParamMC == NULL || *hParamMC == NULL )
     383             :     {
     384         931 :         return;
     385             :     }
     386             : 
     387         279 :     ivas_FB_mixer_close_fx( &( *hParamMC )->hFbMixer, sampling_rate, 0 );
     388             : 
     389         279 :     free( ( *hParamMC ) );
     390         279 :     ( *hParamMC ) = NULL;
     391             : 
     392         279 :     return;
     393             : }
     394             : 
     395             : 
     396             : /*-------------------------------------------------------------------------
     397             :  * ivas_param_mc_enc()
     398             :  *
     399             :  * Parametric MC Encoder main encoding function
     400             :  *------------------------------------------------------------------------*/
     401             : 
     402       10250 : 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       10250 :     push_wmops( "param_mc_enc" );
     429             : 
     430             :     /* initializations */
     431       10250 :     hParamMC = st_ivas->hParamMC;
     432       10250 :     bit_pos = 0;
     433       10250 :     move16();
     434       10250 :     band_step = 1;
     435       10250 :     move16();
     436       10250 :     nchan_inp = st_ivas->hEncoderConfig->nchan_inp;
     437       10250 :     move16();
     438             : 
     439      215250 :     FOR( band = 0; band < PARAM_MC_MAX_PARAMETER_BANDS; band++ )
     440             :     {
     441     3485000 :         FOR( ch = 0; ch < MAX_CICP_CHANNELS; ch++ )
     442             :         {
     443     3280000 :             set32_fx( Cy_sum_fx[band][ch], 0, MAX_CICP_CHANNELS );
     444     3280000 :             set16_fx( Cy_sum_e[band][ch], 0, MAX_CICP_CHANNELS );
     445             :         }
     446      820000 :         FOR( ch = 0; ch < PARAM_MC_MAX_TRANSPORT_CHANS; ch++ )
     447             :         {
     448      615000 :             set32_fx( Cx_sum_fx[band][ch], 0, PARAM_MC_MAX_TRANSPORT_CHANS );
     449      615000 :             set16_fx( Cx_sum_e[band][ch], 0, PARAM_MC_MAX_TRANSPORT_CHANS );
     450             :         }
     451             :     }
     452             : 
     453       10250 :     set16_fx( ILD_idx, 0, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_SZ_ILD_MAP );
     454       10250 :     set16_fx( ICC_idx, 0, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_SZ_ICC_MAP );
     455             : 
     456             :     /* update parameter frame index */
     457       10250 :     hParamMC->hMetadataPMC.param_frame_idx = add( hParamMC->hMetadataPMC.param_frame_idx, 1 ) % PARAM_MC_PARAMETER_FRAMES;
     458       10250 :     move16();
     459             : 
     460             :     /* DMX generation*/
     461       10250 :     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       10250 :     SWITCH( st_ivas->nchan_transport )
     465             :     {
     466       10250 :         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       10250 :             set16_fx( attackIdx, -1, PARAM_MC_MAX_TRANSPORT_CHANS );
     475       10250 :             set16_fx( bAttackPresent, 0, PARAM_MC_MAX_TRANSPORT_CHANS );
     476             : 
     477       30860 :             FOR( ch = 0; ch < st_ivas->nchan_transport; ch++ )
     478             :             {
     479       20610 :                 Word16 cpe_idx = shr( ch, 1 );
     480             : 
     481       20610 :                 q_data_dmx_fx16 = sub( L_norm_arr( data_dmx_fx[ch], input_frame ), 16 );
     482       20610 :                 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       20610 :                 q_data_dmx_fx16 = add( q_data_dmx_fx16, Q11 );
     484             : 
     485       20610 :                 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       20610 :                 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       10250 :             hParamMC->hMetadataPMC.bAttackPresent = 0;
     492       10250 :             move16();
     493       10250 :             hParamMC->hMetadataPMC.attackIndex = 16;
     494       10250 :             move16();
     495             : 
     496       30860 :             FOR( ch = 0; ch < st_ivas->nchan_transport; ch++ )
     497             :             {
     498       20610 :                 hParamMC->hMetadataPMC.bAttackPresent = s_max( hParamMC->hMetadataPMC.bAttackPresent, bAttackPresent[ch] );
     499       20610 :                 move16();
     500             :             }
     501             : 
     502       10250 :             IF( hParamMC->hMetadataPMC.bAttackPresent )
     503             :             {
     504        1500 :                 FOR( ch = 0; ch < st_ivas->nchan_transport; ch++ )
     505             :                 {
     506        1010 :                     hParamMC->hMetadataPMC.attackIndex = s_min( hParamMC->hMetadataPMC.attackIndex, attackIdx[ch] );
     507        1010 :                     move16();
     508             :                 }
     509             :             }
     510             :             ELSE
     511             :             {
     512        9760 :                 hParamMC->hMetadataPMC.attackIndex = 0;
     513        9760 :                 move16();
     514             :             }
     515             :         }
     516       10250 :             BREAK;
     517             :     }
     518             : 
     519             :     /* Encoding */
     520             :     /* parameter estimation*/
     521       10250 :     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       10250 :     IF( hParamMC->hMetadataPMC.bAttackPresent )
     524             :     {
     525         490 :         band_step = PARAM_MC_TRANSIENT_BAND_STEP;
     526         490 :         move16();
     527             :     }
     528             :     ELSE
     529             :     {
     530        9760 :         band_step = 1;
     531        9760 :         move16();
     532             :     }
     533             : 
     534             : 
     535             :     /* ILD parameter quantization */
     536      142356 :     FOR( k = 0; k < hParamMC->hMetadataPMC.nbands_coded; k += band_step )
     537             :     {
     538      132106 :         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      142356 :     FOR( k = 0; k < hParamMC->hMetadataPMC.nbands_coded; k += band_step )
     543             :     {
     544      132106 :         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       30860 :     FOR( ch = 0; ch < st_ivas->nchan_transport; ch++ )
     550             :     {
     551       20610 :         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       10250 :     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       10250 :     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       10250 :     push_next_bits( hMetaData, bit_buffer, bit_pos );
     574             : 
     575             :     /* updates */
     576       10250 :     hParamMC->hMetadataPMC.last_coded_bwidth = hParamMC->hMetadataPMC.coded_bwidth;
     577       10250 :     move16();
     578             : 
     579       10250 :     pop_wmops();
     580             : 
     581       10250 :     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       10250 : 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       10250 :     idx = Param_MC_index;
     611     9741450 :     FOR( i = 0; i < input_frame; i++ )
     612             :     {
     613     9731200 :         p_dmx_fac_fx = hParamMC->dmx_factors_fx;
     614    29299200 :         FOR( dmx_ch = 0; dmx_ch < nchan_transport; dmx_ch++ )
     615             :         {
     616    19568000 :             Word32 *dmx_sample_fx = &data_dmx_fx[idx[dmx_ch]][i];
     617    19568000 :             *dmx_sample_fx = 0;
     618    19568000 :             move16();
     619   140412800 :             FOR( inp_ch = 0; inp_ch < nchan_input; inp_ch++ )
     620             :             {
     621   120844800 :                 ( *dmx_sample_fx ) = Madd_32_32( ( *dmx_sample_fx ), data_f_fx[idx[inp_ch]][i], ( *( p_dmx_fac_fx++ ) ) ); // Q_x - 11
     622   120844800 :                 move16();
     623             :             }
     624             :         }
     625             :     }
     626             : 
     627       10250 :     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       10250 : 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       10250 :     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             :     Word64 dmx_real_64[PARAM_MC_MAX_TRANSPORT_CHANS];
     668             :     Word64 dmx_imag_64[PARAM_MC_MAX_TRANSPORT_CHANS];
     669             :     Word32 a_fx, b_fx, c_fx, d_fx; /* Tmp complex values */
     670             :     Word16 a_e, b_e, c_e, d_e;     /* Tmp complex values */
     671             :     Word64 Cy_sum_real_64[PARAM_MC_MAX_PARAMETER_BANDS][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS];
     672             :     Word64 Cy_sum_imag_64[PARAM_MC_MAX_PARAM_BAND_ABS_COV_ENC][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS];
     673             :     Word16 sub62gb;
     674             :     Word16 sub35gb;
     675             :     Word32 Cx_sum_imag_fx[PARAM_MC_MAX_PARAM_BAND_ABS_COV_ENC][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS];
     676             :     Word16 Cx_sum_imag_e[PARAM_MC_MAX_PARAM_BAND_ABS_COV_ENC][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS];
     677             :     Word32 real_part_fx, imag_part_fx;
     678             :     Word16 real_part_e, imag_part_e;
     679             :     const Word32 *p_dmx_fac_fx;
     680             :     Word32 L_tmp;
     681             :     Word16 tmp_e;
     682             : 
     683       10250 :     push_wmops( "param_mc_prm_est" );
     684             : 
     685             :     /* initializations */
     686       10250 :     l_ts = extract_l( Mpy_32_16_1( input_frame, INV_PARAM_MC_MDFT_NO_SLOTS_FX ) );
     687       10250 :     num_time_slots = PARAM_MC_MDFT_NO_SLOTS;
     688       10250 :     move16();
     689       10250 :     IF( hParamMC->hMetadataPMC.bAttackPresent )
     690             :     {
     691         490 :         start_ts = hParamMC->hMetadataPMC.attackIndex;
     692         490 :         move16();
     693             :     }
     694             :     ELSE
     695             :     {
     696        9760 :         start_ts = 0;
     697        9760 :         move16();
     698             :     }
     699       10250 :     num_parameter_bands = hParamMC->hMetadataPMC.nbands_coded;
     700       10250 :     move16();
     701       10250 :     band_step = 1;
     702       10250 :     move16();
     703      215250 :     FOR( cur_param_band = 0; cur_param_band < PARAM_MC_MAX_PARAMETER_BANDS; cur_param_band++ )
     704             :     {
     705     3485000 :         FOR( ch_idx1 = 0; ch_idx1 < MAX_CICP_CHANNELS; ch_idx1++ )
     706             :         {
     707     3280000 :             set64_fx( Cy_sum_real_64[cur_param_band][ch_idx1], 0, MAX_CICP_CHANNELS );
     708             :         }
     709             :     }
     710             : 
     711      112750 :     FOR( cur_param_band = 0; cur_param_band < PARAM_MC_MAX_PARAM_BAND_ABS_COV_ENC; cur_param_band++ )
     712             :     {
     713     1742500 :         FOR( ch_idx1 = 0; ch_idx1 < MAX_CICP_CHANNELS; ch_idx1++ )
     714             :         {
     715     1640000 :             set64_fx( Cy_sum_imag_64[cur_param_band][ch_idx1], 0, MAX_CICP_CHANNELS );
     716             :         }
     717             : 
     718      410000 :         FOR( ch_idx1 = 0; ch_idx1 < PARAM_MC_MAX_TRANSPORT_CHANS; ch_idx1++ )
     719             :         {
     720      307500 :             set32_fx( Cx_sum_imag_fx[cur_param_band][ch_idx1], 0, PARAM_MC_MAX_TRANSPORT_CHANS );
     721      307500 :             set16_fx( Cx_sum_imag_e[cur_param_band][ch_idx1], 0, PARAM_MC_MAX_TRANSPORT_CHANS );
     722             :         }
     723             :     }
     724             : 
     725             :     /* Copy current frame to memory for delay compensation */
     726       73270 :     FOR( i = 0; i < nchan_input; i++ )
     727             :     {
     728       63020 :         idx_ls = map_ls[i];
     729       63020 :         move16();
     730       63020 :         pcm_in_fx[i] = data_f_fx[idx_ls];
     731       63020 :         p_slot_frame_f_real_fx[i] = &slot_frame_f_real_fx[i][0];
     732       63020 :         p_slot_frame_f_imag_fx[i] = &slot_frame_f_imag_fx[i][0];
     733             :     }
     734             : 
     735       11907 :     FOR( ts = 0; ts < start_ts; ts++ )
     736             :     {
     737        1657 :         ivas_fb_mixer_update_prior_input_fx( hParamMC->hFbMixer, pcm_in_fx, l_ts, hParamMC->hFbMixer->fb_cfg->num_in_chans );
     738       12453 :         FOR( i = 0; i < nchan_input; i++ )
     739             :         {
     740       10796 :             pcm_in_fx[i] += l_ts;
     741             :         }
     742             :     }
     743             : 
     744       10250 :     Word16 gb = find_guarded_bits_fx( l_ts );
     745             : 
     746       10250 :     sub35gb = sub( 32, sub( 11, find_guarded_bits_fx( l_ts ) ) );           // 31 - (((11 - gb) + 31 + norm) - 32)
     747       10250 :     sub62gb = sub( 63, shl( sub( 11, find_guarded_bits_fx( l_ts ) ), 1 ) ); // 31 - ((2*(11 - gb) + norm) - 32)
     748             : 
     749       90593 :     FOR( ts = start_ts; ts < num_time_slots; ts++ )
     750             :     {
     751       80343 :         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 );
     752       80343 :         ivas_fb_mixer_update_prior_input_fx( hParamMC->hFbMixer, pcm_in_fx, l_ts, hParamMC->hFbMixer->fb_cfg->num_in_chans );
     753             : 
     754             :         /* slot_frame_f buffer Q = 11 - gb : exponent = 20 + gb */
     755             : 
     756      573707 :         FOR( i = 0; i < nchan_input; i++ )
     757             :         {
     758      493364 :             pcm_in_fx[i] += l_ts;
     759      493364 :             move32();
     760             :         }
     761             :         /* Computing the downmix */
     762      693761 :         FOR( cur_param_band = 0; cur_param_band < hParamMC->max_param_band_abs_cov; cur_param_band++ )
     763             :         {
     764      613418 :             brange[0] = hParamMC->band_grouping[cur_param_band];
     765      613418 :             move16();
     766      613418 :             brange[1] = hParamMC->band_grouping[cur_param_band + 1];
     767      613418 :             move16();
     768             : 
     769     2220278 :             FOR( cur_cldfb_band = brange[0]; cur_cldfb_band < brange[1]; cur_cldfb_band++ )
     770             :             {
     771             :                 /* Cx for DMX */
     772             :                 /* Real Part */
     773     1606860 :                 p_dmx_fac_fx = hParamMC->dmx_factors_fx;
     774             : 
     775     4836340 :                 FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 )
     776             :                 {
     777             :                     Word64 real_64;
     778             :                     Word64 imag_64;
     779             : 
     780     3229480 :                     real_64 = 0;
     781     3229480 :                     imag_64 = 0;
     782     3229480 :                     move64();
     783     3229480 :                     move64();
     784    23135880 :                     FOR( inp_ch = 0; inp_ch < nchan_input; inp_ch++ )
     785             :                     {
     786    19906400 :                         real_64 = W_add( real_64, W_mult0_32_32( slot_frame_f_real_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) ) );
     787    19906400 :                         imag_64 = W_add( imag_64, W_mult0_32_32( slot_frame_f_imag_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) ) );
     788    19906400 :                         p_dmx_fac_fx++;
     789             :                     }
     790     3229480 :                     dmx_real_64[ch_idx1] = real_64;
     791     3229480 :                     dmx_imag_64[ch_idx1] = imag_64;
     792     3229480 :                     move64();
     793     3229480 :                     move64();
     794             :                 }
     795             : 
     796             :                 /* Cx for transport channels */
     797     4836340 :                 FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 )
     798             :                 {
     799     3229480 :                     CONVERT_DMX( dmx_real_64[ch_idx1], a_fx, a_e );
     800     3229480 :                     CONVERT_DMX( dmx_imag_64[ch_idx1], b_fx, b_e );
     801     9735720 :                     FOR( ch_idx2 = 0; ch_idx2 < nchan_transport; ++ch_idx2 )
     802             :                     {
     803     6506240 :                         CONVERT_DMX( dmx_real_64[ch_idx2], c_fx, c_e );
     804     6506240 :                         CONVERT_DMX( dmx_imag_64[ch_idx2], d_fx, d_e );
     805             : 
     806             :                         /* (a-ib)(c+id) = ac + bd + i(ad-bc) */
     807     6506240 :                         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 );
     808    13012480 :                         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],
     809     6506240 :                                                                                                 L_tmp, tmp_e, &Cx_sum_e[cur_param_band][ch_idx1][ch_idx2] );
     810     6506240 :                         move32();
     811     6506240 :                         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 );
     812    13012480 :                         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],
     813     6506240 :                                                                                                      L_tmp, tmp_e, &Cx_sum_imag_e[cur_param_band][ch_idx1][ch_idx2] );
     814     6506240 :                         move32();
     815             :                     }
     816             :                 }
     817    11474140 :                 FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 )
     818             :                 {
     819     9867280 :                     a_fx = slot_frame_f_real_fx[ch_idx1][cur_cldfb_band];
     820     9867280 :                     b_fx = slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band];
     821     9867280 :                     move32();
     822    45444520 :                     FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 )
     823             :                     {
     824    35577240 :                         c_fx = slot_frame_f_real_fx[ch_idx2][cur_cldfb_band];
     825    35577240 :                         d_fx = slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band];
     826    35577240 :                         move32();
     827             :                         // Conjugated complex multiplication (a-ib)(c+id) = ac+bd + i(ad-bc)
     828    35577240 :                         Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2] = W_add( Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2],
     829             :                                                                                   W_add( W_mult0_32_32( a_fx, c_fx ), W_mult0_32_32( b_fx, d_fx ) ) );
     830    35577240 :                         move64();
     831    35577240 :                         Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2] = W_add( Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2],
     832             :                                                                                   W_sub( W_mult0_32_32( a_fx, d_fx ), W_mult0_32_32( b_fx, c_fx ) ) );
     833    35577240 :                         move64();
     834             :                     }
     835             :                 }
     836             :             }
     837             :         }
     838             : 
     839      527628 :         FOR( ; cur_param_band < num_parameter_bands; cur_param_band++ )
     840             :         {
     841      447285 :             brange[0] = hParamMC->band_grouping[cur_param_band];
     842      447285 :             move16();
     843      447285 :             brange[1] = hParamMC->band_grouping[cur_param_band + 1];
     844      447285 :             move16();
     845             : 
     846     8274025 :             FOR( cur_cldfb_band = brange[0]; cur_cldfb_band < brange[1]; cur_cldfb_band++ )
     847             :             {
     848             :                 /* Cx for DMX */
     849             :                 /* Real Part */
     850     7826740 :                 p_dmx_fac_fx = hParamMC->dmx_factors_fx; // Q31
     851             : 
     852    23559020 :                 FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 )
     853             :                 {
     854             :                     Word64 real_64;
     855             :                     Word64 imag_64;
     856             : 
     857    15732280 :                     real_64 = 0;
     858    15732280 :                     imag_64 = 0;
     859    15732280 :                     move64();
     860    15732280 :                     move64();
     861             : 
     862   112773560 :                     FOR( inp_ch = 0; inp_ch < nchan_input; inp_ch++ )
     863             :                     {
     864    97041280 :                         real_64 = W_add( real_64, W_mult0_32_32( slot_frame_f_real_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) ) );
     865    97041280 :                         imag_64 = W_add( imag_64, W_mult0_32_32( slot_frame_f_imag_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) ) );
     866    97041280 :                         p_dmx_fac_fx++;
     867             :                     }
     868    15732280 :                     dmx_real_64[ch_idx1] = real_64;
     869    15732280 :                     dmx_imag_64[ch_idx1] = imag_64;
     870    15732280 :                     move64();
     871    15732280 :                     move64();
     872             :                 }
     873             : 
     874             :                 /* Cx for transport channels */
     875    23559020 :                 FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 )
     876             :                 {
     877    15732280 :                     CONVERT_DMX( dmx_real_64[ch_idx1], a_fx, a_e );
     878    15732280 :                     CONVERT_DMX( dmx_imag_64[ch_idx1], b_fx, b_e );
     879    47433240 :                     FOR( ch_idx2 = 0; ch_idx2 < nchan_transport; ++ch_idx2 )
     880             :                     {
     881    31700960 :                         CONVERT_DMX( dmx_real_64[ch_idx2], c_fx, c_e );
     882    31700960 :                         CONVERT_DMX( dmx_imag_64[ch_idx2], d_fx, d_e );
     883             : 
     884             :                         /* (a-ib)(c+id) = ac + bd + i(ad-bc) */
     885    31700960 :                         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 );
     886    63401920 :                         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,
     887    31700960 :                                                                                                 &Cx_sum_e[cur_param_band][ch_idx1][ch_idx2] );
     888    31700960 :                         move32();
     889             :                     }
     890             :                 }
     891             : 
     892             :                 /* Cy for input channels */
     893    55917780 :                 FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 )
     894             :                 {
     895    48091040 :                     a_fx = slot_frame_f_real_fx[ch_idx1][cur_cldfb_band];
     896    48091040 :                     b_fx = slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band];
     897    48091040 :                     move32();
     898    48091040 :                     move32();
     899   221618480 :                     FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 )
     900             :                     {
     901   173527440 :                         c_fx = slot_frame_f_real_fx[ch_idx2][cur_cldfb_band];
     902   173527440 :                         d_fx = slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band];
     903   173527440 :                         move32();
     904   173527440 :                         move32();
     905             :                         // Conjugated complex multiplication (a-ib)(c+id) = ac+bd + i(ad-bc)
     906   173527440 :                         Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2] = W_add( Cy_sum_real_64[cur_param_band][ch_idx1][ch_idx2],
     907             :                                                                                   W_add( W_mult0_32_32( a_fx, c_fx ), W_mult0_32_32( b_fx, d_fx ) ) );
     908   173527440 :                         move64();
     909             :                     }
     910             :                 }
     911             :             }
     912             :         }
     913             :     }
     914             : 
     915             :     /* make sure energy and correlation is zero above the relevant LFE bands for LFE
     916             :      * avoids wrong energy in case of band combining at transients */
     917       10250 :     IF( hParamMC->lfe_index >= 0 )
     918             :     {
     919       78220 :         FOR( cur_param_band = PARAM_MC_MAX_BAND_LFE; cur_param_band < hParamMC->max_param_band_abs_cov; cur_param_band++ )
     920             :         {
     921      486350 :             FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 )
     922             :             {
     923      418380 :                 Cy_sum_real_64[cur_param_band][hParamMC->lfe_index][ch_idx1] = 0;
     924      418380 :                 move64();
     925      418380 :                 Cy_sum_real_64[cur_param_band][ch_idx1][hParamMC->lfe_index] = 0;
     926      418380 :                 move64();
     927      418380 :                 Cy_sum_imag_64[cur_param_band][hParamMC->lfe_index][ch_idx1] = 0;
     928      418380 :                 move64();
     929      418380 :                 Cy_sum_imag_64[cur_param_band][ch_idx1][hParamMC->lfe_index] = 0;
     930      418380 :                 move64();
     931             :             }
     932             :         }
     933             : 
     934       67260 :         FOR( ; cur_param_band < num_parameter_bands; cur_param_band++ )
     935             :         {
     936      408230 :             FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 )
     937             :             {
     938      351220 :                 Cy_sum_real_64[cur_param_band][hParamMC->lfe_index][ch_idx1] = 0;
     939      351220 :                 move64();
     940      351220 :                 Cy_sum_real_64[cur_param_band][ch_idx1][hParamMC->lfe_index] = 0;
     941      351220 :                 move64();
     942             :             }
     943             :         }
     944             :     }
     945             : 
     946       10250 :     IF( !hParamMC->hMetadataPMC.bAttackPresent )
     947             :     {
     948             :         const PARAM_MC_ILD_MAPPING *h_ild_mapping;
     949             :         Word16 ild_attack;
     950        9760 :         ild_attack = 0;
     951        9760 :         move16();
     952        9760 :         h_ild_mapping = hParamMC->hMetadataPMC.ild_mapping_conf;
     953             :         /* create ILDs for to non transmitted parameter bands (only lower half) */
     954       74573 :         FOR( cur_param_band = 0; cur_param_band < hParamMC->hMetadataPMC.num_parameter_bands / 2; cur_param_band++ )
     955             :         {
     956             :             Word32 ILD_fx[PARAM_MC_SZ_ILD_MAP];
     957             :             Word16 k;
     958             :             Word16 num_ilds_to_code;
     959             : 
     960       64813 :             IF( GE_16( cur_param_band, PARAM_MC_MAX_BAND_LFE ) )
     961             :             {
     962       55053 :                 num_ilds_to_code = hParamMC->hMetadataPMC.ild_mapping_conf->ild_map_size_wo_lfe;
     963       55053 :                 move16();
     964             :             }
     965             :             ELSE
     966             :             {
     967        9760 :                 num_ilds_to_code = hParamMC->hMetadataPMC.ild_mapping_conf->ild_map_size_lfe;
     968        9760 :                 move16();
     969             :             }
     970       64813 :             IF( NE_16( hParamMC->hMetadataPMC.param_frame_idx, hParamMC->hMetadataPMC.coding_band_mapping[cur_param_band] ) )
     971             :             {
     972             :                 Word32 Nrg_fx[MAX_CICP_CHANNELS];
     973             :                 Word16 Nrg_e[MAX_CICP_CHANNELS];
     974             : 
     975             :                 /* get ICLDs */
     976      231161 :                 FOR( k = 0; k < nchan_input; ++k )
     977             :                 {
     978      198792 :                     CONVERT_CY( Cy_sum_real_64[cur_param_band][k][k], Nrg_fx[k], Nrg_e[k] );
     979      198792 :                     move32();
     980      198792 :                     move16();
     981             :                 }
     982      203355 :                 FOR( k = 0; k < num_ilds_to_code; ++k )
     983             :                 {
     984      170986 :                     Word32 ref_ener_fx = 0;
     985      170986 :                     move32();
     986      170986 :                     Word16 ref_ener_e = 0;
     987      170986 :                     move16();
     988             :                     Word16 ref_channel_cnt;
     989             :                     Word16 ref_channel_idx;
     990             : 
     991      378816 :                     FOR( ref_channel_cnt = 0; ref_channel_cnt < h_ild_mapping->num_ref_channels[k]; ref_channel_cnt++ )
     992             :                     {
     993      207830 :                         ref_channel_idx = h_ild_mapping->ref_channel_idx[k][ref_channel_cnt];
     994      207830 :                         move16();
     995      207830 :                         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
     996      207830 :                                                                 Cx_sum_e[cur_param_band][ref_channel_idx][ref_channel_idx], &ref_ener_e );
     997             :                     }
     998      170986 :                     L_tmp = Mpy_32_16_1( ref_ener_fx, hParamMC->hMetadataPMC.ild_factors_fx[k] );
     999      170986 :                     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 ) );
    1000             : 
    1001      170986 :                     tmp_e = add( sub( Nrg_e[h_ild_mapping->ild_index[k]], ref_ener_e ), tmp_e );
    1002             : 
    1003             :                     /*1342177280 = 10 in Q27*/
    1004      170986 :                     ILD_fx[k] = Mpy_32_32( 1342177280, BASOP_Util_Log10( L_tmp, tmp_e ) ); // Q25 + Q27 - Q31 = Q21
    1005      170986 :                     move32();
    1006             : 
    1007      170986 :                     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] ) )
    1008             :                     {
    1009         313 :                         ild_attack = add( ild_attack, 1 );
    1010             :                     }
    1011             :                 }
    1012             :             }
    1013             :         }
    1014             :         /* check if the ILDs change too much -> go into transient mode... */
    1015        9760 :         if ( GT_16( ild_attack, PARAM_MC_NUM_ATTACK_ILD_THRESH ) )
    1016             :         {
    1017           0 :             hParamMC->hMetadataPMC.bAttackPresent = 1;
    1018           0 :             move16();
    1019             :         }
    1020             :     }
    1021             : 
    1022             : 
    1023       10250 :     IF( hParamMC->hMetadataPMC.bAttackPresent )
    1024             :     {
    1025             :         /* combine bands */
    1026        2325 :         FOR( cur_param_band = 1; cur_param_band < hParamMC->max_param_band_abs_cov; cur_param_band += 2 )
    1027             :         {
    1028        5632 :             FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 )
    1029             :             {
    1030       11772 :                 FOR( ch_idx2 = 0; ch_idx2 < nchan_transport; ++ch_idx2 )
    1031             :                 {
    1032       15950 :                     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],
    1033        7975 :                                                                                                 Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cx_sum_e[cur_param_band][ch_idx1][ch_idx2],
    1034        7975 :                                                                                                 &Cx_sum_e[cur_param_band - 1][ch_idx1][ch_idx2] );
    1035        7975 :                     move32();
    1036       15950 :                     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],
    1037        7975 :                                                                                                      Cx_sum_imag_fx[cur_param_band][ch_idx1][ch_idx2], Cx_sum_imag_e[cur_param_band][ch_idx1][ch_idx2],
    1038        7975 :                                                                                                      &Cx_sum_imag_e[cur_param_band - 1][ch_idx1][ch_idx2] );
    1039        7975 :                     move32();
    1040             :                 }
    1041             :             }
    1042             : 
    1043       13949 :             FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 )
    1044             :             {
    1045       60033 :                 FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 )
    1046             :                 {
    1047       47919 :                     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] );
    1048       47919 :                     move64();
    1049       47919 :                     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] );
    1050       47919 :                     move64();
    1051             :                 }
    1052             :             }
    1053             :         }
    1054             : 
    1055        1779 :         FOR( ; cur_param_band < num_parameter_bands; cur_param_band += 2 )
    1056             :         {
    1057        1289 :             IF( LT_16( cur_param_band, num_parameter_bands ) )
    1058             :             {
    1059        3971 :                 FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 )
    1060             :                 {
    1061        8358 :                     FOR( ch_idx2 = 0; ch_idx2 < nchan_transport; ++ch_idx2 )
    1062             :                     {
    1063       11352 :                         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],
    1064        5676 :                                                                                                     Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cx_sum_e[cur_param_band][ch_idx1][ch_idx2],
    1065        5676 :                                                                                                     &Cx_sum_e[cur_param_band - 1][ch_idx1][ch_idx2] );
    1066        5676 :                         move32();
    1067             :                     }
    1068             :                 }
    1069             : 
    1070        9863 :                 FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 )
    1071             :                 {
    1072       42771 :                     FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 )
    1073             :                     {
    1074       34197 :                         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] );
    1075             :                     }
    1076             :                 }
    1077             :             }
    1078             :         }
    1079             : 
    1080         490 :         band_step = 2;
    1081         490 :         move16();
    1082             :     }
    1083             :     {
    1084             :         // convert the 64 bit fixpoint back into the 48 bit float format
    1085      215250 :         FOR( cur_param_band = 0; cur_param_band < PARAM_MC_MAX_PARAMETER_BANDS; cur_param_band++ )
    1086             :         {
    1087     3485000 :             FOR( ch_idx1 = 0; ch_idx1 < MAX_CICP_CHANNELS; ch_idx1++ )
    1088             :             {
    1089    55760000 :                 FOR( ch_idx2 = 0; ch_idx2 < MAX_CICP_CHANNELS; ch_idx2++ )
    1090             :                 {
    1091    52480000 :                     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] );
    1092    52480000 :                     move32();
    1093    52480000 :                     move16();
    1094             :                 }
    1095             :             }
    1096             :         }
    1097             :     }
    1098             : 
    1099             :     /* map complex covariances to real values */
    1100       86635 :     FOR( cur_param_band = 0; cur_param_band < hParamMC->max_param_band_abs_cov; cur_param_band += band_step )
    1101             :     {
    1102             :         /* Cx for transport channels */
    1103      229968 :         FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ch_idx1++ )
    1104             :         {
    1105      463188 :             FOR( ch_idx2 = 0; ch_idx2 < nchan_transport; ch_idx2++ )
    1106             :             {
    1107      309605 :                 real_part_fx = Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2];
    1108      309605 :                 move32();
    1109      309605 :                 real_part_e = Cx_sum_e[cur_param_band][ch_idx1][ch_idx2];
    1110      309605 :                 move16();
    1111      309605 :                 imag_part_fx = Cx_sum_imag_fx[cur_param_band][ch_idx1][ch_idx2];
    1112      309605 :                 move32();
    1113      309605 :                 imag_part_e = Cx_sum_imag_e[cur_param_band][ch_idx1][ch_idx2];
    1114      309605 :                 move16();
    1115             : 
    1116      309605 :                 real_part_fx = Mpy_32_32( real_part_fx, real_part_fx );
    1117      309605 :                 imag_part_fx = Mpy_32_32( imag_part_fx, imag_part_fx );
    1118      309605 :                 L_tmp = BASOP_Util_Add_Mant32Exp( real_part_fx, shl( real_part_e, 1 ), imag_part_fx, shl( imag_part_e, 1 ), &tmp_e );
    1119             : 
    1120             :                 /* (a-ib)(c+id) = ac + bd + i(ad-bc) */
    1121      309605 :                 L_tmp = Sqrt32( L_tmp, &tmp_e );
    1122      309605 :                 Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2] = L_tmp;
    1123      309605 :                 move32();
    1124      309605 :                 Cx_sum_e[cur_param_band][ch_idx1][ch_idx2] = tmp_e;
    1125      309605 :                 move16();
    1126             :             }
    1127             :         }
    1128             : 
    1129             :         /* Cy for transport channels */
    1130      545671 :         FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ch_idx1++ )
    1131             :         {
    1132     2162267 :             FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ch_idx2++ )
    1133             :             {
    1134     1692981 :                 CONVERT_CY( Cy_sum_imag_64[cur_param_band][ch_idx1][ch_idx2], imag_part_fx, imag_part_e );
    1135     1692981 :                 move32();
    1136     1692981 :                 move16();
    1137     1692981 :                 real_part_fx = Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2];
    1138     1692981 :                 move32();
    1139     1692981 :                 real_part_e = Cy_sum_e[cur_param_band][ch_idx1][ch_idx2];
    1140     1692981 :                 move16();
    1141     1692981 :                 real_part_fx = Mpy_32_32( real_part_fx, real_part_fx );
    1142     1692981 :                 imag_part_fx = Mpy_32_32( imag_part_fx, imag_part_fx );
    1143             : 
    1144     1692981 :                 L_tmp = BASOP_Util_Add_Mant32Exp( real_part_fx, shl( real_part_e, 1 ), imag_part_fx, shl( imag_part_e, 1 ), &tmp_e );
    1145     1692981 :                 L_tmp = Sqrt32( L_tmp, &tmp_e );
    1146             : 
    1147     1692981 :                 Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2] = L_tmp;
    1148     1692981 :                 move32();
    1149     1692981 :                 Cy_sum_e[cur_param_band][ch_idx1][ch_idx2] = tmp_e;
    1150     1692981 :                 move16();
    1151             :             }
    1152             :         }
    1153             :     }
    1154             : 
    1155       10250 :     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 ) )
    1156             :     {
    1157        9181 :         hParamMC->hMetadataPMC.lfe_on = 0;
    1158        9181 :         move16();
    1159             :     }
    1160             :     ELSE
    1161             :     {
    1162        1069 :         hParamMC->hMetadataPMC.lfe_on = 1;
    1163        1069 :         move16();
    1164             :     }
    1165             : 
    1166       10250 :     pop_wmops();
    1167             : 
    1168       10250 :     return;
    1169             : }
    1170             : 
    1171             : /*-------------------------------------------------------------------------
    1172             :  * ivas_param_mc_quantize_ilds()
    1173             :  *
    1174             :  * Quantize the ILD parameters
    1175             :  *------------------------------------------------------------------------*/
    1176             : 
    1177      132106 : static void ivas_param_mc_quantize_ilds_fx(
    1178             :     PARAM_MC_ENC_HANDLE hParamMC,                                             /* i/o: Parametric MC encoder handle    */
    1179             :     Word32 Cy_fx[MAX_CICP_CHANNELS][MAX_CICP_CHANNELS],                       /* i  : Covariance matrix of the input  */
    1180             :     Word16 Cy_e[MAX_CICP_CHANNELS][MAX_CICP_CHANNELS],                        /* i  : Covariance matrix of the input  */
    1181             :     Word32 Cx_fx[PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS], /* i  : Covariance matrix of the dmx    */
    1182             :     Word16 Cx_e[PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS],  /* i  : Covariance matrix of the dmx    */
    1183             :     const Word16 freq_idx,                                                    /* i  : frequency index being processed */
    1184             :     const Word16 nchan_input,                                                 /* i  : number of input channels        */
    1185             :     const Word16 nchan_transport,                                             /* i  : number of transport channels    */
    1186             :     Word16 *ILD_idx_out,                                                      /* o  : ILD indices  */
    1187             :     Word16 ILD_q[PARAM_MC_SZ_ILD_MAP]                                         /* o  : Quanzited ILD matrix            */
    1188             : )
    1189             : {
    1190             :     Word16 i, k;
    1191             :     Word16 Ny;
    1192             :     Word16 num_ilds_to_code;
    1193             :     Word16 ild_map_size;
    1194             :     Word32 Nrg_fx[MAX_CICP_CHANNELS];
    1195             :     Word16 Nrg_e[MAX_CICP_CHANNELS];
    1196             :     Word32 ILD_fx[PARAM_MC_SZ_ILD_MAP];
    1197             :     Word16 ILD_e[PARAM_MC_SZ_ILD_MAP];
    1198             :     const PARAM_MC_ILD_MAPPING *h_ild_mapping;
    1199             :     Word32 tot_ener_fx, dmx_ener_fx, ener_fac_fx, delta_fac_fx;
    1200             :     Word16 tot_ener_e, dmx_ener_e;
    1201             :     Word16 ILD_idx[PARAM_MC_SZ_ILD_MAP];
    1202             :     Word32 L_tmp;
    1203             :     Word16 tmp_e;
    1204             : 
    1205      132106 :     push_wmops( "param_mc_prm_q" );
    1206             : 
    1207             :     /* Initialization */
    1208      132106 :     set32_fx( Nrg_fx, 0, MAX_CICP_CHANNELS );
    1209      132106 :     set32_fx( ILD_fx, 0, PARAM_MC_SZ_ILD_MAP );
    1210             : 
    1211      132106 :     Ny = nchan_input;
    1212      132106 :     move16();
    1213             : 
    1214      132106 :     h_ild_mapping = hParamMC->hMetadataPMC.ild_mapping_conf;
    1215      132106 :     ild_map_size = hParamMC->hMetadataPMC.ild_mapping_conf->ild_map_size_lfe;
    1216      132106 :     move16();
    1217      132106 :     IF( GE_16( freq_idx, PARAM_MC_MAX_BAND_LFE ) )
    1218             :     {
    1219      121856 :         num_ilds_to_code = hParamMC->hMetadataPMC.ild_mapping_conf->ild_map_size_wo_lfe;
    1220      121856 :         move16();
    1221             :     }
    1222             :     ELSE
    1223             :     {
    1224       10250 :         num_ilds_to_code = hParamMC->hMetadataPMC.ild_mapping_conf->ild_map_size_lfe;
    1225       10250 :         move16();
    1226             :     }
    1227             : 
    1228             :     /* Downsampling */
    1229      132106 :     test();
    1230      132106 :     IF( ( hParamMC->hMetadataPMC.bAttackPresent == 0 ) && NE_16( hParamMC->hMetadataPMC.param_frame_idx, hParamMC->hMetadataPMC.coding_band_mapping[freq_idx] ) )
    1231             :     {
    1232       64455 :         pop_wmops();
    1233             : 
    1234       64455 :         return;
    1235             :     }
    1236             : 
    1237             :     /* get ICLDs */
    1238      484191 :     FOR( k = 0; k < Ny; ++k )
    1239             :     {
    1240      416540 :         Nrg_fx[k] = Cy_fx[k][k];
    1241      416540 :         move32();
    1242      416540 :         Nrg_e[k] = Cy_e[k][k];
    1243      416540 :         move16();
    1244             :     }
    1245             : 
    1246             :     /* limit ILDs if DMX energy is lower than sum of channel energies */
    1247       67651 :     tot_ener_fx = 0;
    1248       67651 :     move32();
    1249       67651 :     tot_ener_e = 0;
    1250       67651 :     move16();
    1251       67651 :     dmx_ener_fx = 0;
    1252       67651 :     move32();
    1253       67651 :     dmx_ener_e = 0;
    1254       67651 :     move16();
    1255             : 
    1256      484191 :     FOR( k = 0; k < ild_map_size; k++ )
    1257             :     {
    1258      416540 :         test();
    1259      416540 :         IF( NE_16( k, hParamMC->lfe_index ) || hParamMC->hMetadataPMC.lfe_on )
    1260             :         {
    1261      356156 :             tot_ener_fx = BASOP_Util_Add_Mant32Exp( tot_ener_fx, tot_ener_e, Nrg_fx[k], Nrg_e[k], &tot_ener_e );
    1262             :         }
    1263             :     }
    1264             : 
    1265      203820 :     FOR( k = 0; k < nchan_transport; k++ )
    1266             :     {
    1267      136169 :         dmx_ener_fx = BASOP_Util_Add_Mant32Exp( dmx_ener_fx, dmx_ener_e, Cx_fx[k][k], Cx_e[k][k], &dmx_ener_e );
    1268             :     }
    1269             :     /*ener_fac = 10.0f * log10f( ( tot_ener + EPSILON ) / ( dmx_ener + EPSILON ) )*/
    1270       67651 :     IF( tot_ener_fx == 0 )
    1271             :     {
    1272           0 :         tot_ener_fx = 9223; // 1e-15(EPSILON) in Q63
    1273           0 :         tot_ener_e = -32;
    1274           0 :         move32();
    1275           0 :         move16();
    1276             :     }
    1277       67651 :     IF( dmx_ener_fx == 0 )
    1278             :     {
    1279           0 :         dmx_ener_fx = 9223; // 1e-15(EPSILON) in Q63
    1280           0 :         dmx_ener_e = -32;
    1281           0 :         move32();
    1282           0 :         move16();
    1283             :     }
    1284             : 
    1285       67651 :     L_tmp = L_deposit_h( BASOP_Util_Divide3232_Scale( tot_ener_fx, dmx_ener_fx, &tmp_e ) );
    1286       67651 :     tmp_e = add( sub( tot_ener_e, dmx_ener_e ), tmp_e );
    1287       67651 :     ener_fac_fx = BASOP_Util_Log10( L_tmp, tmp_e );     // Q25
    1288             :                                                         /*10 in Q21 = 1342177280*/
    1289       67651 :     ener_fac_fx = Mpy_32_32( 1342177280, ener_fac_fx ); // Q25 + Q27 - Q31 = Q21;
    1290             : 
    1291       67651 :     IF( GT_32( ener_fac_fx, PARAM_MC_ENER_LIMIT_INTRAFRAME_FX_Q21 ) )
    1292             :     {
    1293          17 :         L_tmp = L_sub( ener_fac_fx, PARAM_MC_ENER_LIMIT_INTRAFRAME_FX_Q21 - ONE_IN_Q21 ); // Q21
    1294          17 :         L_tmp = BASOP_Util_Loge( L_tmp, 31 - Q21 );                                       // Q25
    1295             :         /*0.3 in Q31 = 644245094*/
    1296          17 :         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 ) );
    1297             :         /*0.1 in Q31 = 214748365*/
    1298          17 :         L_tmp = Mpy_32_32( L_tmp, 214748365 );
    1299          17 :         L_tmp = BASOP_util_Pow2( Mpy_32_32( L_tmp, LOG2_10_Q29 ), 31 - 19, &tmp_e );
    1300             : 
    1301             :         /*v_multc( Nrg, limit_fac, Nrg, num_ilds_to_code );*/
    1302         118 :         FOR( i = 0; i < num_ilds_to_code; i++ )
    1303             :         {
    1304         101 :             Nrg_fx[i] = Mpy_32_32( Nrg_fx[i], L_tmp );
    1305         101 :             move32();
    1306         101 :             Nrg_e[i] = add( tmp_e, Nrg_e[i] );
    1307         101 :             move16();
    1308         101 :             Nrg_fx[i] = BASOP_Util_Add_Mant32Exp( Nrg_fx[i], Nrg_e[i], 0, 0, &Nrg_e[i] );
    1309         101 :             move32();
    1310             :         }
    1311             :     }
    1312             : 
    1313             :     /* limit ILD jumps in non-tranient frames */
    1314       67651 :     tot_ener_fx = 0;
    1315       67651 :     move32();
    1316       67651 :     dmx_ener_fx = 0;
    1317       67651 :     move32();
    1318             : 
    1319      484191 :     FOR( k = 0; k < ild_map_size; k++ )
    1320             :     {
    1321      416540 :         test();
    1322      416540 :         IF( NE_16( k, hParamMC->lfe_index ) || hParamMC->hMetadataPMC.lfe_on )
    1323             :         {
    1324      356156 :             tot_ener_fx = BASOP_Util_Add_Mant32Exp( tot_ener_fx, tot_ener_e, Nrg_fx[k], Nrg_e[k], &tot_ener_e );
    1325             :         }
    1326             :     }
    1327             : 
    1328      203820 :     FOR( k = 0; k < nchan_transport; k++ )
    1329             :     {
    1330      136169 :         dmx_ener_fx = BASOP_Util_Add_Mant32Exp( dmx_ener_fx, dmx_ener_e, Cx_fx[k][k], Cx_e[k][k], &dmx_ener_e );
    1331             :     }
    1332             :     /* ener_fac = 10.0f * log10f( ( tot_ener + EPSILON ) / ( dmx_ener + EPSILON ) ); */
    1333       67651 :     IF( tot_ener_fx == 0 )
    1334             :     {
    1335           0 :         tot_ener_fx = 9223; // 1e-15(EPSILON) in Q63
    1336           0 :         tot_ener_e = -32;
    1337           0 :         move32();
    1338           0 :         move16();
    1339             :     }
    1340       67651 :     IF( dmx_ener_fx == 0 )
    1341             :     {
    1342           0 :         dmx_ener_fx = 9223; // 1e-15(EPSILON) in Q63
    1343           0 :         dmx_ener_e = -32;
    1344           0 :         move32();
    1345           0 :         move16();
    1346             :     }
    1347             : 
    1348       67651 :     L_tmp = L_deposit_h( BASOP_Util_Divide3232_Scale( tot_ener_fx, dmx_ener_fx, &tmp_e ) );
    1349       67651 :     tmp_e = add( sub( tot_ener_e, dmx_ener_e ), tmp_e );
    1350       67651 :     ener_fac_fx = BASOP_Util_Log10( L_tmp, tmp_e );     // Q25
    1351             :                                                         /*10 in Q21 = 1342177280*/
    1352       67651 :     ener_fac_fx = Mpy_32_32( 1342177280, ener_fac_fx ); // Q25 + Q27 - Q31 = Q21;
    1353       67651 :     delta_fac_fx = L_sub( ener_fac_fx, hParamMC->ener_fac_fx[freq_idx] );
    1354             : 
    1355       67651 :     test();
    1356       67651 :     test();
    1357       67651 :     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 ) )
    1358             :     {
    1359         403 :         L_tmp = L_sub( delta_fac_fx, PARAM_MC_ENER_LIMIT_INTERFRAME_FX_Q21 - ONE_IN_Q21 ); // Q21
    1360         403 :         L_tmp = BASOP_Util_Loge( L_tmp, 31 - Q21 );                                        // Q25
    1361             :                                                                                            /*0.3 in Q31 = 644245094*/
    1362         403 :         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 ) );
    1363             :         /*0.1 in Q31 = 214748365*/
    1364         403 :         L_tmp = Mpy_32_32( L_tmp, 214748365 );
    1365         403 :         L_tmp = BASOP_util_Pow2( Mpy_32_32( L_tmp, LOG2_10_Q29 ), 31 - 19, &tmp_e );
    1366             : 
    1367        2524 :         FOR( i = 0; i < num_ilds_to_code; i++ )
    1368             :         {
    1369        2121 :             Nrg_fx[i] = Mpy_32_32( Nrg_fx[i], L_tmp );
    1370        2121 :             move32();
    1371        2121 :             Nrg_e[i] = add( tmp_e, Nrg_e[i] );
    1372        2121 :             move16();
    1373        2121 :             Nrg_fx[i] = BASOP_Util_Add_Mant32Exp( Nrg_fx[i], Nrg_e[i], 0, 0, &Nrg_e[i] );
    1374        2121 :             move32();
    1375             :         }
    1376             : 
    1377             :         /*10 in Q21 = 1342177280*/
    1378         403 :         ener_fac_fx = L_add( ener_fac_fx, Mpy_32_32( 1342177280, BASOP_Util_Log10( L_tmp, tmp_e ) ) );
    1379             :     }
    1380             : 
    1381       67651 :     hParamMC->ener_fac_fx[freq_idx] = ener_fac_fx; // Q21
    1382       67651 :     move32();
    1383             : 
    1384             :     /* update also combined bands ener_fac when in transient frame */
    1385       67651 :     test();
    1386       67651 :     if ( hParamMC->hMetadataPMC.bAttackPresent && LT_16( add( freq_idx, 1 ), hParamMC->hMetadataPMC.nbands_coded ) )
    1387             :     {
    1388        3124 :         hParamMC->ener_fac_fx[freq_idx + 1] = ener_fac_fx; // Q21
    1389        3124 :         move32();
    1390             :     }
    1391             : 
    1392      421124 :     FOR( k = 0; k < num_ilds_to_code; ++k )
    1393             :     {
    1394      353473 :         Word32 ref_ener_fx = 0;
    1395      353473 :         move32();
    1396      353473 :         Word16 ref_ener_e = 0;
    1397      353473 :         move16();
    1398             :         Word16 ref_channel_cnt;
    1399             :         Word16 ref_channel_idx;
    1400             : 
    1401      779049 :         FOR( ref_channel_cnt = 0; ref_channel_cnt < h_ild_mapping->num_ref_channels[k]; ref_channel_cnt++ )
    1402             :         {
    1403      425576 :             ref_channel_idx = h_ild_mapping->ref_channel_idx[k][ref_channel_cnt];
    1404      425576 :             move16();
    1405      425576 :             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 );
    1406             :         }
    1407      353473 :         ref_ener_fx = Mpy_32_16_1( ref_ener_fx, hParamMC->hMetadataPMC.ild_factors_fx[k] );
    1408      353473 :         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 ) );
    1409      353473 :         tmp_e = add( sub( Nrg_e[h_ild_mapping->ild_index[k]], ref_ener_e ), tmp_e );
    1410             :         /*10 in Q21 = 1342177280*/
    1411      353473 :         ILD_fx[k] = Mpy_32_32( 1342177280, BASOP_Util_Log10( L_tmp, tmp_e ) ); // Q21
    1412      353473 :         move32();
    1413      353473 :         ILD_e[k] = 31 - 21;
    1414      353473 :         move16();
    1415      353473 :         hParamMC->prev_ilds_fx[freq_idx][k] = ILD_fx[k];
    1416      353473 :         move32();
    1417      353473 :         test();
    1418      353473 :         IF( hParamMC->hMetadataPMC.bAttackPresent && LT_16( add( freq_idx, 1 ), hParamMC->hMetadataPMC.nbands_coded ) )
    1419             :         {
    1420       17853 :             hParamMC->prev_ilds_fx[freq_idx + 1][k] = ILD_fx[k];
    1421       17853 :             move32();
    1422             :         }
    1423             :     }
    1424             : 
    1425             : 
    1426             :     /* quantize parameters */
    1427       67651 :     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 );
    1428             : 
    1429             :     /* Save current quantized ICLDs */
    1430       67651 :     Copy( ILD_idx, ILD_idx_out + freq_idx * ild_map_size, num_ilds_to_code );
    1431             : 
    1432       67651 :     pop_wmops();
    1433             : 
    1434       67651 :     return;
    1435             : }
    1436             : 
    1437             : 
    1438             : /*-------------------------------------------------------------------------
    1439             :  * ivas_param_mc_quantize_iccs()
    1440             :  *
    1441             :  * Quantize the ILD parameters
    1442             :  *------------------------------------------------------------------------*/
    1443             : 
    1444      132106 : static void ivas_param_mc_quantize_iccs_fx(
    1445             :     PARAM_MC_ENC_HANDLE hParamMC,                       /* i/o: Parametric MC encoder handle    */
    1446             :     Word32 Cy_fx[MAX_CICP_CHANNELS][MAX_CICP_CHANNELS], /* i  : Covariance matrix of the input  */
    1447             :     Word16 Cy_e[MAX_CICP_CHANNELS][MAX_CICP_CHANNELS],  /* i  : Covariance matrix of the input  */
    1448             :     const Word16 freq_idx,                              /* i  : frequency index being processed */
    1449             :     const Word16 nchan_input,                           /* i  : number of input channels        */
    1450             :     Word16 *ICC_idx_out                                 /* o  : quantizer indices               */
    1451             : )
    1452             : {
    1453             :     Word16 i, k;
    1454             :     Word16 Ny;
    1455             :     Word16 num_iccs_to_code;
    1456             :     Word16 icc_map_size;
    1457             :     Word16 tmp_map[2];
    1458             :     Word16 ICC_idx[PARAM_MC_SZ_ICC_MAP];
    1459             : 
    1460             :     /* Initialization */
    1461             :     Word32 a_fx;
    1462             :     Word32 Nrg_fx[MAX_CICP_CHANNELS];
    1463             :     Word16 Nrg_e;
    1464             :     Word32 ICC_vect_fx[PARAM_MC_SZ_ICC_MAP];
    1465             :     Word16 ICC_vect_e[PARAM_MC_SZ_ICC_MAP];
    1466             :     Word16 ICC_vect_q_fx[PARAM_MC_SZ_ICC_MAP];
    1467             : 
    1468      132106 :     set32_fx( Nrg_fx, 0, MAX_CICP_CHANNELS );
    1469      132106 :     set32_fx( ICC_vect_fx, 0, PARAM_MC_SZ_ICC_MAP );
    1470      132106 :     set16_fx( ICC_vect_q_fx, 0, PARAM_MC_SZ_ICC_MAP );
    1471             : 
    1472             : 
    1473      132106 :     Ny = nchan_input;
    1474      132106 :     move16();
    1475             : 
    1476             :     /* Downsampling */
    1477      132106 :     test();
    1478      132106 :     IF( ( hParamMC->hMetadataPMC.bAttackPresent == 0 ) && NE_16( hParamMC->hMetadataPMC.param_frame_idx, hParamMC->hMetadataPMC.coding_band_mapping[freq_idx] ) )
    1479             :     {
    1480       64455 :         return;
    1481             :     }
    1482             : 
    1483       67651 :     icc_map_size = hParamMC->hMetadataPMC.icc_mapping_conf->icc_map_size_lfe;
    1484       67651 :     move16();
    1485       67651 :     num_iccs_to_code = icc_map_size;
    1486       67651 :     move16();
    1487             : 
    1488       67651 :     if ( GE_16( freq_idx, PARAM_MC_MAX_BAND_LFE ) )
    1489             :     {
    1490       62266 :         num_iccs_to_code = hParamMC->hMetadataPMC.icc_mapping_conf->icc_map_size_wo_lfe;
    1491       62266 :         move16();
    1492             :     }
    1493             : 
    1494             :     /* Get ICC matrix from Cy */
    1495      484191 :     FOR( k = 0; k < Ny; ++k )
    1496             :     {
    1497      416540 :         Nrg_fx[k] = Cy_fx[k][k];
    1498      416540 :         move32();
    1499      416540 :         Nrg_e = Cy_e[k][k];
    1500      416540 :         move16();
    1501      416540 :         a_fx = ISqrt32( L_add( Nrg_fx[k], EPSILLON_FX ), &Nrg_e );
    1502             : 
    1503     1923686 :         FOR( i = k; i < Ny; ++i )
    1504             :         {
    1505     1507146 :             Cy_fx[k][i] = Mpy_32_32( Cy_fx[k][i], a_fx );
    1506     1507146 :             move32();
    1507     1507146 :             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] );
    1508     1507146 :             move32();
    1509             :         }
    1510             : 
    1511     1923686 :         FOR( i = 0; i <= k; i++ )
    1512             :         {
    1513     1507146 :             Cy_fx[i][k] = Mpy_32_32( Cy_fx[i][k], a_fx );
    1514     1507146 :             move32();
    1515     1507146 :             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] );
    1516     1507146 :             move32();
    1517             :         }
    1518             :     }
    1519             : 
    1520             :     /* set ICCs for zero channels to 1 to avoid artifacts in the decoded signal */
    1521      484191 :     FOR( k = 0; k < Ny; ++k )
    1522             :     {
    1523      416540 :         IF( Nrg_fx[k] == 0 )
    1524             :         {
    1525      258920 :             FOR( i = k; i < Ny; ++i )
    1526             :             {
    1527      196632 :                 Cy_fx[k][i] = ONE_IN_Q31;
    1528      196632 :                 move32();
    1529      196632 :                 Cy_e[k][i] = 0;
    1530      196632 :                 move16();
    1531             :             }
    1532             : 
    1533      311440 :             FOR( i = 0; i <= k; ++i )
    1534             :             {
    1535      249152 :                 Cy_fx[i][k] = ONE_IN_Q31;
    1536      249152 :                 move32();
    1537      249152 :                 Cy_e[i][k] = 0;
    1538      249152 :                 move16();
    1539             :             }
    1540             :         }
    1541             :     }
    1542             : 
    1543             :     /* Reduce set of parameters and quantize them */
    1544      354274 :     FOR( k = 0; k < num_iccs_to_code; ++k )
    1545             :     {
    1546      286623 :         tmp_map[0] = hParamMC->hMetadataPMC.icc_mapping_conf->icc_mapping[k][0];
    1547      286623 :         move16();
    1548      286623 :         tmp_map[1] = hParamMC->hMetadataPMC.icc_mapping_conf->icc_mapping[k][1];
    1549      286623 :         move16();
    1550      286623 :         ICC_vect_fx[k] = Cy_fx[tmp_map[0]][tmp_map[1]];
    1551      286623 :         move32();
    1552      286623 :         ICC_vect_e[k] = Cy_e[tmp_map[0]][tmp_map[1]];
    1553      286623 :         move16();
    1554             :     }
    1555             : 
    1556             :     /* Quantization */
    1557       67651 :     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 );
    1558             : 
    1559             :     /* Save current quantized ICCs */
    1560       67651 :     Copy( ICC_idx, ICC_idx_out + freq_idx * icc_map_size, num_iccs_to_code );
    1561             : 
    1562       67651 :     return;
    1563             : }
    1564             : 
    1565             : 
    1566             : /*-------------------------------------------------------------------------
    1567             :  * ivas_param_mc_parameter_quantizer()
    1568             :  *
    1569             :  * Parameter Quantization
    1570             :  *------------------------------------------------------------------------*/
    1571             : 
    1572      135302 : static void ivas_param_mc_parameter_quantizer_fx(
    1573             :     const Word32 *x,            /* i  : input sequence            */
    1574             :     const Word16 *x_e,          /* i  : input sequence            */
    1575             :     const Word16 L,             /* i  : input length              */
    1576             :     const Word16 sz_quantizer,  /* i  : quantizer size            */
    1577             :     const Word16 *quantizer_fx, /* i  : quantizer table   Q_quant */
    1578             :     const Word16 Q_quant,       /* i  : quantizer table           */
    1579             :     Word16 *quant_idx,          /* o  : quant indices             */
    1580             :     Word16 *y_fx                /* o  : output sequence   Q_quant */
    1581             : )
    1582             : {
    1583             :     Word16 idx, i;
    1584             :     Word16 idx_min;
    1585             :     Word32 tmp_min_fx;
    1586             :     Word16 tmp_min_e;
    1587             :     Word32 tmp_val;
    1588             :     Word16 tmp_e;
    1589             : 
    1590      135302 :     set16_fx( y_fx, 0, L );
    1591      135302 :     idx_min = 0;
    1592      135302 :     move16();
    1593             : 
    1594      775398 :     FOR( idx = 0; idx < L; ++idx )
    1595             :     {
    1596      640096 :         tmp_min_fx = 1000;
    1597      640096 :         move32();
    1598      640096 :         tmp_min_e = 31;
    1599      640096 :         move16();
    1600             : 
    1601     8588648 :         FOR( i = 0; i < sz_quantizer; ++i )
    1602             :         {
    1603     7948552 :             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 );
    1604     7948552 :             tmp_val = L_abs( tmp_val );
    1605     7948552 :             IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( tmp_val, tmp_e, tmp_min_fx, tmp_min_e ), -1 ) )
    1606             :             {
    1607     4184865 :                 tmp_min_fx = tmp_val;
    1608     4184865 :                 move32();
    1609     4184865 :                 tmp_min_e = tmp_e;
    1610     4184865 :                 move16();
    1611     4184865 :                 idx_min = i;
    1612     4184865 :                 move16();
    1613             :             }
    1614             :         }
    1615             : 
    1616      640096 :         y_fx[idx] = quantizer_fx[idx_min];
    1617      640096 :         move32();
    1618      640096 :         quant_idx[idx] = idx_min;
    1619      640096 :         move16();
    1620             :     }
    1621             : 
    1622      135302 :     return;
    1623             : }
    1624             : 
    1625             : 
    1626             : /*-------------------------------------------------------------------------
    1627             :  * ivas_param_mc_transient_detection()
    1628             :  *
    1629             :  * Detect if the current frame has a transient
    1630             :  *------------------------------------------------------------------------*/
    1631             : 
    1632       20610 : static void ivas_param_mc_transient_detection_fx(
    1633             :     PARAM_MC_ENC_HANDLE hParamMC, /* i  : Parametric MC encoder handle                                      */
    1634             :     TRAN_DET_HANDLE hTranDet,     /* i  : Transient detector handle from core coder for a transport channel */
    1635             :     Word16 *pbIsAttackPresent,    /* o  : Flag for indicating a found transient                             */
    1636             :     Word16 *pAttackIndex          /* o  : Attack position (0 if no attack)                                  */
    1637             : )
    1638             : {
    1639             :     Word16 i;
    1640             :     Word16 bIsAttackPresent, attackIndex;
    1641             :     Word32 *pSubblockNrg_fx;
    1642             :     Word32 *pAccSubblockNrg_fx;
    1643             :     Word16 attackRatioThreshold_fx;
    1644             : 
    1645       20610 :     push_wmops( "param_mc_trn_det" );
    1646             : 
    1647       20610 :     attackRatioThreshold_fx = hTranDet->transientDetector.attackRatioThreshold;
    1648       20610 :     pSubblockNrg_fx = &hTranDet->subblockEnergies.subblockNrg[hParamMC->transient_detector_delay];       // Q(-1)
    1649       20610 :     pAccSubblockNrg_fx = &hTranDet->subblockEnergies.accSubblockNrg[hParamMC->transient_detector_delay]; // Q(-1)
    1650             : 
    1651       20610 :     bIsAttackPresent = FALSE;
    1652       20610 :     move16();
    1653       20610 :     attackIndex = 16;
    1654       20610 :     move16();
    1655             : 
    1656             :     /* Search for the last attack in the subblocks,
    1657             :      * if we had an attack very late in the last frame,
    1658             :      * make the current frame also a transient one... */
    1659       20610 :     test();
    1660       20610 :     IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg_fx[-1], 32, Mpy_32_16_1( pAccSubblockNrg_fx[-1], attackRatioThreshold_fx ), ( 32 + ATTACKTHRESHOLD_E ) ), 1 ) ||
    1661             :         EQ_16( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg_fx[-2], 32, Mpy_32_16_1( pAccSubblockNrg_fx[-2], attackRatioThreshold_fx ), ( 32 + ATTACKTHRESHOLD_E ) ), 1 ) )
    1662             :     {
    1663          71 :         bIsAttackPresent = TRUE;
    1664          71 :         move16();
    1665          71 :         attackIndex = 0;
    1666          71 :         move16();
    1667             :     }
    1668             : 
    1669      185490 :     FOR( i = 0; i < NSUBBLOCKS; i++ ){
    1670      164880 :         IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg_fx[i], 32, Mpy_32_16_1( pAccSubblockNrg_fx[i], attackRatioThreshold_fx ), ( 32 + ATTACKTHRESHOLD_E ) ), 1 ) ){
    1671         784 :             bIsAttackPresent = TRUE;
    1672         784 :     move16();
    1673         784 :     attackIndex = i;
    1674         784 :     move16();
    1675             : }
    1676             : }
    1677             : 
    1678             : /* avoid post-echos on click sounds (very short transients) due to TNS aliasing */
    1679       20610 : *pAttackIndex = attackIndex;
    1680       20610 : move16();
    1681       20610 : *pbIsAttackPresent = bIsAttackPresent;
    1682       20610 : move16();
    1683             : 
    1684       20610 : pop_wmops();
    1685             : 
    1686       20610 : return;
    1687             : }
    1688             : 
    1689             : /*-------------------------------------------------------------------------
    1690             :  * ivas_param_mc_entropy_encoder()
    1691             :  *
    1692             :  * Write the metadata bitstream
    1693             :  *------------------------------------------------------------------------*/
    1694             : 
    1695       10250 : static void ivas_param_mc_write_bs_fx(
    1696             :     const PARAM_MC_ENC_HANDLE hParamMC,    /* i/o: Parametric MC encoder Handle   */
    1697             :     Word16 *ILD_idx,                       /* i  : ILD quantizer indices sequence */
    1698             :     Word16 *ICC_idx,                       /* i  : ICC quantizer indices sequence */
    1699             :     UWord16 bit_buffer[PARAM_MC_MAX_BITS], /* o  : Output bit buffer              */
    1700             :     Word16 *bit_pos                        /* o  : Number of bits used            */
    1701             : )
    1702             : {
    1703             :     Word16 i, pos;
    1704             :     Word16 nbands;
    1705             :     Word16 band_step;
    1706             :     /*buffers are not getting used in the function*/
    1707             :     // Word16 seq_tmp[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_SZ_ILD_MAP];
    1708             :     // float seq_tmp_uni[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_SZ_ILD_MAP];
    1709             :     Word16 icc_map_size_wo_lfe;
    1710             :     Word16 icc_map_size;
    1711             :     Word16 ild_map_size_wo_lfe;
    1712             :     Word16 ild_map_size;
    1713             : 
    1714       10250 :     push_wmops( "param_mc_prm_enc" );
    1715             : 
    1716             :     /* Init */
    1717             :     /*buffers are not getting used in the function */
    1718             :     // set_zero( seq_tmp_uni, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_SZ_ILD_MAP );
    1719             :     // set_s( seq_tmp, 0, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_SZ_ILD_MAP );
    1720       10250 :     nbands = hParamMC->hMetadataPMC.nbands_in_param_frame[hParamMC->hMetadataPMC.param_frame_idx];
    1721       10250 :     move16();
    1722       10250 :     icc_map_size_wo_lfe = hParamMC->hMetadataPMC.icc_mapping_conf->icc_map_size_wo_lfe;
    1723       10250 :     move16();
    1724       10250 :     icc_map_size = hParamMC->hMetadataPMC.icc_mapping_conf->icc_map_size_lfe;
    1725       10250 :     move16();
    1726       10250 :     ild_map_size_wo_lfe = hParamMC->hMetadataPMC.ild_mapping_conf->ild_map_size_wo_lfe;
    1727       10250 :     move16();
    1728       10250 :     ild_map_size = hParamMC->hMetadataPMC.ild_mapping_conf->ild_map_size_lfe;
    1729       10250 :     move16();
    1730             : 
    1731             :     /*-----------------------------------------------------------------*
    1732             :      * Signaling bits
    1733             :      *-----------------------------------------------------------------*/
    1734             : 
    1735             :     /* reserved bit */
    1736       10250 :     bit_buffer[( *bit_pos )++] = hParamMC->hMetadataPMC.lfe_on;
    1737       10250 :     move16();
    1738             : 
    1739             :     /* write coded band width */
    1740       10250 :     i = hParamMC->hMetadataPMC.coded_bwidth;
    1741       10250 :     move16();
    1742       30750 :     FOR( pos = 0; pos < 2; pos++ )
    1743             :     {
    1744       20500 :         bit_buffer[( *bit_pos )++] = (UWord16) s_and( shr( i, pos ), 1 );
    1745       20500 :         move16();
    1746             :     }
    1747             : 
    1748             :     /* write param frame indicator */
    1749       10250 :     bit_buffer[( *bit_pos )++] = hParamMC->hMetadataPMC.param_frame_idx;
    1750       10250 :     move16();
    1751             : 
    1752             :     /* write transient frame indicator */
    1753       10250 :     bit_buffer[( *bit_pos )++] = hParamMC->hMetadataPMC.bAttackPresent;
    1754       10250 :     move16();
    1755             : 
    1756       10250 :     band_step = 1;
    1757       10250 :     move16();
    1758       10250 :     IF( hParamMC->hMetadataPMC.bAttackPresent )
    1759             :     {
    1760         490 :         band_step = PARAM_MC_TRANSIENT_BAND_STEP;
    1761         490 :         move16();
    1762        1960 :         FOR( pos = 2; pos >= 0; --pos )
    1763             :         {
    1764        1470 :             bit_buffer[( *bit_pos )++] = (UWord16) s_and( shr( hParamMC->hMetadataPMC.attackIndex, pos ), 1 );
    1765        1470 :             move16();
    1766             :         }
    1767         490 :         IF( ( hParamMC->hMetadataPMC.nbands_coded % band_step ) )
    1768             :         {
    1769          53 :             nbands = add( idiv1616( hParamMC->hMetadataPMC.nbands_coded, band_step ), 1 );
    1770             :         }
    1771             :         ELSE
    1772             :         {
    1773         437 :             nbands = add( idiv1616( hParamMC->hMetadataPMC.nbands_coded, band_step ), 0 );
    1774             :         }
    1775             :     }
    1776             : 
    1777       10250 :     ivas_param_mc_encode_parameter_fx( ICC_idx, &hParamMC->hMetadataPMC, &hParamMC->hMetadataPMC.icc_coding,
    1778             :                                        nbands, band_step, icc_map_size_wo_lfe, icc_map_size, bit_buffer, bit_pos );
    1779             : 
    1780       10250 :     ivas_param_mc_encode_parameter_fx( ILD_idx, &hParamMC->hMetadataPMC, &hParamMC->hMetadataPMC.ild_coding,
    1781             :                                        nbands, band_step, ild_map_size_wo_lfe, ild_map_size, bit_buffer, bit_pos );
    1782       10250 :     pop_wmops();
    1783             : 
    1784       10250 :     return;
    1785             : }
    1786             : 
    1787             : 
    1788             : /*-------------------------------------------------------------------------
    1789             :  * ivas_param_mc_encode_parameter_fx()
    1790             :  *
    1791             :  * (entropy) encode a sequence of parameter indices
    1792             :  *------------------------------------------------------------------------*/
    1793             : 
    1794       20500 : static void ivas_param_mc_encode_parameter_fx(
    1795             :     Word16 *quant_idx,                                          /* i  : indices sequence to encode              */
    1796             :     HANDLE_IVAS_PARAM_MC_METADATA hMetadataPMC,                 /* i  : Parametric MC metadata handle           */
    1797             :     HANDLE_PARAM_MC_PARAMETER_CODING_INFO hParameterCodingInfo, /* i  : parameter quantization and coding info  */
    1798             :     const Word16 nbands,                                        /* i  : number of parameter bands to encode     */
    1799             :     const Word16 band_step,                                     /* i  : parameter band step                     */
    1800             :     const Word16 map_size_wo_lfe,                               /* i  : number of parameters per band (w/o LFE) */
    1801             :     const Word16 map_size,                                      /* i  : number of parameters per band           */
    1802             :     UWord16 bit_buffer[PARAM_MC_MAX_BITS],                      /* o  : Output bit buffer                       */
    1803             :     Word16 *bit_pos                                             /* o  : Number of bits used                     */
    1804             : )
    1805             : {
    1806             :     Word16 sz_seq;
    1807             :     Word16 idx_prev;
    1808             :     Word16 idx_offset;
    1809             :     Word16 bit_cnt_uni;
    1810             :     Word16 bit_cnt_range;
    1811             :     Word16 bit_cnt_range_diff;
    1812             :     Word16 bit_cnt_range_min;
    1813             :     Word16 bit_pos_tmp;
    1814             :     Word16 i, j;
    1815             :     Word16 idx;
    1816             :     Word16 seq_delta[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE];
    1817             :     Word16 seq[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE];
    1818             :     UWord16 tmp_bit_buffer[PARAM_MC_MAX_BITS];
    1819             :     UWord16 tmp_bit_buffer_diff[PARAM_MC_MAX_BITS];
    1820             : 
    1821             :     /* Inits */
    1822       20500 :     sz_seq = i_mult( nbands, ( map_size_wo_lfe ) );
    1823             : 
    1824             :     /* Computing Delta Sequence */
    1825       20500 :     idx_prev = sub( add( shr( hParameterCodingInfo->quantizer_size, 1 ), hParameterCodingInfo->quantizer_size % 2 ), 1 );
    1826       20500 :     idx_offset = sub( hParameterCodingInfo->quantizer_size, 1 );
    1827             : 
    1828      115680 :     FOR( j = 0; j < map_size_wo_lfe; ++j )
    1829             :     {
    1830       95180 :         Word16 coding_band = 0;
    1831       95180 :         move16();
    1832             : 
    1833     1321237 :         FOR( i = 0; i < hMetadataPMC->nbands_coded; i += band_step )
    1834             :         {
    1835     1226057 :             test();
    1836     1226057 :             IF( hMetadataPMC->bAttackPresent || EQ_16( hMetadataPMC->param_frame_idx, hMetadataPMC->coding_band_mapping[i] ) )
    1837             :             {
    1838      629260 :                 idx = quant_idx[i * map_size + j];
    1839      629260 :                 move16();
    1840      629260 :                 seq[coding_band + j * nbands] = idx;
    1841      629260 :                 move16();
    1842      629260 :                 seq_delta[coding_band + j * nbands] = add( sub( idx, idx_prev ), idx_offset );
    1843      629260 :                 move16();
    1844      629260 :                 idx_prev = idx;
    1845      629260 :                 move16();
    1846      629260 :                 coding_band = add( coding_band, 1 );
    1847             :             }
    1848             :         }
    1849             :     }
    1850             : 
    1851             :     /* LFE */
    1852       20500 :     IF( hMetadataPMC->lfe_on )
    1853             :     {
    1854        4276 :         FOR( i = 0; i < PARAM_MC_MAX_BAND_LFE; i += band_step )
    1855             :         {
    1856        2138 :             test();
    1857        2138 :             IF( hMetadataPMC->bAttackPresent || EQ_16( hMetadataPMC->param_frame_idx, hMetadataPMC->coding_band_mapping[i] ) )
    1858             :             {
    1859             :                 /* LFE ICC/ILDs are always the last ones in coding band 0 */
    1860             :                 Word16 n_lfe_idx, k;
    1861        1172 :                 n_lfe_idx = sub( map_size, map_size_wo_lfe );
    1862        2410 :                 FOR( k = 0; k < n_lfe_idx; k++ )
    1863             :                 {
    1864        1238 :                     idx = quant_idx[( i + 1 ) * map_size - n_lfe_idx + k];
    1865        1238 :                     move16();
    1866        1238 :                     seq[sz_seq] = idx;
    1867        1238 :                     move16();
    1868        1238 :                     seq_delta[sz_seq] = add( sub( idx, idx_prev ), idx_offset );
    1869        1238 :                     move16();
    1870        1238 :                     idx_prev = idx;
    1871        1238 :                     move16();
    1872        1238 :                     sz_seq = add( sz_seq, 1 );
    1873             :                 }
    1874             :             }
    1875             :         }
    1876             :     }
    1877             : 
    1878             : 
    1879       20500 :     bit_cnt_uni = sub( i_mult( sz_seq, hParameterCodingInfo->uni_bits ), 1 ); /* -1 for the additional diff/direct signaling bit for the range encoder*/
    1880             : 
    1881             :     /* code the direct index sequence */
    1882       20500 :     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 );
    1883             : 
    1884             :     /* Coding the delta index sequence */
    1885       20500 :     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 );
    1886             : 
    1887       20500 :     bit_cnt_range_min = s_min( bit_cnt_range, bit_cnt_range_diff );
    1888             : 
    1889             :     /* uniform fallback */
    1890       20500 :     IF( GT_16( bit_cnt_range_min, bit_cnt_uni ) )
    1891             :     {
    1892             :         /* Uniform coding is used */
    1893         478 :         bit_buffer[( *bit_pos )++] = 0;
    1894         478 :         move16();
    1895         478 :         bit_pos_tmp = 0;
    1896         478 :         move16();
    1897             : 
    1898       12904 :         FOR( i = 0; i < sz_seq; ++i )
    1899             :         {
    1900       12426 :             ivas_param_mc_dec2bin_fx( seq[i], hParameterCodingInfo->uni_bits, &bit_buffer[*( bit_pos ) + bit_pos_tmp] );
    1901       12426 :             bit_pos_tmp = add( bit_pos_tmp, hParameterCodingInfo->uni_bits );
    1902             :         }
    1903         478 :         *bit_pos = add( *bit_pos, bit_pos_tmp );
    1904             :     }
    1905             :     ELSE
    1906             :     {
    1907             :         /* Range Coding is used */
    1908       20022 :         bit_buffer[( *bit_pos )++] = 1;
    1909       20022 :         move16();
    1910       20022 :         IF( bit_cnt_range_diff < bit_cnt_range )
    1911             :         {
    1912       19757 :             bit_buffer[( *bit_pos )++] = 1;
    1913       19757 :             move16();
    1914     1356014 :             FOR( i = 0; i < bit_cnt_range_diff; i++ )
    1915             :             {
    1916     1336257 :                 bit_buffer[( *bit_pos )++] = tmp_bit_buffer_diff[i];
    1917     1336257 :                 move16();
    1918             :             }
    1919             :         }
    1920             :         ELSE
    1921             :         {
    1922         265 :             bit_buffer[( *bit_pos )++] = 0;
    1923         265 :             move16();
    1924       15687 :             FOR( i = 0; i < bit_cnt_range; i++ )
    1925             :             {
    1926       15422 :                 bit_buffer[( *bit_pos )++] = tmp_bit_buffer[i];
    1927       15422 :                 move16();
    1928             :             }
    1929             :         }
    1930             :     }
    1931             : 
    1932       20500 :     return;
    1933             : }
    1934             : 
    1935             : 
    1936             : /*-------------------------------------------------------------------------
    1937             :  * ivas_param_mc_dec2bin()
    1938             :  *
    1939             :  * Decimal to binary routine
    1940             :  *------------------------------------------------------------------------*/
    1941             : 
    1942       12426 : static void ivas_param_mc_dec2bin_fx(
    1943             :     const Word16 val,                 /* i  : value to encode                       */
    1944             :     const Word16 N,                   /* i  : number of bits for encoding the value */
    1945             :     UWord16 bits[PARAM_MC_MAX_BITS] ) /* o  : encoded bits buffer                   */
    1946             : {
    1947             :     Word16 idx;
    1948             : 
    1949       12426 :     idx = 0;
    1950       12426 :     move16();
    1951             :     /* convert value to bitstream, MSB first */
    1952       49704 :     FOR( idx = 0; idx < N; idx++ )
    1953             :     {
    1954       37278 :         bits[idx] = (UWord16) s_and( shr( val, sub( sub( N, 1 ), idx ) ), 1 );
    1955       37278 :         move16();
    1956             :     }
    1957             : 
    1958       12426 :     return;
    1959             : }
    1960             : 
    1961             : 
    1962             : /*-------------------------------------------------------------------*
    1963             :  * ivas_param_mc_range_encoder()
    1964             :  *
    1965             :  * Parametric MC Range encoder
    1966             :  *-------------------------------------------------------------------*/
    1967             : 
    1968       41000 : static void ivas_param_mc_range_encoder_fx(
    1969             :     const Word16 *seq_in,     /* i  : input sequence                     */
    1970             :     const Word16 num_symbols, /* i  : Number of symbole to encode        */
    1971             :     const UWord16 *cum_freq,  /* i  : cumulated frequencies              */
    1972             :     const UWord16 *sym_freq,  /* i  : symbol frequencies                 */
    1973             :     const UWord16 tot_shift,  /* i  : max cumulative freq as power of 2  */
    1974             :     const Word16 max_nb_bits, /* i  : Maximum number of bits allowed     */
    1975             :     UWord16 *bit_buffer,      /* o  : output bit buffer                  */
    1976             :     Word16 *bit_pos           /* o  : number of bits used                */
    1977             : )
    1978             : {
    1979             :     RangeUniEncState rc_st_enc;
    1980             :     Word16 rc_tot_bits; /* No. of bits returned by range coder */
    1981             :     Word16 i;
    1982             :     UWord8 k, byte;
    1983             :     UWord16 *bits;
    1984             : 
    1985             :     /* Initialize range encoder */
    1986       41000 :     rc_uni_enc_init_fx( &rc_st_enc );
    1987             : 
    1988             :     /* Main loop over the length of the sequence */
    1989     1242380 :     FOR( i = 0; i < num_symbols; ++i )
    1990             :     {
    1991     1211481 :         rc_uni_enc_encode_symbol_fastS_fx( &rc_st_enc, (UWord16) seq_in[i], cum_freq, sym_freq, tot_shift );
    1992             : 
    1993     1211481 :         IF( GT_16( rc_uni_enc_virtual_finish_fx( &rc_st_enc ), max_nb_bits ) )
    1994             :         {
    1995             :             /* we alread have exceeded the maximum number of bits allowed, i.e. the uniform fallback */
    1996       10101 :             *bit_pos = MAX_BITS_PER_FRAME;
    1997       10101 :             return;
    1998             :         }
    1999             :     }
    2000             : 
    2001             :     /* Finish range encoder */
    2002       30899 :     rc_tot_bits = rc_uni_enc_finish_fx( &rc_st_enc ); /* No. of bits consumed by range coder */
    2003             : 
    2004             :     /* Push range coded bits from byte_buffer to bitstream */
    2005             : 
    2006             :     /* 1) Push all complete bytes, one byte at a time */
    2007      335966 :     FOR( i = 0; i < ( rc_tot_bits >> 3 ); ++i )
    2008             :     {
    2009             :         /* use rc_st_enc.byte_buffer */
    2010      305067 :         bits = &bit_buffer[i << 3];
    2011             : 
    2012      305067 :         byte = rc_st_enc.byte_buffer[i];
    2013      305067 :         move16();
    2014             : 
    2015      305067 :         bits[0] = (UWord16) s_and( shr( (Word16) byte, 7 ), 1 );
    2016      305067 :         move16();
    2017      305067 :         bits[1] = (UWord16) s_and( shr( (Word16) byte, 6 ), 1 );
    2018      305067 :         move16();
    2019      305067 :         bits[2] = (UWord16) s_and( shr( (Word16) byte, 5 ), 1 );
    2020      305067 :         move16();
    2021      305067 :         bits[3] = (UWord16) s_and( shr( (Word16) byte, 4 ), 1 );
    2022      305067 :         move16();
    2023      305067 :         bits[4] = (UWord16) s_and( shr( (Word16) byte, 3 ), 1 );
    2024      305067 :         move16();
    2025      305067 :         bits[5] = (UWord16) s_and( shr( (Word16) byte, 2 ), 1 );
    2026      305067 :         move16();
    2027      305067 :         bits[6] = (UWord16) s_and( shr( (Word16) byte, 1 ), 1 );
    2028      305067 :         move16();
    2029      305067 :         bits[7] = (UWord16) s_and( (Word16) byte, 1 );
    2030      305067 :         move16();
    2031             :     }
    2032             : 
    2033             :     /* 2) Push remaining bits */
    2034       30899 :     IF( s_and( rc_tot_bits, 7 ) != 0 )
    2035             :     {
    2036       27184 :         UWord8 rem_bits = (UWord8) s_and( rc_tot_bits, 7 );
    2037             : 
    2038       27184 :         bits = &bit_buffer[( i << 3 )];
    2039       27184 :         byte = rc_st_enc.byte_buffer[i];
    2040       27184 :         move16();
    2041             : 
    2042      134734 :         FOR( k = 0; k < rem_bits; k++ )
    2043             :         {
    2044      107550 :             bits[k] = (UWord16) s_and( shr( (Word16) byte, sub( 7, k ) ), 1 );
    2045      107550 :             move16();
    2046             :         }
    2047             :     }
    2048             : 
    2049             :     /* Update output number of bits */
    2050       30899 :     *bit_pos = rc_tot_bits;
    2051       30899 :     move16();
    2052             : 
    2053       30899 :     return;
    2054             : }

Generated by: LCOV version 1.14