LCOV - code coverage report
Current view: top level - lib_enc - ivas_mcmasa_enc_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 1114 1185 94.0 %
Date: 2025-05-03 01:55:50 Functions: 12 12 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : #include <assert.h>
      34             : #include <math.h>
      35             : #include <stdlib.h>
      36             : #include <stdio.h>
      37             : #include "ivas_cnst.h"
      38             : #include "ivas_prot_fx.h"
      39             : #include "options.h"
      40             : #include "prot_fx.h"
      41             : #include "ivas_rom_com.h"
      42             : #include "ivas_rom_com_fx.h"
      43             : #include "ivas_rom_enc.h"
      44             : #include "wmc_auto.h"
      45             : #include "ivas_prot_fx.h"
      46             : 
      47             : 
      48             : /*-------------------------------------------------------------------------
      49             :  * Local constants
      50             :  *------------------------------------------------------------------------*/
      51             : 
      52             : #define NEAR_HORIZONTAL_PLANE_ELEVATION_FX 73400320 /*Q22*/
      53             : #define VERTICAL_ENERGY_RATIO_OFFSET_FX    4915     /*Q15*/
      54             : 
      55             : /*-------------------------------------------------------------------------
      56             :  * Local function prototypes
      57             :  *------------------------------------------------------------------------*/
      58             : 
      59             : /* Structure for covariance matrix */
      60             : typedef struct
      61             : {
      62             :     Word32 xr_fx[MCMASA_MAX_ANA_CHANS][MCMASA_MAX_ANA_CHANS];
      63             :     Word32 xi_fx[MCMASA_MAX_ANA_CHANS][MCMASA_MAX_ANA_CHANS];
      64             :     Word16 xr_e[MCMASA_MAX_ANA_CHANS][MCMASA_MAX_ANA_CHANS]; /*Stores exponent for xr_fx*/
      65             :     Word16 xi_e[MCMASA_MAX_ANA_CHANS][MCMASA_MAX_ANA_CHANS]; /*Stores exponent for xi_fx*/
      66             : } CovarianceMatrix;
      67             : 
      68             : static void ivas_mcmasa_dmx_fx(
      69             :     MCMASA_ENC_HANDLE hMcMasa,
      70             :     Word32 *data_fx[],
      71             :     Word16 data_e,
      72             :     const Word16 input_frame,
      73             :     const Word16 nchan_transport,
      74             :     const Word16 nchan_inp );
      75             : 
      76             : static void compute_cov_mtx_fx(
      77             :     Word32 sr[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i  : Input matrix, real, s[ch][freq]                         */
      78             :     Word32 si[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i  : Input matrix, imag, s[ch][freq]                         */
      79             :     const Word16 freq,                                      /* i  : Freq to process                                         */
      80             :     const Word16 N,                                         /* i  : Number of channels                                      */
      81             :     CovarianceMatrix *COVls,                                /* o  : Output matrix, contains upper part of cov mtx           */
      82             :     Word16 inp_exp                                          /*Stores exponent for temp*/
      83             : );
      84             : static void computeIntensityVector_enc_fx( const Word16 *band_grouping, Word32 Cldfb_RealBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX], Word32 Cldfb_ImagBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX], const Word16 enc_param_start_band, const Word16 num_frequency_bands, Word32 intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] );
      85             : 
      86             : static void computeVerticalDiffuseness_fx(
      87             :     Word32 **buffer_intensity,     /* i  : Intensity vectors           */
      88             :     const Word32 *buffer_energy,   /* i  : Energy                      */
      89             :     const Word16 averaging_length, /* i  : Averaging length            */
      90             :     const Word16 num_freq_bands,   /* i  : Number of frequency bands   */
      91             :     Word32 *diffuseness,           /* o  : Estimated diffuseness       */
      92             :     Word16 *buffer_intensity_q,
      93             :     Word16 *buffer_energy_q );
      94             : 
      95             : static void computeEvenLayout_fx(
      96             :     const Word32 *ls_azimuth,
      97             :     Word32 *ls_azimuth_even,
      98             :     const Word16 numChannels );
      99             : 
     100             : static void computeLfeEnergy_fx( MCMASA_ENC_HANDLE hMcMasa, Word32 *data_fx[], const Word16 input_frame, Word16 q_fac );
     101             : 
     102             : 
     103             : /*--------------------------------------------------------------------------*
     104             :  * ivas_mcmasa_enc_open()
     105             :  *
     106             :  *
     107             :  *--------------------------------------------------------------------------*/
     108             : 
     109         277 : ivas_error ivas_mcmasa_enc_open_fx(
     110             :     Encoder_Struct *st_ivas /* i/o: IVAS encoder handle          */
     111             : )
     112             : {
     113             :     Word16 i, j;
     114             :     Word16 tmp_f;
     115             :     MCMASA_ENC_HANDLE hMcMasa;
     116             :     MASA_ENCODER_HANDLE hMasa;
     117             :     Word32 ls_azimuth[MCMASA_MAX_ANA_CHANS];
     118             :     Word32 ls_elevation[MCMASA_MAX_ANA_CHANS];
     119             :     Word32 ls_azimuth_even[MCMASA_MAX_ANA_CHANS];
     120             :     Word16 numAnalysisChannels;
     121             :     Word32 left_min, right_min, azi_diff;
     122             :     const Word16 *band_mapping;
     123             :     Word16 maxBin, input_frame;
     124             :     Word16 nchan_inp;
     125             :     Word32 input_Fs;
     126             :     IVAS_FB_CFG *fb_cfg, *fb_cfgLfe;
     127             :     ivas_error error;
     128             : 
     129         277 :     error = IVAS_ERR_OK;
     130         277 :     move32();
     131             : 
     132         277 :     assert( st_ivas->hMasa != NULL && "MASA encoder handle is not present" );
     133         277 :     hMasa = st_ivas->hMasa;
     134             : 
     135         277 :     IF( ( hMcMasa = (MCMASA_ENC_HANDLE) malloc( sizeof( MCMASA_ENC_DATA ) ) ) == NULL )
     136             :     {
     137           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
     138             :     }
     139             : 
     140         277 :     nchan_inp = st_ivas->hEncoderConfig->nchan_inp;
     141         277 :     move16();
     142         277 :     input_Fs = st_ivas->hEncoderConfig->input_Fs;
     143         277 :     move32();
     144             : 
     145             :     /* Determine if to separate some channels from the analysis */
     146         277 :     ivas_mcmasa_set_separate_channel_mode_fx( &( hMcMasa->separateChannelEnabled ), &( hMcMasa->separateChannelIndex ), st_ivas->hEncoderConfig->ivas_total_brate );
     147             : 
     148         277 :     numAnalysisChannels = sub( nchan_inp, 1 );
     149         277 :     IF( hMcMasa->separateChannelEnabled )
     150             :     {
     151          28 :         numAnalysisChannels = sub( nchan_inp, 2 );
     152             :     }
     153             : 
     154             :     /* With McMASA, we config MASA encoder only in init as we know the input and there are no frame-by-frame changes currently. */
     155         277 :     IF( NE_32( ( error = ivas_masa_enc_config_fx( st_ivas ) ), IVAS_ERR_OK ) )
     156             :     {
     157           0 :         return error;
     158             :     }
     159             : 
     160             : 
     161             :     /* Determine the number of bands */
     162         277 :     hMcMasa->nbands = st_ivas->hMasa->config.numCodingBands;
     163         277 :     move16();
     164         277 :     hMcMasa->nCodingBands = st_ivas->hMasa->config.numCodingBands;
     165         277 :     move16();
     166             : 
     167             :     /* Determine band grouping */
     168         277 :     IF( EQ_16( hMcMasa->nbands, 24 ) )
     169             :     {
     170           0 :         FOR( i = 0; i < hMcMasa->nbands + 1; i++ )
     171             :         {
     172           0 :             hMcMasa->band_grouping[i] = i_mult( MASA_band_grouping_24[i], CLDFB_TO_MDFT_FAC );
     173           0 :             move16();
     174             :         }
     175             :     }
     176             :     ELSE
     177             :     {
     178         277 :         band_mapping = hMasa->data.band_mapping;
     179        1939 :         FOR( i = 0; i < hMcMasa->nbands + 1; i++ )
     180             :         {
     181        1662 :             hMcMasa->band_grouping[i] = i_mult( MASA_band_grouping_24[band_mapping[i]], CLDFB_TO_MDFT_FAC );
     182        1662 :             move16();
     183             :         }
     184             :     }
     185             : 
     186         277 :     maxBin = extract_l( W_extract_h( W_add( W_mult_32_32( input_Fs, INV_CLDFB_BANDWIDTH_MDFT_FAC_Q31 ), ONE_IN_Q31 /*0.5f in Q32*/ ) ) ); // Q0
     187             : 
     188        1385 :     FOR( i = 1; i < hMcMasa->nbands + 1; i++ )
     189             :     {
     190        1385 :         IF( GE_32( hMcMasa->band_grouping[i], maxBin ) )
     191             :         {
     192         277 :             hMcMasa->band_grouping[i] = maxBin; // Q0
     193         277 :             move16();
     194         277 :             hMcMasa->nbands = i;
     195         277 :             move16();
     196         277 :             BREAK;
     197             :         }
     198             :     }
     199             : 
     200             :     /* initialize delay compensation */
     201         277 :     hMcMasa->num_samples_delay_comp = NS2SA_FX2( input_Fs, DELAY_DIRAC_ENC_CMP_NS );
     202         277 :     move16();
     203             : #ifdef DISABLE_DIRAC_DELAY_COMP
     204             :     hMcMasa->num_samples_delay_comp = 0; /* disable delay compensation by setting to 0 */
     205             : #endif
     206         277 :     tmp_f = idiv1616( hMcMasa->num_samples_delay_comp, ( NS2SA_FX2( input_Fs, DIRAC_SLOT_ENC_NS ) ) );
     207         277 :     hMcMasa->num_slots_delay_comp = tmp_f;
     208         277 :     move16();
     209             : 
     210         277 :     IF( GT_16( hMcMasa->num_samples_delay_comp, ( NS2SA_FX2( input_Fs, DIRAC_SLOT_ENC_NS ) ) ) )
     211             :     {
     212         277 :         hMcMasa->num_slots_delay_comp = add( hMcMasa->num_slots_delay_comp, 1 );
     213         277 :         move16();
     214         277 :         hMcMasa->offset_comp = negate( hMcMasa->num_samples_delay_comp );
     215         277 :         move16();
     216         277 :         hMcMasa->num_samples_delay_comp = i_mult( hMcMasa->num_slots_delay_comp, NS2SA_FX2( input_Fs, DIRAC_SLOT_ENC_NS ) );
     217         277 :         move16();
     218         277 :         hMcMasa->offset_comp = add( hMcMasa->offset_comp, hMcMasa->num_samples_delay_comp );
     219         277 :         move16();
     220             :     }
     221             :     ELSE
     222             :     {
     223           0 :         hMcMasa->offset_comp = 0;
     224           0 :         move16();
     225             :     }
     226             : 
     227             :     /* set FB config. */
     228         277 :     IF( NE_32( ( error = ivas_fb_set_cfg( &fb_cfg, MASA_FORMAT, numAnalysisChannels, 0, 0, input_Fs, 0 ) ), IVAS_ERR_OK ) )
     229             :     {
     230           0 :         return error;
     231             :     }
     232             : 
     233             :     /* Allocate and initialize FB mixer handle */
     234         277 :     IF( NE_32( ( error = ivas_FB_mixer_open_fx( &( hMcMasa->hFbMixer ), input_Fs, fb_cfg, 0 ) ), IVAS_ERR_OK ) )
     235             :     {
     236           0 :         return error;
     237             :     }
     238             : 
     239         277 :     IF( hMcMasa->separateChannelEnabled )
     240             :     {
     241             :         /* TD Energy calculation with LP */
     242          28 :         IF( ( hMcMasa->delay_buffer_lfe[0] = (Word32 *) malloc( NS2SA_FX2( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) * sizeof( Word32 ) ) ) == NULL )
     243             :         {
     244           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
     245             :         }
     246          28 :         set_zero_fx( hMcMasa->delay_buffer_lfe[0], NS2SA_FX2( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) );
     247             : 
     248          28 :         IF( ( hMcMasa->delay_buffer_lfe[1] = (Word32 *) malloc( NS2SA_FX2( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) * sizeof( Word32 ) ) ) == NULL )
     249             :         {
     250           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
     251             :         }
     252          28 :         set_zero_fx( hMcMasa->delay_buffer_lfe[1], NS2SA_FX2( input_Fs, DELAY_DIRAC_ENC_CMP_NS + DIRAC_SLOT_ENC_NS ) );
     253          28 :         hMcMasa->hFbMixerLfe = NULL;
     254             :     }
     255             :     ELSE
     256             :     {
     257             :         /* Allocate and initialize FB mixer handle for LFE channel */
     258         249 :         IF( NE_32( ( error = ivas_fb_set_cfg( &fb_cfgLfe, MASA_FORMAT, 1, 0, 0, input_Fs, 0 ) ), IVAS_ERR_OK ) )
     259             :         {
     260           0 :             return error;
     261             :         }
     262             : 
     263         249 :         IF( NE_32( ( error = ivas_FB_mixer_open_fx( &( hMcMasa->hFbMixerLfe ), input_Fs, fb_cfgLfe, 0 ) ), IVAS_ERR_OK ) )
     264             :         {
     265           0 :             return error;
     266             :         }
     267             : 
     268         249 :         hMcMasa->delay_buffer_lfe[0] = NULL;
     269         249 :         hMcMasa->delay_buffer_lfe[1] = NULL;
     270             :     }
     271             : 
     272         277 :     IF( hMcMasa->separateChannelEnabled )
     273             :     {
     274             :         Word16 bufferSize;
     275             : 
     276             :         /* Ring buffer for the filterbank of the LFE analysis.
     277             :          * The filterbank is using moving average lowpass filter with the crossover of 120 Hz. */
     278          28 :         bufferSize = (Word16) ( ( input_Fs / FRAMES_PER_SEC ) / MAX_PARAM_SPATIAL_SUBFRAMES );
     279          84 :         FOR( i = 0; i < 2; i++ )
     280             :         {
     281          56 :             IF( ( hMcMasa->lfeAnaRingBuffer[i] = (Word32 *) malloc( bufferSize * sizeof( float ) ) ) == NULL )
     282             :             {
     283           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
     284             :             }
     285          56 :             set_zero_fx( hMcMasa->lfeAnaRingBuffer[i], bufferSize );
     286          56 :             hMcMasa->lowpassSum[i] = 0;
     287          56 :             move32();
     288             :         }
     289          28 :         hMcMasa->ringBufferPointer = 0;
     290          28 :         move16();
     291          28 :         hMcMasa->ringBufferSize = bufferSize;
     292          28 :         move16();
     293             :     }
     294             : 
     295             : 
     296             :     /*dirac_slot_ns = DIRAC_SLOT_ENC_NS;*/
     297             : 
     298             :     /* intensity 3-dim */
     299        1108 :     FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
     300             :     {
     301         831 :         IF( ( hMcMasa->direction_vector_m_fx[i] = (Word32 **) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( Word32 * ) ) ) == NULL )
     302             :         {
     303           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
     304             :         }
     305             : 
     306        4155 :         FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
     307             :         {
     308        3324 :             IF( ( hMcMasa->direction_vector_m_fx[i][j] = (Word32 *) malloc( hMcMasa->nbands * sizeof( Word32 ) ) ) == NULL )
     309             :             {
     310           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
     311             :             }
     312             :         }
     313             :     }
     314             : 
     315        1108 :     FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
     316             :     {
     317         831 :         IF( ( hMcMasa->direction_vector_e[i] = (Word16 **) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( Word16 * ) ) ) == NULL )
     318             :         {
     319           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
     320             :         }
     321             : 
     322        4155 :         FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
     323             :         {
     324        3324 :             IF( ( hMcMasa->direction_vector_e[i][j] = (Word16 *) malloc( hMcMasa->nbands * sizeof( Word16 ) ) ) == NULL )
     325             :             {
     326           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
     327             :             }
     328             :         }
     329             :     }
     330             : 
     331         277 :     hMcMasa->no_col_avg_diff = (Word8) ( DIRAC_NO_COL_AVG_DIFF_NS / DIRAC_SLOT_ENC_NS ); /* dirac_slot_ns = DIRAC_SLOT_ENC_NS */
     332         277 :     move16();
     333             : 
     334        1108 :     FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
     335             :     {
     336         831 :         IF( ( hMcMasa->buffer_intensity_real_fx[i] = (Word32 **) malloc( hMcMasa->no_col_avg_diff * sizeof( Word32 * ) ) ) == NULL )
     337             :         {
     338           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
     339             :         }
     340             : 
     341        7479 :         FOR( j = 0; j < hMcMasa->no_col_avg_diff; j++ )
     342             :         {
     343        6648 :             IF( ( hMcMasa->buffer_intensity_real_fx[i][j] = (Word32 *) malloc( hMcMasa->nbands * sizeof( Word32 ) ) ) == NULL )
     344             :             {
     345           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
     346             :             }
     347        6648 :             set_zero_fx( hMcMasa->buffer_intensity_real_fx[i][j], hMcMasa->nbands ); // hMcMasa->buffer_intensity_real_q
     348             :         }
     349             :     }
     350         277 :     set16_fx( hMcMasa->buffer_intensity_real_q, 31, DIRAC_NO_COL_AVG_DIFF );
     351             : 
     352         277 :     IF( ( hMcMasa->buffer_intensity_real_vert_fx = (Word32 **) malloc( hMcMasa->no_col_avg_diff * sizeof( Word32 * ) ) ) == NULL )
     353             :     {
     354           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
     355             :     }
     356             : 
     357        2493 :     FOR( j = 0; j < hMcMasa->no_col_avg_diff; j++ )
     358             :     {
     359        2216 :         IF( ( hMcMasa->buffer_intensity_real_vert_fx[j] = (Word32 *) malloc( hMcMasa->nbands * sizeof( Word32 ) ) ) == NULL ) // hMcMasa->buffer_intensity_real_vert_q
     360             :         {
     361           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
     362             :         }
     363        2216 :         set_zero_fx( hMcMasa->buffer_intensity_real_vert_fx[j], hMcMasa->nbands );
     364             :     }
     365             : 
     366         277 :     IF( ( hMcMasa->buffer_energy_fx = (Word32 *) malloc( hMcMasa->nbands * hMcMasa->no_col_avg_diff * sizeof( Word32 ) ) ) == NULL )
     367             :     {
     368           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for McMasa\n" ) );
     369             :     }
     370         277 :     set_zero_fx( hMcMasa->buffer_energy_fx, imult1616( hMcMasa->nbands, hMcMasa->no_col_avg_diff ) ); // hMcMasa->buffer_energy_q
     371         277 :     set16_fx( hMcMasa->buffer_intensity_real_vert_q, 31, DIRAC_NO_COL_AVG_DIFF );
     372         277 :     set16_fx( hMcMasa->buffer_energy_q, 31, DIRAC_NO_COL_AVG_DIFF );
     373             : 
     374         277 :     IF( EQ_32( st_ivas->hEncoderConfig->mc_input_setup, MC_LS_SETUP_5_1 ) )
     375             :     {
     376         169 :         Copy32( ls_azimuth_CICP6_fx, ls_azimuth, sub( nchan_inp, 1 ) );
     377         169 :         Copy32( ls_elevation_CICP6_fx, ls_elevation, sub( nchan_inp, 1 ) );
     378         169 :         hMcMasa->numHorizontalChannels = 5;
     379         169 :         move16();
     380         169 :         hMcMasa->isHorizontalSetup = 1;
     381         169 :         move16();
     382             :     }
     383         108 :     ELSE IF( EQ_32( st_ivas->hEncoderConfig->mc_input_setup, MC_LS_SETUP_7_1 ) )
     384             :     {
     385          13 :         Copy32( ls_azimuth_CICP12_fx, ls_azimuth, sub( nchan_inp, 1 ) );
     386          13 :         Copy32( ls_elevation_CICP12_fx, ls_elevation, sub( nchan_inp, 1 ) );
     387          13 :         hMcMasa->numHorizontalChannels = 7;
     388          13 :         move16();
     389          13 :         hMcMasa->isHorizontalSetup = 1;
     390          13 :         move16();
     391             :     }
     392          95 :     ELSE IF( EQ_32( st_ivas->hEncoderConfig->mc_input_setup, MC_LS_SETUP_5_1_2 ) )
     393             :     {
     394          10 :         Copy32( ls_azimuth_CICP14_fx, ls_azimuth, sub( nchan_inp, 1 ) );
     395          10 :         Copy32( ls_elevation_CICP14_fx, ls_elevation, sub( nchan_inp, 1 ) );
     396          10 :         hMcMasa->numHorizontalChannels = 5;
     397          10 :         move16();
     398          10 :         hMcMasa->isHorizontalSetup = 0;
     399          10 :         move16();
     400             :     }
     401          85 :     ELSE IF( EQ_32( st_ivas->hEncoderConfig->mc_input_setup, MC_LS_SETUP_5_1_4 ) )
     402             :     {
     403          10 :         Copy32( ls_azimuth_CICP16_fx, ls_azimuth, sub( nchan_inp, 1 ) );     // Q22
     404          10 :         Copy32( ls_elevation_CICP16_fx, ls_elevation, sub( nchan_inp, 1 ) ); // Q22
     405          10 :         hMcMasa->numHorizontalChannels = 5;
     406          10 :         move16();
     407          10 :         hMcMasa->isHorizontalSetup = 0;
     408          10 :         move16();
     409             :     }
     410             :     ELSE
     411             :     {
     412          75 :         Copy32( ls_azimuth_CICP19_fx, ls_azimuth, sub( nchan_inp, 1 ) );     // Q22
     413          75 :         Copy32( ls_elevation_CICP19_fx, ls_elevation, sub( nchan_inp, 1 ) ); // Q22
     414          75 :         hMcMasa->numHorizontalChannels = 7;
     415          75 :         move16();
     416          75 :         hMcMasa->isHorizontalSetup = 0;
     417          75 :         move16();
     418             :     }
     419             : 
     420         277 :     IF( hMcMasa->separateChannelEnabled )
     421             :     {
     422          28 :         Copy32( &ls_azimuth[hMcMasa->separateChannelIndex + 1], &ls_azimuth[hMcMasa->separateChannelIndex], numAnalysisChannels - hMcMasa->separateChannelIndex );     // Q22
     423          28 :         Copy32( &ls_elevation[hMcMasa->separateChannelIndex + 1], &ls_elevation[hMcMasa->separateChannelIndex], numAnalysisChannels - hMcMasa->separateChannelIndex ); // Q22
     424          28 :         hMcMasa->numHorizontalChannels = sub( hMcMasa->numHorizontalChannels, 1 );
     425          28 :         move16();
     426             :     }
     427             : 
     428         277 :     computeEvenLayout_fx( ls_azimuth, ls_azimuth_even, hMcMasa->numHorizontalChannels );
     429         277 :     IF( !hMcMasa->isHorizontalSetup )
     430             :     {
     431          95 :         computeEvenLayout_fx( &ls_azimuth[hMcMasa->numHorizontalChannels], &ls_azimuth_even[hMcMasa->numHorizontalChannels], sub( numAnalysisChannels, hMcMasa->numHorizontalChannels ) );
     432             :     }
     433             : 
     434        2170 :     FOR( i = 0; i < numAnalysisChannels; i++ )
     435             :     {
     436        1893 :         hMcMasa->chnlToFoaMtx_fx[0][i] = ONE_IN_Q31;
     437        1893 :         move32();
     438        1893 :         hMcMasa->chnlToFoaMtx_fx[1][i] = L_mult( getSineWord16R2( extract_l( Mpy_32_32( ls_azimuth[i], 46603 /*32767/360*/ ) /*Q22+Q24-31=>Q15*/ ) ), getCosWord16R2( extract_l( Mpy_32_32( ls_elevation[i], 46603 /*2^24/360*/ ) ) ) ); // Q31
     439        1893 :         move32();
     440        1893 :         hMcMasa->chnlToFoaMtx_fx[2][i] = L_shl( getSineWord16R2( extract_l( Mpy_32_32( ls_elevation[i], 46603 /*2^24/360*/ ) ) ), 16 ); // Q31
     441        1893 :         move32();
     442        1893 :         hMcMasa->chnlToFoaMtx_fx[3][i] = L_mult( getCosWord16R2( extract_l( Mpy_32_32( ls_azimuth[i], 46603 /*2^24/360*/ ) ) ), getCosWord16R2( extract_l( Mpy_32_32( ls_elevation[i], 46603 /*2^24/360*/ ) ) ) ); // Q31
     443        1893 :         move32();
     444             : 
     445        1893 :         hMcMasa->chnlToFoaEvenMtx_fx[0][i] = ONE_IN_Q31;
     446        1893 :         move32();
     447        1893 :         hMcMasa->chnlToFoaEvenMtx_fx[1][i] = L_shl( getSineWord16R2( extract_l( Mpy_32_32( ls_azimuth_even[i], 46603 /*2^24/360*/ ) ) ), 16 ); // Q31
     448        1893 :         move32();
     449        1893 :         hMcMasa->chnlToFoaEvenMtx_fx[2][i] = 0;
     450        1893 :         move32();
     451        1893 :         hMcMasa->chnlToFoaEvenMtx_fx[3][i] = L_shl( getCosWord16R2( extract_l( Mpy_32_32( ls_azimuth_even[i], 46603 /*2^24/360*/ ) ) ), 16 );
     452        1893 :         move32();
     453             :     }
     454             : 
     455         277 :     hMcMasa->combineRatios = hMasa->config.mergeRatiosOverSubframes;
     456         277 :     move16();
     457             : 
     458         277 :     Copy32( ls_azimuth, hMcMasa->ls_azimuth_fx, numAnalysisChannels ); // Q22
     459             : 
     460        1810 :     FOR( i = 0; i < hMcMasa->numHorizontalChannels; i++ )
     461             :     {
     462        1533 :         left_min = ( 360 << 22 );
     463        1533 :         right_min = -( ( 360 << 22 ) );
     464             : 
     465       10214 :         FOR( j = 0; j < hMcMasa->numHorizontalChannels; j++ )
     466             :         {
     467        8681 :             azi_diff = L_sub( ls_azimuth[j], ls_azimuth[i] );
     468             : 
     469        8681 :             IF( GT_32( azi_diff, ( 180 << 22 ) ) )
     470             :             {
     471         466 :                 azi_diff = L_sub( azi_diff, 360 << 22 );
     472             :             }
     473        8215 :             ELSE IF( LT_32( azi_diff, -( 180 << 22 ) ) )
     474             :             {
     475         466 :                 azi_diff = L_add( azi_diff, 360 << 22 );
     476             :             }
     477        8681 :             test();
     478        8681 :             IF( LT_32( azi_diff, left_min ) && azi_diff > 0 )
     479             :             {
     480        2336 :                 hMcMasa->leftNearest[i] = j;
     481        2336 :                 move16();
     482        2336 :                 left_min = azi_diff;
     483        2336 :                 move32();
     484             :             }
     485        8681 :             test();
     486        8681 :             IF( GT_32( azi_diff, right_min ) && azi_diff < 0 )
     487             :             {
     488        2059 :                 hMcMasa->rightNearest[i] = j;
     489        2059 :                 move16();
     490        2059 :                 right_min = azi_diff;
     491        2059 :                 move32();
     492             :             }
     493             :         }
     494             :     }
     495             : 
     496         277 :     hMcMasa->prevMultiChEne_fx = 0;
     497         277 :     move32();
     498         277 :     hMcMasa->prevDownmixEne_fx = 0;
     499         277 :     move32();
     500         277 :     hMcMasa->prevMultiChEne_e = 0;
     501         277 :     move16();
     502         277 :     hMcMasa->prevDownmixEne_e = 0;
     503         277 :     move16();
     504         277 :     hMcMasa->prevEQ_e = 1;
     505         277 :     move16();
     506         277 :     hMcMasa->prevEQ_fx = 1073741824;
     507         277 :     move32();
     508         277 :     input_frame = (Word16) Mpy_32_32( input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 );
     509      253397 :     FOR( i = 0; i < input_frame; i++ )
     510             :     {
     511      253120 :         hMcMasa->interpolator_fx[i] = div_s( i, input_frame );
     512      253120 :         move16();
     513             :     }
     514             : 
     515         277 :     mvs2s( DirAC_block_grouping_5ms_MDFT, hMcMasa->block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 );
     516             : 
     517         277 :     hMcMasa->index_buffer_intensity = 0;
     518         277 :     move16();
     519         277 :     st_ivas->hMcMasa = hMcMasa;
     520             : 
     521         277 :     return error;
     522             : }
     523             : /*-------------------------------------------------------------------------
     524             :  * ivas_mcmasa_enc_reconfig()
     525             :  *
     526             :  * Reconfigure McMASA encoder
     527             :  *------------------------------------------------------------------------*/
     528             : 
     529          46 : ivas_error ivas_mcmasa_enc_reconfig_fx(
     530             :     Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */
     531             : )
     532             : {
     533             :     Word32 ivas_total_brate;
     534             :     ivas_error error;
     535             : 
     536          46 :     error = IVAS_ERR_OK;
     537          46 :     move32();
     538             : 
     539          46 :     ivas_total_brate = st_ivas->hEncoderConfig->ivas_total_brate;
     540          46 :     move32();
     541             : 
     542          46 :     IF( NE_32( ivas_total_brate, st_ivas->hEncoderConfig->last_ivas_total_brate ) )
     543             :     {
     544             :         /* bitrate changed, may need to do something */
     545             : 
     546             :         /* brute-force solution: close McMASA and re-instantiate with new settings */
     547          46 :         ivas_masa_enc_close_fx( &( st_ivas->hMasa ) );
     548             : 
     549          46 :         ivas_mcmasa_enc_close_fx( &( st_ivas->hMcMasa ), st_ivas->hEncoderConfig->input_Fs );
     550             : 
     551             :         /* Determine if to separate some channels from the analysis */
     552          46 :         ivas_mcmasa_setNumTransportChannels_fx( &( st_ivas->nchan_transport ), &( st_ivas->hEncoderConfig->element_mode_init ), ivas_total_brate );
     553             : 
     554          46 :         IF( NE_32( ( error = ivas_masa_enc_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
     555             :         {
     556           0 :             return error;
     557             :         }
     558          46 :         IF( NE_32( ( error = ivas_mcmasa_enc_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
     559             :         {
     560           0 :             return error;
     561             :         }
     562             : 
     563             :         /* core SCE, CPE reconfiguration happens later */
     564             :     }
     565             : 
     566          46 :     return error;
     567             : }
     568             : /*--------------------------------------------------------------------------*
     569             :  * ivas_mcmasa_enc_close()
     570             :  *
     571             :  *
     572             :  *--------------------------------------------------------------------------*/
     573             : 
     574        1271 : void ivas_mcmasa_enc_close_fx(
     575             :     MCMASA_ENC_HANDLE *hMcMasa, /* i/o: encoder McMASA handle    */
     576             :     const Word32 input_Fs       /* i  : input sampling rate      */
     577             : )
     578             : {
     579             :     Word16 i, j;
     580             : 
     581        1271 :     test();
     582        1271 :     IF( hMcMasa == NULL || *hMcMasa == NULL )
     583             :     {
     584         994 :         return;
     585             :     }
     586             : 
     587         277 :     IF( ( *hMcMasa )->separateChannelEnabled )
     588             :     {
     589          28 :         free( ( *hMcMasa )->delay_buffer_lfe[0] );
     590          28 :         free( ( *hMcMasa )->delay_buffer_lfe[1] );
     591             : 
     592          84 :         FOR( i = 0; i < 2; i++ )
     593             :         {
     594          56 :             free( ( *hMcMasa )->lfeAnaRingBuffer[i] );
     595             :         }
     596             :     }
     597             : 
     598         277 :     ivas_FB_mixer_close_fx( &( *hMcMasa )->hFbMixer, input_Fs, 0 );
     599             : 
     600         277 :     IF( !( *hMcMasa )->separateChannelEnabled )
     601             :     {
     602         249 :         ivas_FB_mixer_close_fx( &( *hMcMasa )->hFbMixerLfe, input_Fs, 0 );
     603             :     }
     604             : 
     605             :     /* intensity 3-dim */
     606        1108 :     FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
     607             :     {
     608        4155 :         FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
     609             :         {
     610        3324 :             free( ( *hMcMasa )->direction_vector_m_fx[i][j] );
     611        3324 :             ( *hMcMasa )->direction_vector_m_fx[i][j] = NULL;
     612             :         }
     613        4155 :         FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
     614             :         {
     615        3324 :             free( ( *hMcMasa )->direction_vector_e[i][j] );
     616        3324 :             ( *hMcMasa )->direction_vector_e[i][j] = NULL;
     617             :         }
     618             : 
     619        7479 :         FOR( j = 0; j < ( *hMcMasa )->no_col_avg_diff; j++ )
     620             :         {
     621        6648 :             free( ( *hMcMasa )->buffer_intensity_real_fx[i][j] );
     622        6648 :             ( *hMcMasa )->buffer_intensity_real_fx[i][j] = NULL;
     623             :         }
     624             : 
     625         831 :         free( ( *hMcMasa )->buffer_intensity_real_fx[i] );
     626         831 :         ( *hMcMasa )->buffer_intensity_real_fx[i] = NULL;
     627             : 
     628         831 :         free( ( *hMcMasa )->direction_vector_m_fx[i] );
     629         831 :         ( *hMcMasa )->direction_vector_m_fx[i] = NULL;
     630             : 
     631         831 :         free( ( *hMcMasa )->direction_vector_e[i] );
     632         831 :         ( *hMcMasa )->direction_vector_e[i] = NULL;
     633             :     }
     634             : 
     635        2493 :     FOR( j = 0; j < ( *hMcMasa )->no_col_avg_diff; j++ )
     636             :     {
     637        2216 :         free( ( *hMcMasa )->buffer_intensity_real_vert_fx[j] );
     638        2216 :         ( *hMcMasa )->buffer_intensity_real_vert_fx[j] = NULL;
     639             :     }
     640         277 :     free( ( *hMcMasa )->buffer_intensity_real_vert_fx );
     641         277 :     ( *hMcMasa )->buffer_intensity_real_vert_fx = NULL;
     642             : 
     643         277 :     free( ( *hMcMasa )->buffer_energy_fx );
     644         277 :     ( *hMcMasa )->buffer_energy_fx = NULL;
     645             : 
     646         277 :     free( ( *hMcMasa ) );
     647         277 :     ( *hMcMasa ) = NULL;
     648             : 
     649         277 :     return;
     650             : }
     651             : /*--------------------------------------------------------------------------*
     652             :  * ivas_mcmasa_enc()
     653             :  *
     654             :  * Multichannel MASA encoder
     655             :  *--------------------------------------------------------------------------*/
     656             : 
     657       11470 : void ivas_mcmasa_enc_fx(
     658             :     MCMASA_ENC_HANDLE hMcMasa,    /* i/o: Encoder McMASA handle         */
     659             :     IVAS_QMETADATA_HANDLE hQMeta, /* o  : Qmetadata handle              */
     660             :     MASA_ENCODER_HANDLE hMasa,    /* i/o: Encoder MASA handle           */
     661             :     Word32 *data_fx[],            /* i  : Input frame of audio Q(q_inp) */
     662             :     const Word16 input_frame,     /* i  : Input frame size              */
     663             :     const Word16 nchan_transport, /* i  : Number of transport channels  */
     664             :     const Word16 nchan_inp,       /* i  : Number of input channels      */
     665             :     const Word16 q_inp            /* i  : Input data q-format           */
     666             : )
     667             : {
     668             :     Word16 i, j, k;
     669       11470 :     Word16 nBands = hMcMasa->nbands;
     670       11470 :     move16();
     671       11470 :     Word16 nBlocks = MAX_PARAM_SPATIAL_SUBFRAMES;
     672       11470 :     move16();
     673       11470 :     UWord8 fixedDistance = 0;
     674       11470 :     move16();
     675             :     Word32 elevation_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];   // Q22
     676             :     Word32 azimuth_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];     // Q22
     677             :     Word32 energyRatio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];          // Q31
     678             :     Word32 spreadCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];      // Q30
     679             :     Word32 surroundingCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; // Q31
     680             :     Word32 separatedChannelSignal[L_FRAME48k];
     681             : 
     682             :     /* Compute low frequency energy */
     683       11470 :     computeLfeEnergy_fx( hMcMasa, data_fx, input_frame, q_inp );
     684             : 
     685             :     /* Sum center and LFE, move surround channels */
     686       11470 :     v_add_32( data_fx[2], data_fx[3], data_fx[2], input_frame ); // q_inp
     687       42430 :     FOR( i = 4; i < nchan_inp; i++ )
     688             :     {
     689       30960 :         Copy32( data_fx[i], data_fx[i - 1], input_frame ); // q_inp
     690             :     }
     691             : 
     692       11470 :     IF( hMcMasa->separateChannelEnabled )
     693             :     {
     694             :         /* Identify channel to separate */
     695         625 :         i = hMcMasa->separateChannelIndex;
     696         625 :         move16();
     697             : 
     698             :         /* Separate the identified channel */
     699         625 :         Copy32( data_fx[i], separatedChannelSignal, input_frame ); // q_inp
     700             : 
     701             :         /* Move the remaining channels in order to perform the analysis without the separated channel */
     702        5585 :         FOR( i = ( hMcMasa->separateChannelIndex + 1 ); i < ( nchan_inp - 1 ); i++ )
     703             :         {
     704        4960 :             Copy32( data_fx[i], data_fx[i - 1], input_frame ); // q_inp
     705             :         }
     706             :     }
     707             : 
     708             :     /* Analysis */
     709       11470 :     ivas_mcmasa_param_est_enc_fx( hMcMasa, hMasa, data_fx, elevation_m_values_fx, azimuth_m_values_fx, energyRatio_fx, spreadCoherence_fx, surroundingCoherence_fx, input_frame, nchan_inp, q_inp );
     710             : 
     711             :     /* Determine LFE-to-total energy ratio */
     712       57350 :     FOR( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
     713             :     {
     714       45880 :         hMasa->data.lfeToTotalEnergyRatio_fx[i] = L_deposit_h( BASOP_Util_Divide3232_Scale( hMcMasa->lfeLfEne[i], L_add( EPSILON_FX, hMcMasa->totalLfEne[i] ), &hMasa->data.lfeToTotalEnergyRatio_e[i] ) ); // hMasa->data.lfeToTotalEnergyRatio_e[i]
     715       45880 :         hMasa->data.lfeToTotalEnergyRatio_e[i] = add( sub( hMcMasa->lfeLfEne_e[i], hMcMasa->totalLfEne_e[i] ), hMasa->data.lfeToTotalEnergyRatio_e[i] );
     716       45880 :         move32();
     717       45880 :         move16();
     718             :     }
     719             : 
     720             :     /* Set analyzed values to the MASA struct */
     721       68820 :     FOR( i = 0; i < nBands; i++ )
     722             :     {
     723      286750 :         FOR( j = 0; j < nBlocks; j++ )
     724             :         {
     725      229400 :             IF( hMcMasa->combineRatios )
     726             :             {
     727      229400 :                 k = 0;
     728      229400 :                 move16();
     729             :             }
     730             :             ELSE
     731             :             {
     732           0 :                 k = j;
     733           0 :                 move16();
     734             :             }
     735             : 
     736      229400 :             hQMeta->q_direction[0].band_data[i].azimuth_fx[j] = azimuth_m_values_fx[j][i]; // Q22
     737      229400 :             move32();
     738      229400 :             hQMeta->q_direction[0].band_data[i].elevation_fx[j] = elevation_m_values_fx[j][i]; // Q22
     739      229400 :             move32();
     740      229400 :             hQMeta->q_direction[0].band_data[i].energy_ratio_fx[j] = energyRatio_fx[k][i]; // Q30
     741      229400 :             move32();
     742      229400 :             hQMeta->q_direction[0].band_data[i].distance[j] = fixedDistance;
     743      229400 :             move16();
     744             : 
     745      229400 :             IF( hQMeta->surcoh_band_data != NULL )
     746             :             {
     747      202200 :                 hQMeta->q_direction[0].coherence_band_data[i].spread_coherence[j] = (UWord8) round_fx( Mpy_32_32( spreadCoherence_fx[j][i], L_shl( UINT8_MAX, Q17 ) ) ); // Q0
     748      202200 :                 hQMeta->surcoh_band_data[i].surround_coherence[j] = (UWord8) round_fx( Mpy_32_32( surroundingCoherence_fx[k][i], L_shl( UINT8_MAX, Q16 ) ) );            // Q0
     749      202200 :                 move16();
     750      202200 :                 move16();
     751             :             }
     752             :         }
     753             :     }
     754             : 
     755             :     /* At lower sampling rates, set zeros for higher bands that were not analyzed */
     756       11470 :     IF( LT_16( nBands, hMcMasa->nCodingBands ) )
     757             :     {
     758           0 :         FOR( i = nBands; i < hMcMasa->nCodingBands; i++ )
     759             :         {
     760           0 :             FOR( j = 0; j < nBlocks; j++ )
     761             :             {
     762           0 :                 hQMeta->q_direction[0].band_data[i].azimuth_fx[j] = 0; // Q22
     763           0 :                 move32();
     764           0 :                 hQMeta->q_direction[0].band_data[i].elevation_fx[j] = 0; // Q22
     765           0 :                 move32();
     766           0 :                 hQMeta->q_direction[0].band_data[i].energy_ratio_fx[j] = 0; // Q30
     767           0 :                 move32();
     768           0 :                 hQMeta->q_direction[0].band_data[i].distance[j] = 0;
     769           0 :                 move16();
     770             : 
     771           0 :                 IF( hQMeta->surcoh_band_data != NULL )
     772             :                 {
     773           0 :                     hQMeta->q_direction[0].coherence_band_data[i].spread_coherence[j] = 0;
     774           0 :                     move16();
     775           0 :                     hQMeta->surcoh_band_data[i].surround_coherence[j] = 0;
     776           0 :                     move16();
     777             :                 }
     778             :             }
     779             :         }
     780             :     }
     781             : 
     782             :     /* Downmix */
     783       11470 :     ivas_mcmasa_dmx_fx( hMcMasa, data_fx, sub( 31, q_inp ), input_frame, nchan_transport, nchan_inp );
     784             : 
     785       11470 :     IF( hMcMasa->separateChannelEnabled )
     786             :     {
     787             :         /* Put separated channel back to data_f to first empty channel after the transport audio signals for encoding */
     788         625 :         Copy32( separatedChannelSignal, data_fx[2], input_frame );
     789             :     }
     790             : 
     791             :     /* Update mcMASA-relevant coding parameters */
     792             :     /* These are reset to default values as they may be modified during later processing. */
     793       11470 :     hMasa->config.joinedSubframes = FALSE;
     794       11470 :     move16();
     795       11470 :     hQMeta->q_direction[0].cfg.nbands = hMcMasa->nbands;
     796       11470 :     move16();
     797       11470 :     hQMeta->q_direction[0].cfg.nblocks = MAX_PARAM_SPATIAL_SUBFRAMES;
     798       11470 :     move16();
     799       11470 :     hQMeta->all_coherence_zero = 1;
     800       11470 :     move16();
     801             : 
     802             :     /* Check spread coherence */
     803       11470 :     i = 0;
     804       11470 :     move16();
     805       11470 :     test();
     806       25892 :     WHILE( ( i < nBlocks ) && hQMeta->all_coherence_zero )
     807             :     {
     808       14422 :         test();
     809       14422 :         j = 0;
     810       14422 :         move16();
     811       14422 :         test();
     812       44499 :         WHILE( LT_16( j, nBands ) && hQMeta->all_coherence_zero )
     813             :         {
     814       30077 :             test();
     815       30077 :             IF( GT_32( spreadCoherence_fx[i][j], MASA_COHERENCE_THRESHOLD_FX >> 1 ) )
     816             :             {
     817       10678 :                 hQMeta->all_coherence_zero = 0;
     818       10678 :                 move16();
     819             :             }
     820       30077 :             j++;
     821             :         }
     822       14422 :         i++;
     823             :     }
     824             : 
     825             :     /* Check surrounding coherence */
     826       11470 :     IF( hQMeta->all_coherence_zero )
     827             :     {
     828             :         Word32 diffuse_to_total_ratio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
     829             :         UWord8 cohSignificant;
     830             :         Word16 nSubFrames;
     831             : 
     832         792 :         IF( hMcMasa->combineRatios )
     833             :         {
     834         792 :             nSubFrames = 1;
     835         792 :             move16();
     836             :         }
     837             :         ELSE
     838             :         {
     839           0 :             nSubFrames = MAX_PARAM_SPATIAL_SUBFRAMES;
     840           0 :             move16();
     841             :         }
     842             : 
     843        1584 :         FOR( i = 0; i < nSubFrames; i++ )
     844             :         {
     845        4752 :             FOR( j = 0; j < nBands; j++ )
     846             :             {
     847        3960 :                 diffuse_to_total_ratio_fx[i][j] = L_max( 0, L_sub( ONE_IN_Q31, energyRatio_fx[i][j] ) ); // Q31
     848        3960 :                 move32();
     849             :             }
     850             :         }
     851             : 
     852         792 :         cohSignificant = ivas_masa_surrcoh_signicant_fx( surroundingCoherence_fx, diffuse_to_total_ratio_fx, nSubFrames, nBands );
     853         792 :         IF( cohSignificant )
     854             :         {
     855         417 :             hQMeta->all_coherence_zero = 0;
     856         417 :             move16();
     857             :         }
     858             :     }
     859       11470 :     hMasa->config.coherencePresent = !hQMeta->all_coherence_zero;
     860       11470 :     move16();
     861             : 
     862       11470 :     return;
     863             : }
     864             : 
     865             : /*--------------------------------------------------------------------------*
     866             :  * ivas_mcmasa_param_est_enc()
     867             :  *
     868             :  * Estimate metadata parameters for McMASA
     869             :  *--------------------------------------------------------------------------*/
     870             : 
     871       11470 : void ivas_mcmasa_param_est_enc_fx(
     872             :     MCMASA_ENC_HANDLE hMcMasa,                                                         /* i  : McMASA encoder structure            */
     873             :     MASA_ENCODER_HANDLE hMasa,                                                         /* i  : MASA encoder structure              */
     874             :     Word32 *data_f[],                                                                  /* i  : Audio frame in MC-format        Q(q_inp)    */
     875             :     Word32 elevation_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],   /* o  : Estimated elevation             Q22 */
     876             :     Word32 azimuth_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],     /* o  : Estimated azimuth               Q22 */
     877             :     Word32 energyRatio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],          /* o  : Estimated direct-to-total ratio Q31 */
     878             :     Word32 spreadCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],      /* o  : Estimated spread coherence      Q30 */
     879             :     Word32 surroundingCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o  : Estimated surround coherence    Q31 */
     880             :     const Word16 input_frame,                                                          /* i  : Input frame size                    */
     881             :     const Word16 nchan_inp,                                                            /* i  : Number of input channels            */
     882             :     const Word16 q_inp                                                                 /* i  : Q factor of the data_f              */
     883             : )
     884             : {
     885             :     Word32 reference_power_fx[MDFT_NO_COL_MAX][DIRAC_NO_FB_BANDS_MAX];
     886             :     Word16 ts, i, j, d;
     887             :     Word16 num_freq_bins, num_freq_bands, index;
     888             :     Word32 dir_v_fx[DIRAC_NUM_DIMS];
     889             :     Word16 out_exp[MASA_FREQUENCY_BANDS];
     890             :     Word16 q_vdv[MASA_FREQUENCY_BANDS];
     891             :     Word16 l_ts;
     892             :     Word32 *pcm_in[MCMASA_MAX_ANA_CHANS];
     893             :     Word32 Chnl_RealBuffer_fx[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX];
     894             :     Word32 Chnl_ImagBuffer_fx[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX];
     895             :     Word32 *p_Chnl_RealBuffer_fx[MCMASA_MAX_ANA_CHANS];
     896             :     Word32 *p_Chnl_ImagBuffer_fx[MCMASA_MAX_ANA_CHANS];
     897             :     Word32 Foa_RealBuffer_fx[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX];
     898             :     Word32 Foa_ImagBuffer_fx[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX];
     899             :     Word32 FoaEven_RealBuffer_fx[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX];
     900             :     Word32 FoaEven_ImagBuffer_fx[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX];
     901             :     Word32 intensity_real_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
     902             :     Word32 intensity_even_real_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
     903             :     Word32 direction_vector_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
     904             :     Word32 diffuseness_vector_fx[MASA_FREQUENCY_BANDS];
     905             :     Word32 vertical_diffuseness_vector_fx[MASA_FREQUENCY_BANDS];                // q_vdv
     906             :     Word32 diffuseness_m_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; // diffuseness_e
     907             :     Word16 diffuseness_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
     908             :     Word32 coherentEnergyRatio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; // coherentEnergyRatio_e
     909             :     Word16 coherentEnergyRatio_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
     910             :     Word16 band_m_idx, block_m_idx;
     911             :     Word32 renormalization_factor_diff_fx[MASA_FREQUENCY_BANDS]; // renormalization_factor_diff_e
     912             :     Word16 renormalization_factor_diff_e[MASA_FREQUENCY_BANDS];
     913             :     Word32 norm_tmp_fx;
     914             :     Word16 mrange[2], brange[2];
     915             :     Word16 numSubFramesForRatio;
     916             :     CovarianceMatrix COVls[MASA_FREQUENCY_BANDS];
     917             :     Word32 absCOVls_fx[MCMASA_MAX_ANA_CHANS][MCMASA_MAX_ANA_CHANS];
     918             :     Word16 absCOVls_e[MCMASA_MAX_ANA_CHANS][MCMASA_MAX_ANA_CHANS];
     919             :     Word32 lsEnergy_fx[MCMASA_MAX_ANA_CHANS]; // lsEnergy_e
     920             :     Word16 lsEnergy_e[MCMASA_MAX_ANA_CHANS];
     921             :     Word32 lsEnergySum_fx, maxEne_fx;
     922       11470 :     Word16 lsEnergySum_e = 0, maxEne_e;
     923       11470 :     move16();
     924             :     Word16 loudestCh;
     925             :     Word32 surrCoh_fx, tempCoh_fx, tempCoh2_fx;
     926             :     Word16 surrCoh_e, tempCoh_e, tempCoh2_e;
     927             :     Word16 i1, i2, i3;
     928             :     Word32 angleDist_fx, minAngleDist_fx;
     929             :     Word32 currentAzi_fx;
     930             :     Word32 lsEnergyRelation_fx; // lsEnergyRelation_e
     931             :     Word16 lsEnergyRelation_e;
     932             :     Word32 tempLsEnergyRelation_fx; // tempLsEnergyRelation_e
     933             :     Word16 tempLsEnergyRelation_e;
     934             :     Word32 stereoness_fx, cohwideness_fx, spreadCoh_fx;
     935             :     Word32 stereoRatio_fx, cohPanRatio_fx;
     936             :     Word32 stereoCoh_fx, cohPanCoh_fx, cohRatio_fx;
     937             :     Word16 stereoCoh_e, cohPanCoh_e, spreadCoh_e, stereoness_e;
     938             :     Word32 renormalization_factor_coh_fx[MASA_FREQUENCY_BANDS]; // renormalization_factor_coh_e
     939             :     Word16 renormalization_factor_coh_e[MASA_FREQUENCY_BANDS];
     940             :     Word16 surroundingCoherence_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
     941             :     Word16 numAnalysisChannels;
     942             : 
     943      137640 :     FOR( i = 0; i < MCMASA_MAX_ANA_CHANS; i++ )
     944             :     {
     945      126170 :         set_zero_fx( Chnl_RealBuffer_fx[i], DIRAC_NO_FB_BANDS_MAX );
     946      126170 :         set_zero_fx( Chnl_ImagBuffer_fx[i], DIRAC_NO_FB_BANDS_MAX );
     947             :     }
     948             : 
     949       11470 :     num_freq_bins = idiv1616( input_frame, MDFT_NO_COL_MAX );
     950       11470 :     num_freq_bands = hMcMasa->nbands;
     951       11470 :     move16();
     952       11470 :     l_ts = idiv1616( input_frame, MDFT_NO_COL_MAX );
     953             : 
     954       11470 :     set16_fx( q_vdv, 31, MASA_FREQUENCY_BANDS );
     955       11470 :     set16_fx( out_exp, 30, MASA_FREQUENCY_BANDS );
     956             : 
     957       11470 :     numAnalysisChannels = sub( nchan_inp, 1 );
     958       11470 :     IF( hMcMasa->separateChannelEnabled )
     959             :     {
     960         625 :         numAnalysisChannels = sub( nchan_inp, 2 );
     961             :     }
     962             : 
     963       11470 :     IF( hMcMasa->combineRatios )
     964             :     {
     965             :         /* Need to initialize renormalization_factors, and variables to be normalized */
     966       11470 :         set_zero_fx( renormalization_factor_diff_fx, hMcMasa->nbands ); // renormalization_factor_diff_e
     967       11470 :         set16_fx( renormalization_factor_diff_e, 0, hMcMasa->nbands );
     968       11470 :         set_zero_fx( &diffuseness_m_fx[0][0], MASA_FREQUENCY_BANDS * MAX_PARAM_SPATIAL_SUBFRAMES ); // diffuseness_e
     969       11470 :         set16_fx( &diffuseness_e[0][0], 31, MASA_FREQUENCY_BANDS * MAX_PARAM_SPATIAL_SUBFRAMES );
     970       11470 :         set_zero_fx( renormalization_factor_coh_fx, hMcMasa->nbands ); // renormalization_factor_coh_e
     971       11470 :         set16_fx( renormalization_factor_coh_e, 31, hMcMasa->nbands );
     972       11470 :         set_zero_fx( surroundingCoherence_fx[0], hMcMasa->nbands ); // surroundingCoherence_e
     973       11470 :         set16_fx( &surroundingCoherence_e[0][0], 31, MASA_FREQUENCY_BANDS * MAX_PARAM_SPATIAL_SUBFRAMES );
     974       11470 :         set_zero_fx( coherentEnergyRatio_fx[0], hMcMasa->nbands ); // coherentEnergyRatio_e
     975       11470 :         set16_fx( &coherentEnergyRatio_e[0][0], 0, MASA_FREQUENCY_BANDS * MAX_PARAM_SPATIAL_SUBFRAMES );
     976             :     }
     977             : 
     978             :     /* Copy current frame to memory for delay compensation */
     979       76215 :     FOR( i = 0; i < numAnalysisChannels; i++ )
     980             :     {
     981       64745 :         pcm_in[i] = data_f[i];                               // q_inp
     982       64745 :         p_Chnl_RealBuffer_fx[i] = &Chnl_RealBuffer_fx[i][0]; // q_inp
     983       64745 :         p_Chnl_ImagBuffer_fx[i] = &Chnl_ImagBuffer_fx[i][0]; // q_inp
     984             :     }
     985             : 
     986             :     /* initialising energy_fx */
     987       57350 :     FOR( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
     988             :     {
     989     1147000 :         FOR( i = 0; i < MASA_FREQUENCY_BANDS; i++ )
     990             :         {
     991     1101120 :             hMasa->data.energy_fx[block_m_idx][i] = 0; // hMasa->data.energy_e
     992     1101120 :             move32();
     993     1101120 :             hMasa->data.energy_e[block_m_idx][i] = 31;
     994     1101120 :             move16();
     995             :         }
     996             :     }
     997       11470 :     hMasa->data.q_energy = 0;
     998       11470 :     move16();
     999             : 
    1000             :     /* do processing over all CLDFB time slots */
    1001       57350 :     FOR( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
    1002             :     {
    1003       45880 :         mrange[0] = hMcMasa->block_grouping[block_m_idx];
    1004       45880 :         move16();
    1005       45880 :         mrange[1] = hMcMasa->block_grouping[block_m_idx + 1];
    1006       45880 :         move16();
    1007             : 
    1008      275280 :         FOR( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ )
    1009             :         {
    1010      229400 :             hMcMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx] = 0;
    1011      229400 :             move32();
    1012      229400 :             hMcMasa->direction_vector_m_fx[1][block_m_idx][band_m_idx] = 0;
    1013      229400 :             move32();
    1014      229400 :             hMcMasa->direction_vector_m_fx[2][block_m_idx][band_m_idx] = 0;
    1015      229400 :             move32();
    1016             :         }
    1017             : 
    1018             :         /* Reset variable */
    1019      275280 :         FOR( i = 0; i < hMcMasa->nbands; i++ )
    1020             :         {
    1021     1524300 :             FOR( j = 0; j < numAnalysisChannels; j++ )
    1022             :             {
    1023     1294900 :                 set_zero_fx( COVls[i].xr_fx[j], numAnalysisChannels ); // COVls[i].xr_e[j]
    1024     1294900 :                 set_zero_fx( COVls[i].xi_fx[j], numAnalysisChannels ); // COVls[i].xi_e[j]
    1025     1294900 :                 set16_fx( COVls[i].xr_e[j], 0, numAnalysisChannels );
    1026     1294900 :                 set16_fx( COVls[i].xi_e[j], 0, numAnalysisChannels );
    1027             :             }
    1028             :         }
    1029             : 
    1030       91760 :         FOR( ts = mrange[0]; ts < mrange[1]; ts++ )
    1031             :         {
    1032       45880 :             Word16 cr_q = MAX_16, ci_q = MAX_16, sf, c_e;
    1033       45880 :             Word16 inp_q = q_inp;
    1034       45880 :             move16();
    1035       45880 :             move16();
    1036       45880 :             move16();
    1037             : 
    1038       45880 :             ivas_fb_mixer_get_windowed_fr_fx( hMcMasa->hFbMixer, pcm_in, p_Chnl_RealBuffer_fx, p_Chnl_ImagBuffer_fx, l_ts, l_ts, hMcMasa->hFbMixer->fb_cfg->num_in_chans, 0 );
    1039             : 
    1040       45880 :             ivas_fb_mixer_update_prior_input_fx( hMcMasa->hFbMixer, pcm_in, l_ts, hMcMasa->hFbMixer->fb_cfg->num_in_chans );
    1041             : 
    1042      304860 :             FOR( i = 0; i < numAnalysisChannels; i++ )
    1043             :             {
    1044      258980 :                 pcm_in[i] += l_ts;
    1045      258980 :                 cr_q = s_min( cr_q, L_norm_arr( Chnl_ImagBuffer_fx[i], DIRAC_NO_FB_BANDS_MAX ) );
    1046      258980 :                 ci_q = s_min( ci_q, L_norm_arr( Chnl_RealBuffer_fx[i], DIRAC_NO_FB_BANDS_MAX ) );
    1047             :             }
    1048             : 
    1049       45880 :             sf = sub( s_min( cr_q, ci_q ), 5 );
    1050      304860 :             FOR( i = 0; i < numAnalysisChannels; i++ )
    1051             :             {
    1052      258980 :                 scale_sig32( Chnl_RealBuffer_fx[i], DIRAC_NO_FB_BANDS_MAX, sf ); // Q-> inp_q + sf
    1053      258980 :                 scale_sig32( Chnl_ImagBuffer_fx[i], DIRAC_NO_FB_BANDS_MAX, sf ); // Q-> inp_q + sf
    1054             :             }
    1055       45880 :             inp_q = add( inp_q, sf );
    1056       45880 :             c_e = sub( 31, inp_q );
    1057             : 
    1058             :             /* Compute covariance matrix */
    1059      275280 :             FOR( i = 0; i < num_freq_bands; i++ )
    1060             :             {
    1061      229400 :                 brange[0] = hMcMasa->band_grouping[i];
    1062      229400 :                 move16();
    1063      229400 :                 brange[1] = hMcMasa->band_grouping[i + 1];
    1064      229400 :                 move16();
    1065    11176600 :                 FOR( j = brange[0]; j < brange[1]; j++ )
    1066             :                 {
    1067    10947200 :                     compute_cov_mtx_fx( Chnl_RealBuffer_fx, Chnl_ImagBuffer_fx, j, numAnalysisChannels, &( COVls[i] ), sub( 31, inp_q ) );
    1068             :                 }
    1069             : 
    1070             :                 /* Store energies for guiding metadata encoding */
    1071     1524300 :                 FOR( j = 0; j < numAnalysisChannels; j++ )
    1072             :                 {
    1073     1294900 :                     move32();
    1074     1294900 :                     hMasa->data.energy_fx[block_m_idx][i] = BASOP_Util_Add_Mant32Exp( hMasa->data.energy_fx[block_m_idx][i], hMasa->data.energy_e[block_m_idx][i], COVls[i].xr_fx[j][j], COVls[i].xr_e[j][j], &hMasa->data.energy_e[block_m_idx][i] );
    1075             :                 }
    1076             :             }
    1077             : 
    1078       45880 :             IF( !hMcMasa->separateChannelEnabled )
    1079             :             {
    1080             :                 /* Compute low frequency energy */
    1081      277520 :                 FOR( i = 0; i < numAnalysisChannels; i++ )
    1082             :                 {
    1083     1170700 :                     FOR( j = 0; j < CLDFB_TO_MDFT_FAC; j++ )
    1084             :                     {
    1085      936560 :                         move32();
    1086      936560 :                         hMcMasa->totalLfEne[block_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->totalLfEne[block_m_idx], hMcMasa->totalLfEne_e[block_m_idx], L_add( Mpy_32_32( Chnl_RealBuffer_fx[i][j], Chnl_RealBuffer_fx[i][j] ), Mpy_32_32( Chnl_ImagBuffer_fx[i][j], Chnl_ImagBuffer_fx[i][j] ) ), sub( 31, sub( shl( inp_q, 1 ), 31 ) ), &hMcMasa->totalLfEne_e[block_m_idx] );
    1087             :                     }
    1088             :                 }
    1089             :             }
    1090             : 
    1091             :             /* Compute standard FOA */
    1092             :             /* W */
    1093       45880 :             v_add_32( Chnl_RealBuffer_fx[0], Chnl_RealBuffer_fx[1], Foa_RealBuffer_fx[0], num_freq_bins ); // inp_q
    1094       45880 :             v_add_32( Chnl_ImagBuffer_fx[0], Chnl_ImagBuffer_fx[1], Foa_ImagBuffer_fx[0], num_freq_bins ); // inp_q
    1095      213100 :             FOR( i = 2; i < numAnalysisChannels; i++ )
    1096             :             {
    1097      167220 :                 v_add_32( Chnl_RealBuffer_fx[i], Foa_RealBuffer_fx[0], Foa_RealBuffer_fx[0], num_freq_bins ); // inp_q
    1098      167220 :                 v_add_32( Chnl_ImagBuffer_fx[i], Foa_ImagBuffer_fx[0], Foa_ImagBuffer_fx[0], num_freq_bins ); // inp_q
    1099             :             }
    1100             : 
    1101             :             /* Y */
    1102       45880 :             v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[1][0], Foa_RealBuffer_fx[1], num_freq_bins ); // inp_q
    1103       45880 :             v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[1][0], Foa_ImagBuffer_fx[1], num_freq_bins ); // inp_q
    1104      258980 :             FOR( i = 1; i < numAnalysisChannels; i++ )
    1105             :             {
    1106      213100 :                 v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[1][i], Foa_RealBuffer_fx[1], num_freq_bins ); // inp_q
    1107      213100 :                 v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[1][i], Foa_ImagBuffer_fx[1], num_freq_bins ); // inp_q
    1108             :             }
    1109             : 
    1110             :             /* Z */
    1111       45880 :             IF( hMcMasa->isHorizontalSetup )
    1112             :             {
    1113             :                 /* Set zero for horizontal setups */
    1114       39760 :                 set_zero_fx( Foa_RealBuffer_fx[2], num_freq_bins );
    1115       39760 :                 set_zero_fx( Foa_ImagBuffer_fx[2], num_freq_bins );
    1116             :             }
    1117             :             ELSE
    1118             :             {
    1119        6120 :                 v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[2][0], Foa_RealBuffer_fx[2], num_freq_bins ); // inp_q
    1120        6120 :                 v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[2][0], Foa_ImagBuffer_fx[2], num_freq_bins ); // inp_q
    1121       59060 :                 FOR( i = 1; i < numAnalysisChannels; i++ )
    1122             :                 {
    1123       52940 :                     v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[2][i], Foa_RealBuffer_fx[2], num_freq_bins ); // inp_q
    1124       52940 :                     v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[2][i], Foa_ImagBuffer_fx[2], num_freq_bins ); // inp_q
    1125             :                 }
    1126             :             }
    1127             : 
    1128             :             /* X */
    1129       45880 :             v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[3][0], Foa_RealBuffer_fx[3], num_freq_bins ); // inp_q
    1130       45880 :             v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[3][0], Foa_ImagBuffer_fx[3], num_freq_bins ); // inp_q
    1131      258980 :             FOR( i = 1; i < numAnalysisChannels; i++ )
    1132             :             {
    1133      213100 :                 v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[3][i], Foa_RealBuffer_fx[3], num_freq_bins ); // inp_q
    1134      213100 :                 v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[3][i], Foa_ImagBuffer_fx[3], num_freq_bins ); // inp_q
    1135             :             }
    1136             : 
    1137             :             /* Compute even FOA */
    1138             :             /* W */
    1139       45880 :             Copy32( Foa_RealBuffer_fx[0], FoaEven_RealBuffer_fx[0], num_freq_bins ); // inp_q
    1140       45880 :             Copy32( Foa_ImagBuffer_fx[0], FoaEven_ImagBuffer_fx[0], num_freq_bins ); // inp_q
    1141             : 
    1142             :             /* Y */
    1143       45880 :             v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaEvenMtx_fx[1][0], FoaEven_RealBuffer_fx[1], num_freq_bins ); // inp_q
    1144       45880 :             v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaEvenMtx_fx[1][0], FoaEven_ImagBuffer_fx[1], num_freq_bins ); // inp_q
    1145      258980 :             FOR( i = 1; i < numAnalysisChannels; i++ )
    1146             :             {
    1147      213100 :                 v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaEvenMtx_fx[1][i], FoaEven_RealBuffer_fx[1], num_freq_bins ); // inp_q
    1148      213100 :                 v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaEvenMtx_fx[1][i], FoaEven_ImagBuffer_fx[1], num_freq_bins ); // inp_q
    1149             :             }
    1150             : 
    1151             :             /* Z (even setups are handled as horizontal) */
    1152       45880 :             set_zero_fx( FoaEven_RealBuffer_fx[2], num_freq_bins ); // inp_q
    1153       45880 :             set_zero_fx( FoaEven_ImagBuffer_fx[2], num_freq_bins ); // inp_q
    1154             : 
    1155             :             /* X */
    1156       45880 :             v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaEvenMtx_fx[3][0], FoaEven_RealBuffer_fx[3], num_freq_bins ); // inp_q
    1157       45880 :             v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaEvenMtx_fx[3][0], FoaEven_ImagBuffer_fx[3], num_freq_bins ); // inp_q
    1158      258980 :             FOR( i = 1; i < numAnalysisChannels; i++ )
    1159             :             {
    1160      213100 :                 v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaEvenMtx_fx[3][i], FoaEven_RealBuffer_fx[3], num_freq_bins ); // inp_q
    1161      213100 :                 v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaEvenMtx_fx[3][i], FoaEven_ImagBuffer_fx[3], num_freq_bins ); // inp_q
    1162             :             }
    1163             : 
    1164             :             /* Direction estimation */
    1165       45880 :             computeIntensityVector_enc_fx(
    1166       45880 :                 hMcMasa->band_grouping,
    1167             :                 Foa_RealBuffer_fx,
    1168             :                 Foa_ImagBuffer_fx,
    1169             :                 0,
    1170             :                 num_freq_bands,
    1171             :                 intensity_real_fx );
    1172             : 
    1173       45880 :             computeDirectionVectors_fixed(
    1174             :                 intensity_real_fx[0],
    1175             :                 intensity_real_fx[1],
    1176             :                 intensity_real_fx[2],
    1177             :                 0,
    1178             :                 num_freq_bands,
    1179             :                 direction_vector_fx[0],
    1180             :                 direction_vector_fx[1],
    1181             :                 direction_vector_fx[2], c_e,
    1182             :                 NULL );
    1183             : 
    1184             :             /* Power and intensity estimation for diffuseness */
    1185       45880 :             computeIntensityVector_enc_fx(
    1186       45880 :                 hMcMasa->band_grouping,
    1187             :                 FoaEven_RealBuffer_fx,
    1188             :                 FoaEven_ImagBuffer_fx,
    1189             :                 0,
    1190             :                 num_freq_bands,
    1191             :                 intensity_even_real_fx );
    1192       45880 :             Word16 ref_e = 0;
    1193       45880 :             move16();
    1194       45880 :             computeReferencePower_enc_fx( hMcMasa->band_grouping,
    1195             :                                           FoaEven_RealBuffer_fx,
    1196             :                                           FoaEven_ImagBuffer_fx,
    1197       45880 :                                           reference_power_fx[ts],
    1198             :                                           0,
    1199             :                                           num_freq_bands,
    1200             :                                           MC_FORMAT,
    1201             :                                           0,
    1202             :                                           FOA_CHANNELS, inp_q, &ref_e );
    1203             : 
    1204             :             /* Fill buffers of length "averaging_length" time slots for intensity and energy */
    1205       45880 :             hMcMasa->index_buffer_intensity = add( ( hMcMasa->index_buffer_intensity % hMcMasa->no_col_avg_diff ), 1 ); /* averaging_length = 32 */
    1206       45880 :             move16();
    1207       45880 :             index = hMcMasa->index_buffer_intensity;
    1208       45880 :             move16();
    1209      183520 :             FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
    1210             :             {
    1211             :                 /* only real part needed */
    1212      137640 :                 Copy32( intensity_even_real_fx[i], &( hMcMasa->buffer_intensity_real_fx[i][index - 1][0] ), num_freq_bands ); // hMcMasa->buffer_intensity_real_q
    1213             :             }
    1214       45880 :             hMcMasa->buffer_intensity_real_q[index - 1] = sub( shl( inp_q, 1 ), 31 );
    1215       45880 :             move16();
    1216       45880 :             Copy32( reference_power_fx[ts], &( hMcMasa->buffer_energy_fx[( index - 1 ) * num_freq_bands] ), num_freq_bands ); // ref_e
    1217       45880 :             hMcMasa->buffer_energy_q[index - 1] = sub( Q31, ref_e );
    1218       45880 :             move16();
    1219             : 
    1220       45880 :             computeDiffuseness_mdft_fx( hMcMasa->buffer_intensity_real_fx, hMcMasa->buffer_energy_fx, num_freq_bands, hMcMasa->no_col_avg_diff, diffuseness_vector_fx, hMcMasa->buffer_intensity_real_q, hMcMasa->buffer_energy_q, &out_exp[0] );
    1221      229400 :             FOR( i = 1; i < num_freq_bands; i++ )
    1222             :             {
    1223      183520 :                 out_exp[i] = out_exp[0];
    1224      183520 :                 move16();
    1225             :             }
    1226             :             /* Compute vertical diffuseness, and tune original diffuseness if needed */
    1227       45880 :             IF( !hMcMasa->isHorizontalSetup )
    1228             :             {
    1229        6120 :                 Copy32( intensity_real_fx[2], &( hMcMasa->buffer_intensity_real_vert_fx[index - 1][0] ), num_freq_bands );
    1230        6120 :                 hMcMasa->buffer_intensity_real_vert_q[index - 1] = sub( shl( inp_q, 1 ), 31 );
    1231        6120 :                 move16();
    1232        6120 :                 computeVerticalDiffuseness_fx( hMcMasa->buffer_intensity_real_vert_fx, hMcMasa->buffer_energy_fx, hMcMasa->no_col_avg_diff, num_freq_bands, vertical_diffuseness_vector_fx, hMcMasa->buffer_intensity_real_vert_q, hMcMasa->buffer_energy_q );
    1233        6120 :                 v_min_fx( diffuseness_vector_fx, out_exp, vertical_diffuseness_vector_fx, q_vdv, diffuseness_vector_fx, out_exp, num_freq_bands );
    1234             :             }
    1235             : 
    1236      275280 :             FOR( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ )
    1237             :             {
    1238      229400 :                 norm_tmp_fx = Mult_32_32( reference_power_fx[ts][band_m_idx], L_sub( ONE_IN_Q31, diffuseness_vector_fx[band_m_idx] ) ); /*31-ref_e*/
    1239      229400 :                 hMcMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx], hMcMasa->direction_vector_e[0][block_m_idx][band_m_idx], Mult_32_32( norm_tmp_fx, direction_vector_fx[0][band_m_idx] ), add( 1, ref_e ), &hMcMasa->direction_vector_e[0][block_m_idx][band_m_idx] );
    1240      229400 :                 move32();
    1241      229400 :                 hMcMasa->direction_vector_m_fx[1][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->direction_vector_m_fx[1][block_m_idx][band_m_idx], hMcMasa->direction_vector_e[1][block_m_idx][band_m_idx], Mult_32_32( norm_tmp_fx, direction_vector_fx[1][band_m_idx] ), add( 1, ref_e ), &hMcMasa->direction_vector_e[1][block_m_idx][band_m_idx] );
    1242      229400 :                 move32();
    1243      229400 :                 hMcMasa->direction_vector_m_fx[2][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->direction_vector_m_fx[2][block_m_idx][band_m_idx], hMcMasa->direction_vector_e[2][block_m_idx][band_m_idx], Mult_32_32( norm_tmp_fx, direction_vector_fx[2][band_m_idx] ), add( 1, ref_e ), &hMcMasa->direction_vector_e[2][block_m_idx][band_m_idx] );
    1244      229400 :                 move32();
    1245      229400 :                 IF( hMcMasa->combineRatios )
    1246             :                 {
    1247      229400 :                     diffuseness_m_fx[0][band_m_idx] = BASOP_Util_Add_Mant32Exp( diffuseness_m_fx[0][band_m_idx], diffuseness_e[0][band_m_idx], Mult_32_32( reference_power_fx[ts][band_m_idx], diffuseness_vector_fx[band_m_idx] ), ref_e, &diffuseness_e[0][band_m_idx] );
    1248      229400 :                     move32();
    1249      229400 :                     renormalization_factor_diff_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( renormalization_factor_diff_fx[band_m_idx], renormalization_factor_diff_e[band_m_idx], reference_power_fx[ts][band_m_idx], ref_e, &renormalization_factor_diff_e[band_m_idx] );
    1250      229400 :                     move32();
    1251             :                 }
    1252             :                 ELSE
    1253             :                 {
    1254           0 :                     diffuseness_m_fx[block_m_idx][band_m_idx] = diffuseness_vector_fx[band_m_idx];
    1255           0 :                     diffuseness_e[block_m_idx][band_m_idx] = 0; // Q31
    1256           0 :                     move32();
    1257           0 :                     move16();
    1258             :                 }
    1259             :             }
    1260             :         }
    1261             : 
    1262      275280 :         FOR( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ )
    1263             :         {
    1264      229400 :             Word16 max_e = MIN_16;
    1265      229400 :             move16();
    1266      917600 :             FOR( d = 0; d < DIRAC_NUM_DIMS; d++ )
    1267             :             {
    1268      688200 :                 max_e = s_max( max_e, hMcMasa->direction_vector_e[d][block_m_idx][band_m_idx] );
    1269             :             }
    1270      229400 :             max_e = add( max_e, 1 ); /*1 as guard bit to prevent overflow*/
    1271      917600 :             FOR( d = 0; d < DIRAC_NUM_DIMS; d++ )
    1272             :             {
    1273      688200 :                 dir_v_fx[d] = L_shr( hMcMasa->direction_vector_m_fx[d][block_m_idx][band_m_idx], sub( max_e, hMcMasa->direction_vector_e[d][block_m_idx][band_m_idx] ) );
    1274      688200 :                 move32();
    1275             :             }
    1276      229400 :             Word16 div_q = sub( 31, max_e );
    1277      229400 :             ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( dir_v_fx, div_q, &azimuth_m_values_fx[block_m_idx][band_m_idx], &elevation_m_values_fx[block_m_idx][band_m_idx] );
    1278             :         }
    1279             : 
    1280             :         /* Coherence processing */
    1281      275280 :         FOR( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ )
    1282             :         {
    1283             :             /* Compute absolute values */
    1284     1524300 :             FOR( i = 0; i < numAnalysisChannels; i++ )
    1285             :             {
    1286     5913000 :                 FOR( j = i; j < numAnalysisChannels; j++ )
    1287             :                 {
    1288     4618100 :                     Word32 temp = BASOP_Util_Add_Mant32Exp( Mult_32_32( COVls[band_m_idx].xr_fx[i][j], COVls[band_m_idx].xr_fx[i][j] ), shl( COVls[band_m_idx].xr_e[i][j], 1 ), Mult_32_32( COVls[band_m_idx].xi_fx[i][j], COVls[band_m_idx].xi_fx[i][j] ), shl( COVls[band_m_idx].xi_e[i][j], 1 ), &absCOVls_e[i][j] );
    1289     4618100 :                     absCOVls_fx[i][j] = Sqrt32( temp, &absCOVls_e[i][j] );
    1290     4618100 :                     move32();
    1291             :                 }
    1292     1294900 :                 lsEnergy_fx[i] = absCOVls_fx[i][i];
    1293     1294900 :                 move32();
    1294     1294900 :                 lsEnergy_e[i] = absCOVls_e[i][i];
    1295     1294900 :                 move16();
    1296             :             }
    1297             : 
    1298             :             /* Find loudest channel */
    1299      229400 :             maxEne_fx = lsEnergy_fx[0];
    1300      229400 :             move32();
    1301      229400 :             maxEne_e = lsEnergy_e[0];
    1302      229400 :             move16();
    1303      229400 :             loudestCh = 0;
    1304      229400 :             move16();
    1305     1294900 :             FOR( i = 1; i < numAnalysisChannels; i++ )
    1306             :             {
    1307     1065500 :                 IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( lsEnergy_fx[i], lsEnergy_e[i], maxEne_fx, maxEne_e ), 1 ) )
    1308             :                 {
    1309      349831 :                     maxEne_fx = lsEnergy_fx[i];
    1310      349831 :                     move32();
    1311      349831 :                     maxEne_e = lsEnergy_e[i];
    1312      349831 :                     move16();
    1313      349831 :                     loudestCh = i;
    1314      349831 :                     move16();
    1315             :                 }
    1316             :             }
    1317             : 
    1318             :             /* Compute surrounding coherence */
    1319      229400 :             surrCoh_fx = ONE_IN_Q31;
    1320      229400 :             move32();
    1321      229400 :             surrCoh_e = 0;
    1322      229400 :             move16();
    1323     1524300 :             FOR( i = 0; i < numAnalysisChannels; i++ )
    1324             :             {
    1325     1294900 :                 IF( NE_16( i, loudestCh ) )
    1326             :                 {
    1327     1065500 :                     IF( LT_16( i, loudestCh ) )
    1328             :                     {
    1329      656098 :                         i1 = i;
    1330      656098 :                         move16();
    1331      656098 :                         i2 = loudestCh;
    1332      656098 :                         move16();
    1333             :                     }
    1334             :                     ELSE
    1335             :                     {
    1336      409402 :                         i1 = loudestCh;
    1337      409402 :                         move16();
    1338      409402 :                         i2 = i;
    1339      409402 :                         move16();
    1340             :                     }
    1341     1065500 :                     Word16 temp_exp = add( lsEnergy_e[i1], lsEnergy_e[i2] );
    1342     1065500 :                     Word32 temp = Sqrt32( L_add( Mult_32_32( lsEnergy_fx[i1], lsEnergy_fx[i2] ), EPSILON_FX ), &temp_exp );
    1343     1065500 :                     tempCoh_e = 0;
    1344     1065500 :                     move16();
    1345     1065500 :                     tempCoh_fx = L_shl( BASOP_Util_Divide3232_Scale( absCOVls_fx[i1][i2], temp, &tempCoh_e ), 16 );
    1346     1065500 :                     tempCoh_e = add( sub( absCOVls_e[i1][i2], temp_exp ), tempCoh_e );
    1347     1065500 :                     IF( NE_16( BASOP_Util_Cmp_Mant32Exp( surrCoh_fx, surrCoh_e, tempCoh_fx, tempCoh_e ), -1 ) )
    1348             :                     {
    1349      453599 :                         surrCoh_fx = tempCoh_fx;
    1350      453599 :                         move32();
    1351      453599 :                         surrCoh_e = tempCoh_e;
    1352      453599 :                         move16();
    1353             :                     }
    1354             :                 }
    1355             :             }
    1356      229400 :             surrCoh_fx = L_shl( surrCoh_fx, surrCoh_e ); // Q31
    1357      229400 :             surrCoh_e = 0;
    1358      229400 :             move16();
    1359      229400 :             surrCoh_fx = Mult_32_32( surrCoh_fx, surrCoh_fx );
    1360      229400 :             IF( GE_32( surrCoh_fx, ONE_IN_Q31 ) )
    1361             :             {
    1362           0 :                 surrCoh_fx = ONE_IN_Q31;
    1363           0 :                 move32();
    1364             :             }
    1365      229400 :             surrCoh_fx = L_max( surrCoh_fx, 0 );
    1366             : 
    1367             :             /* Compute spread coherence */
    1368      229400 :             IF( LT_32( elevation_m_values_fx[block_m_idx][band_m_idx], NEAR_HORIZONTAL_PLANE_ELEVATION_FX ) ) /* Computed only near horizontal plane */
    1369             :             {
    1370      203279 :                 minAngleDist_fx = 754974720; /*180.0f Q.22*/
    1371      203279 :                 move32();
    1372      203279 :                 i1 = 0;
    1373      203279 :                 move16();
    1374      203279 :                 currentAzi_fx = azimuth_m_values_fx[block_m_idx][band_m_idx];
    1375      203279 :                 move32();
    1376     1228209 :                 FOR( i = 0; i < hMcMasa->numHorizontalChannels; i++ )
    1377             :                 {
    1378     1024930 :                     angleDist_fx = L_abs( L_sub( currentAzi_fx, hMcMasa->ls_azimuth_fx[i] ) );
    1379     1024930 :                     IF( GT_32( angleDist_fx, 754974720 /*180.0f Q.22*/ ) )
    1380             :                     {
    1381       10052 :                         angleDist_fx = L_abs( L_sub( angleDist_fx, 1509949440 /*360.0f Q.22*/ ) );
    1382             :                     }
    1383     1024930 :                     IF( LT_32( angleDist_fx, minAngleDist_fx ) )
    1384             :                     {
    1385      450443 :                         minAngleDist_fx = angleDist_fx;
    1386      450443 :                         move32();
    1387      450443 :                         i1 = i;
    1388      450443 :                         move16();
    1389             :                     }
    1390             :                 }
    1391      203279 :                 i2 = hMcMasa->leftNearest[i1];
    1392      203279 :                 move16();
    1393      203279 :                 i3 = hMcMasa->rightNearest[i1];
    1394      203279 :                 move16();
    1395      203279 :                 Word16 temp_e = add( lsEnergy_e[i2], lsEnergy_e[i3] );
    1396      203279 :                 Word32 temp = Sqrt32( L_add( Mult_32_32( lsEnergy_fx[i2], lsEnergy_fx[i3] ), EPSILON_FX ), &temp_e );
    1397      203279 :                 IF( LT_16( i2, i3 ) )
    1398             :                 {
    1399      183018 :                     stereoCoh_fx = BASOP_Util_Divide3232_Scale( absCOVls_fx[i2][i3], temp, &stereoCoh_e );
    1400      183018 :                     stereoCoh_e = add( sub( absCOVls_e[i2][i3], temp_e ), stereoCoh_e );
    1401             :                 }
    1402             :                 ELSE
    1403             :                 {
    1404       20261 :                     stereoCoh_fx = BASOP_Util_Divide3232_Scale( absCOVls_fx[i3][i2], temp, &stereoCoh_e );
    1405       20261 :                     stereoCoh_e = add( sub( absCOVls_e[i3][i2], temp_e ), stereoCoh_e );
    1406             :                 }
    1407      203279 :                 stereoCoh_fx = L_shl( stereoCoh_fx, 16 );
    1408             :                 Word32 temp1, temp2;
    1409             :                 Word16 temp1_e, temp2_e;
    1410      203279 :                 temp1 = BASOP_Util_Add_Mant32Exp( lsEnergy_fx[i2], lsEnergy_e[i2], lsEnergy_fx[i3], lsEnergy_e[i3], &temp1_e );
    1411      203279 :                 temp2 = BASOP_Util_Add_Mant32Exp( temp1, temp1_e, lsEnergy_fx[i1], lsEnergy_e[i1], &temp2_e );
    1412      203279 :                 temp2 = L_add( temp2, EPSILON_FX );
    1413      203279 :                 lsEnergyRelation_fx = BASOP_Util_Divide3232_Scale( temp1, temp2, &lsEnergyRelation_e );
    1414      203279 :                 lsEnergyRelation_e = add( lsEnergyRelation_e, sub( temp1_e, temp2_e ) );
    1415      203279 :                 lsEnergyRelation_fx = L_shl_sat( lsEnergyRelation_fx, add( 16, lsEnergyRelation_e ) );
    1416      203279 :                 stereoness_fx = Mult_32_32( stereoCoh_fx, lsEnergyRelation_fx );
    1417      203279 :                 stereoness_e = stereoCoh_e;
    1418      203279 :                 move16();
    1419             : 
    1420      203279 :                 IF( LT_16( i1, i2 ) )
    1421             :                 {
    1422       95808 :                     temp_e = add( lsEnergy_e[i1], lsEnergy_e[i2] );
    1423       95808 :                     tempCoh_fx = BASOP_Util_Divide3232_Scale( absCOVls_fx[i1][i2], ( Sqrt32( L_add( Mult_32_32( lsEnergy_fx[i1], lsEnergy_fx[i2] ), EPSILON_FX ), &temp_e ) ), &tempCoh_e );
    1424       95808 :                     tempCoh_e = add( tempCoh_e, sub( absCOVls_e[i1][i2], temp_e ) );
    1425             :                 }
    1426             :                 ELSE
    1427             :                 {
    1428      107471 :                     temp_e = add( lsEnergy_e[i1], lsEnergy_e[i2] );
    1429      107471 :                     tempCoh_fx = BASOP_Util_Divide3232_Scale( absCOVls_fx[i2][i1], ( Sqrt32( L_add( Mult_32_32( lsEnergy_fx[i1], lsEnergy_fx[i2] ), EPSILON_FX ), &temp_e ) ), &tempCoh_e );
    1430      107471 :                     tempCoh_e = add( tempCoh_e, sub( absCOVls_e[i2][i1], temp_e ) );
    1431             :                 }
    1432      203279 :                 tempCoh_fx = L_shl( tempCoh_fx, 16 );
    1433      203279 :                 IF( LT_16( i1, i3 ) )
    1434             :                 {
    1435       95789 :                     temp_e = add( lsEnergy_e[i1], lsEnergy_e[i3] );
    1436       95789 :                     tempCoh2_fx = BASOP_Util_Divide3232_Scale( absCOVls_fx[i1][i3], ( Sqrt32( L_add( Mult_32_32( lsEnergy_fx[i1], lsEnergy_fx[i3] ), EPSILON_FX ), &temp_e ) ), &tempCoh2_e );
    1437       95789 :                     tempCoh2_e = add( tempCoh2_e, sub( absCOVls_e[i1][i3], temp_e ) );
    1438             :                 }
    1439             :                 ELSE
    1440             :                 {
    1441      107490 :                     temp_e = add( lsEnergy_e[i1], lsEnergy_e[i3] );
    1442      107490 :                     tempCoh2_fx = BASOP_Util_Divide3232_Scale( absCOVls_fx[i3][i1], ( Sqrt32( L_add( Mult_32_32( lsEnergy_fx[i1], lsEnergy_fx[i3] ), EPSILON_FX ), &temp_e ) ), &tempCoh2_e );
    1443      107490 :                     tempCoh2_e = add( tempCoh2_e, sub( absCOVls_e[i3][i1], temp_e ) );
    1444             :                 }
    1445      203279 :                 tempCoh2_fx = L_shl( tempCoh2_fx, 16 );
    1446      203279 :                 IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( tempCoh_fx, tempCoh_e, tempCoh2_fx, tempCoh2_e ), -1 ) )
    1447             :                 {
    1448      104786 :                     cohPanCoh_fx = tempCoh_fx;
    1449      104786 :                     move32();
    1450      104786 :                     cohPanCoh_e = tempCoh_e;
    1451      104786 :                     move16();
    1452             :                 }
    1453             :                 ELSE
    1454             :                 {
    1455       98493 :                     cohPanCoh_fx = tempCoh2_fx;
    1456       98493 :                     move32();
    1457       98493 :                     cohPanCoh_e = tempCoh2_e;
    1458       98493 :                     move16();
    1459             :                 }
    1460             :                 /* IF( GT_32( cohPanCoh_fx, ONE_IN_Q30 ) )
    1461             :                  {
    1462             :                      cohPanCoh_fx = ONE_IN_Q30;
    1463             :                      move32();
    1464             :                  }*/
    1465      203279 :                 cohPanCoh_fx = L_shl_sat( cohPanCoh_fx, cohPanCoh_e ); /*Q31*/
    1466      203279 :                 cohPanCoh_e = 0;
    1467      203279 :                 move16();
    1468      203279 :                 lsEnergyRelation_fx = BASOP_Util_Divide3232_Scale( lsEnergy_fx[i2], L_add( lsEnergy_fx[i1], EPSILON_FX ), &lsEnergyRelation_e );
    1469      203279 :                 lsEnergyRelation_e = add( lsEnergyRelation_e, sub( lsEnergy_e[i2], lsEnergy_e[i1] ) );
    1470      203279 :                 tempLsEnergyRelation_fx = BASOP_Util_Divide3232_Scale( lsEnergy_fx[i1], L_add( lsEnergy_fx[i2], EPSILON_FX ), &tempLsEnergyRelation_e );
    1471      203279 :                 tempLsEnergyRelation_e = add( tempLsEnergyRelation_e, sub( lsEnergy_e[i1], lsEnergy_e[i2] ) );
    1472      203279 :                 IF( NE_16( BASOP_Util_Cmp_Mant32Exp( lsEnergyRelation_fx, lsEnergyRelation_e, tempLsEnergyRelation_fx, tempLsEnergyRelation_e ), -1 ) )
    1473             :                 {
    1474      101468 :                     lsEnergyRelation_fx = tempLsEnergyRelation_fx;
    1475      101468 :                     move32();
    1476      101468 :                     lsEnergyRelation_e = tempLsEnergyRelation_e;
    1477      101468 :                     move16();
    1478             :                 }
    1479      203279 :                 tempLsEnergyRelation_fx = BASOP_Util_Divide3232_Scale( lsEnergy_fx[i3], L_add( lsEnergy_fx[i1], EPSILON_FX ), &tempLsEnergyRelation_e );
    1480      203279 :                 tempLsEnergyRelation_e = add( tempLsEnergyRelation_e, sub( lsEnergy_e[i3], lsEnergy_e[i1] ) );
    1481      203279 :                 IF( NE_16( BASOP_Util_Cmp_Mant32Exp( lsEnergyRelation_fx, lsEnergyRelation_e, tempLsEnergyRelation_fx, tempLsEnergyRelation_e ), -1 ) )
    1482             :                 {
    1483       22822 :                     lsEnergyRelation_fx = tempLsEnergyRelation_fx;
    1484       22822 :                     move32();
    1485       22822 :                     lsEnergyRelation_e = tempLsEnergyRelation_e;
    1486       22822 :                     move16();
    1487             :                 }
    1488      203279 :                 tempLsEnergyRelation_fx = BASOP_Util_Divide3232_Scale( lsEnergy_fx[i1], L_add( lsEnergy_fx[i3], EPSILON_FX ), &tempLsEnergyRelation_e );
    1489      203279 :                 tempLsEnergyRelation_e = add( tempLsEnergyRelation_e, sub( lsEnergy_e[i1], lsEnergy_e[i3] ) );
    1490      203279 :                 IF( NE_16( BASOP_Util_Cmp_Mant32Exp( lsEnergyRelation_fx, lsEnergyRelation_e, tempLsEnergyRelation_fx, tempLsEnergyRelation_e ), -1 ) )
    1491             :                 {
    1492       60087 :                     lsEnergyRelation_fx = tempLsEnergyRelation_fx;
    1493       60087 :                     move32();
    1494       60087 :                     lsEnergyRelation_e = tempLsEnergyRelation_e;
    1495       60087 :                     move16();
    1496             :                 }
    1497      203279 :                 lsEnergyRelation_fx = L_shl_sat( lsEnergyRelation_fx, add( 16, lsEnergyRelation_e ) ); /*Q31*/
    1498      203279 :                 cohwideness_fx = Mult_32_32( cohPanCoh_fx, lsEnergyRelation_fx );
    1499      203279 :                 IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( cohwideness_fx, cohPanCoh_e, stereoness_fx, stereoness_e ), 1 ) )
    1500             :                 {
    1501       32464 :                     spreadCoh_fx = cohwideness_fx;
    1502       32464 :                     move32();
    1503       32464 :                     spreadCoh_e = cohPanCoh_e;
    1504       32464 :                     move16();
    1505             :                 }
    1506             :                 ELSE
    1507             :                 {
    1508      170815 :                     spreadCoh_fx = stereoness_fx;
    1509      170815 :                     move32();
    1510      170815 :                     spreadCoh_e = stereoness_e;
    1511      170815 :                     move16();
    1512             :                 }
    1513      203279 :                 IF( ( spreadCoh_e < 0 ) )
    1514             :                 {
    1515        5425 :                     spreadCoh_fx = L_shl( spreadCoh_fx, spreadCoh_e );
    1516        5425 :                     spreadCoh_e = 0;
    1517        5425 :                     move16();
    1518             :                 }
    1519      203279 :                 IF( GT_32( spreadCoh_fx, L_shl_sat( 1, sub( 30, spreadCoh_e ) /*0.5f with exp=spreadCoh_e*/ ) ) )
    1520             :                 {
    1521      128438 :                     IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( cohwideness_fx, cohPanCoh_e, stereoness_fx, stereoness_e ), 1 ) )
    1522             :                     {
    1523       21850 :                         tempCoh_fx = BASOP_Util_Add_Mant32Exp( stereoness_fx, stereoness_e, L_negate( L_sub( cohwideness_fx, L_shl( 1, sub( 30, cohPanCoh_e ) ) ) ), cohPanCoh_e, &tempCoh_e );
    1524       21850 :                         IF( ( tempCoh_e < 0 ) )
    1525             :                         {
    1526       21850 :                             tempCoh_fx = L_shl( tempCoh_fx, tempCoh_e ); // Q31
    1527       21850 :                             tempCoh_e = 0;
    1528       21850 :                             move16();
    1529             :                         }
    1530       21850 :                         IF( GT_32( tempCoh_fx, L_shl_sat( 1, sub( 30, tempCoh_e ) ) ) )
    1531             :                         {
    1532           0 :                             spreadCoh_fx = tempCoh_fx; // tempCoh_e
    1533           0 :                             move32();
    1534             :                         }
    1535             :                         ELSE
    1536             :                         {
    1537       21850 :                             spreadCoh_fx = L_shl_sat( 1, sub( 30, tempCoh_e ) ); // Q30
    1538             :                         }
    1539       21850 :                         spreadCoh_e = tempCoh_e;
    1540       21850 :                         move16();
    1541             :                     }
    1542             :                 }
    1543      203279 :                 IF( ( spreadCoh_e < 0 ) )
    1544             :                 {
    1545           0 :                     spreadCoh_fx = L_shl( spreadCoh_fx, spreadCoh_e ); // Q31
    1546           0 :                     spreadCoh_e = 0;
    1547           0 :                     move16();
    1548             :                 }
    1549             : 
    1550      203279 :                 IF( ( GE_32( spreadCoh_fx, L_shl_sat( 1, sub( 31, spreadCoh_e ) ) ) ) )
    1551             :                 {
    1552           0 :                     spreadCoh_fx = L_shl_sat( 1, sub( 31, spreadCoh_e ) ); // Q31
    1553             :                 }
    1554      203279 :                 IF( ( spreadCoh_fx <= 0 ) )
    1555             :                 {
    1556        1385 :                     spreadCoh_fx = 0;
    1557        1385 :                     move32();
    1558             :                 }
    1559      203279 :                 spreadCoh_fx = L_shl( spreadCoh_fx, sub( spreadCoh_e, 1 ) ); /*Q30*/
    1560             : 
    1561             :                 /* Compute energy ratio tuning parameter */
    1562      203279 :                 lsEnergySum_fx = 0;
    1563      203279 :                 move32();
    1564      203279 :                 lsEnergySum_e = 0;
    1565      203279 :                 move16();
    1566     1241837 :                 FOR( i = 0; i < numAnalysisChannels; i++ )
    1567             :                 {
    1568     1038558 :                     lsEnergySum_fx = BASOP_Util_Add_Mant32Exp( lsEnergy_fx[i], lsEnergy_e[i], lsEnergySum_fx, lsEnergySum_e, &lsEnergySum_e );
    1569             :                 }
    1570      203279 :                 lsEnergySum_fx = L_add_sat( lsEnergySum_fx, EPSILON_FX );
    1571      203279 :                 lsEnergyRelation_fx = BASOP_Util_Divide3232_Scale( temp1, lsEnergySum_fx, &lsEnergyRelation_e );
    1572      203279 :                 lsEnergyRelation_e = add( lsEnergyRelation_e, sub( temp1_e, lsEnergySum_e ) );
    1573      203279 :                 lsEnergyRelation_fx = L_shl_sat( lsEnergyRelation_fx, add( 16, lsEnergyRelation_e ) );                           // Q31
    1574      203279 :                 stereoRatio_fx = L_sub( Mult_32_32( L_shl_sat( stereoCoh_fx, stereoCoh_e ), lsEnergyRelation_fx ), surrCoh_fx ); // Q31
    1575             : 
    1576      203279 :                 temp2 = L_sub( temp2, EPSILLON_FX );
    1577      203279 :                 lsEnergyRelation_fx = BASOP_Util_Divide3232_Scale( temp2, lsEnergySum_fx, &lsEnergyRelation_e );
    1578      203279 :                 lsEnergyRelation_e = add( lsEnergyRelation_e, sub( temp2_e, lsEnergySum_e ) );
    1579      203279 :                 lsEnergyRelation_fx = L_shl_sat( lsEnergyRelation_fx, add( 16, lsEnergyRelation_e ) ); // Q31
    1580      203279 :                 cohPanRatio_fx = L_sub( Mult_32_32( cohPanCoh_fx, lsEnergyRelation_fx ), surrCoh_fx ); // Q31
    1581      203279 :                 IF( GT_32( stereoRatio_fx, cohPanRatio_fx ) )
    1582             :                 {
    1583        3970 :                     cohRatio_fx = stereoRatio_fx;
    1584        3970 :                     move32();
    1585             :                 }
    1586             :                 ELSE
    1587             :                 {
    1588      199309 :                     cohRatio_fx = cohPanRatio_fx;
    1589      199309 :                     move32();
    1590             :                 }
    1591             : 
    1592      203279 :                 IF( GE_32( cohRatio_fx, ONE_IN_Q31 ) )
    1593             :                 {
    1594           0 :                     cohRatio_fx = ONE_IN_Q31; // Q31
    1595           0 :                     move32();
    1596             :                 }
    1597      203279 :                 IF( cohRatio_fx <= 0 )
    1598             :                 {
    1599       91308 :                     cohRatio_fx = 0;
    1600       91308 :                     move32();
    1601             :                 }
    1602             :             }
    1603             :             ELSE /* Otherwise, set spread coherence to zero */
    1604             :             {
    1605       26121 :                 spreadCoh_fx = 0;
    1606       26121 :                 move32();
    1607       26121 :                 cohRatio_fx = 0;
    1608       26121 :                 move32();
    1609       26121 :                 lsEnergySum_fx = 0;
    1610       26121 :                 move32();
    1611      282463 :                 FOR( i = 0; i < numAnalysisChannels; i++ )
    1612             :                 {
    1613      256342 :                     lsEnergySum_fx = BASOP_Util_Add_Mant32Exp( lsEnergy_fx[i], lsEnergy_e[i], lsEnergySum_fx, lsEnergySum_e, &lsEnergySum_e );
    1614             :                 }
    1615       26121 :                 lsEnergySum_fx = L_add_sat( lsEnergySum_fx, EPSILON_FX );
    1616             :             }
    1617             : 
    1618             :             /* Store values */
    1619      229400 :             spreadCoherence_fx[block_m_idx][band_m_idx] = spreadCoh_fx; /*Q30*/
    1620      229400 :             move32();
    1621             : 
    1622      229400 :             IF( hMcMasa->combineRatios )
    1623             :             {
    1624      229400 :                 surroundingCoherence_fx[0][band_m_idx] = BASOP_Util_Add_Mant32Exp( surroundingCoherence_fx[0][band_m_idx], surroundingCoherence_e[0][band_m_idx], Mult_32_32( lsEnergySum_fx, surrCoh_fx ), lsEnergySum_e, &surroundingCoherence_e[0][band_m_idx] );
    1625      229400 :                 move32();
    1626      229400 :                 coherentEnergyRatio_fx[0][band_m_idx] = BASOP_Util_Add_Mant32Exp( coherentEnergyRatio_fx[0][band_m_idx], coherentEnergyRatio_e[0][band_m_idx], Mult_32_32( lsEnergySum_fx, cohRatio_fx ), lsEnergySum_e, &coherentEnergyRatio_e[0][band_m_idx] );
    1627      229400 :                 move32();
    1628      229400 :                 renormalization_factor_coh_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( renormalization_factor_coh_fx[band_m_idx], renormalization_factor_coh_e[band_m_idx], lsEnergySum_fx, lsEnergySum_e, &renormalization_factor_coh_e[band_m_idx] );
    1629      229400 :                 move32();
    1630             :             }
    1631             :             ELSE
    1632             :             {
    1633           0 :                 surroundingCoherence_fx[block_m_idx][band_m_idx] = surrCoh_fx; // Q31
    1634           0 :                 move32();
    1635           0 :                 coherentEnergyRatio_fx[block_m_idx][band_m_idx] = cohRatio_fx; // Q31
    1636           0 :                 move32();
    1637             :             }
    1638             :         }
    1639             :     }
    1640             : 
    1641       11470 :     IF( hMcMasa->combineRatios )
    1642             :     {
    1643       68820 :         FOR( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ )
    1644             :         {
    1645             :             Word16 diffuseness_m_e;
    1646       57350 :             IF( GT_32( renormalization_factor_diff_fx[band_m_idx], EPSILON_FX ) )
    1647             :             {
    1648       57350 :                 diffuseness_m_fx[0][band_m_idx] = BASOP_Util_Divide3232_Scale( diffuseness_m_fx[0][band_m_idx], renormalization_factor_diff_fx[band_m_idx], &diffuseness_m_e );
    1649       57350 :                 move32();
    1650       57350 :                 diffuseness_m_e = add( diffuseness_m_e, sub( diffuseness_e[0][band_m_idx], renormalization_factor_diff_e[band_m_idx] ) );
    1651       57350 :                 diffuseness_m_fx[0][band_m_idx] = L_shl_sat( diffuseness_m_fx[0][band_m_idx], add( 16, diffuseness_m_e ) ); // Q(31 - diffuseness_m_e) -> Q31
    1652       57350 :                 move32();
    1653             :             }
    1654             :             ELSE
    1655             :             {
    1656           0 :                 diffuseness_m_fx[0][band_m_idx] = 0;
    1657           0 :                 move32();
    1658             :             }
    1659       57350 :             IF( GT_32( renormalization_factor_coh_fx[band_m_idx], EPSILON_FX ) )
    1660             :             {
    1661       57350 :                 Word16 cer_e = 31, sc_e = 31;
    1662       57350 :                 move16();
    1663       57350 :                 move16();
    1664       57350 :                 surroundingCoherence_fx[0][band_m_idx] = BASOP_Util_Divide3232_Scale( surroundingCoherence_fx[0][band_m_idx], renormalization_factor_coh_fx[band_m_idx], &sc_e );
    1665       57350 :                 move32();
    1666       57350 :                 sc_e = add( sc_e, sub( surroundingCoherence_e[0][band_m_idx], renormalization_factor_coh_e[band_m_idx] ) );
    1667       57350 :                 surroundingCoherence_fx[0][band_m_idx] = L_shl_sat( surroundingCoherence_fx[0][band_m_idx], add( 16, sc_e ) ); // Q(31 - sc_e) -> Q31
    1668       57350 :                 move32();
    1669       57350 :                 coherentEnergyRatio_fx[0][band_m_idx] = BASOP_Util_Divide3232_Scale( coherentEnergyRatio_fx[0][band_m_idx], renormalization_factor_coh_fx[band_m_idx], &cer_e );
    1670       57350 :                 move32();
    1671       57350 :                 cer_e = add( cer_e, sub( coherentEnergyRatio_e[0][band_m_idx], renormalization_factor_coh_e[band_m_idx] ) );
    1672       57350 :                 coherentEnergyRatio_fx[0][band_m_idx] = L_shl_sat( coherentEnergyRatio_fx[0][band_m_idx], add( 16, cer_e ) ); // Q(31 - cer_e) -> Q31
    1673       57350 :                 move32();
    1674             :             }
    1675             :             ELSE
    1676             :             {
    1677           0 :                 surroundingCoherence_fx[0][band_m_idx] = 0;
    1678           0 :                 move32();
    1679           0 :                 coherentEnergyRatio_fx[0][band_m_idx] = 0;
    1680           0 :                 move32();
    1681             :             }
    1682             :         }
    1683             :     }
    1684             : 
    1685             :     /* Determine energy ratios */
    1686       11470 :     IF( hMcMasa->combineRatios )
    1687             :     {
    1688       11470 :         numSubFramesForRatio = 1;
    1689       11470 :         move16();
    1690             :     }
    1691             :     ELSE
    1692             :     {
    1693           0 :         numSubFramesForRatio = MAX_PARAM_SPATIAL_SUBFRAMES;
    1694           0 :         move16();
    1695             :     }
    1696             : 
    1697       22940 :     FOR( i = 0; i < numSubFramesForRatio; i++ )
    1698             :     {
    1699       68820 :         FOR( j = 0; j < hMcMasa->nbands; j++ )
    1700             :         {
    1701       57350 :             energyRatio_fx[i][j] = L_sub( ONE_IN_Q31, diffuseness_m_fx[i][j] ); // Q31
    1702       57350 :             move32();
    1703       57350 :             IF( GT_32( energyRatio_fx[i][j], coherentEnergyRatio_fx[i][j] ) )
    1704             :             {
    1705       53860 :                 energyRatio_fx[i][j] = energyRatio_fx[i][j];
    1706       53860 :                 move32();
    1707             :             }
    1708             :             ELSE
    1709             :             {
    1710        3490 :                 energyRatio_fx[i][j] = coherentEnergyRatio_fx[i][j]; // Q31
    1711        3490 :                 move32();
    1712             :             }
    1713             :         }
    1714             :     }
    1715             : 
    1716       11470 :     return;
    1717             : }
    1718             : 
    1719             : 
    1720             : /*--------------------------------------------------------------------------*
    1721             :  * ivas_mcmasa_dmx_modify()
    1722             :  *
    1723             :  *
    1724             :  *--------------------------------------------------------------------------*/
    1725             : 
    1726          39 : void ivas_mcmasa_dmx_modify_fx(
    1727             :     const Word16 n_samples,                                             /* i  : input frame length in samples                        */
    1728             :     Word32 dmx_fx[][L_FRAME48k + NS2SA( 48000, IVAS_FB_ENC_DELAY_NS )], /* i/o: downmix signal to be transformed into another format Qx*/
    1729             :     Word16 dmx_Q[],                                                     /* i/o : Q of the intput signal which is being transformed*/
    1730             :     const Word16 n_chnls_dmx_old,                                       /* i  : number of downmix channels in the old format        Q0 */
    1731             :     const Word16 n_chnls_dmx_new )                                      /* i  : number of downmix channels in the target format      Q0*/
    1732             : {
    1733             :     /* assumed data ordering in **dmx: [sce][cpe_chnl0][cpe_chnl1], i.e., [c][l][r] */
    1734             :     Word16 i;
    1735             : 
    1736          39 :     assert( ( n_chnls_dmx_old == 1 || n_chnls_dmx_old == 2 || n_chnls_dmx_old == 3 ) && "Input downmix may contain only 1-3 channels." );
    1737          39 :     assert( ( n_chnls_dmx_new == 1 || n_chnls_dmx_new == 2 || n_chnls_dmx_new == 3 ) && "Output downmix may contain only 1-3 channels." );
    1738             : 
    1739          39 :     IF( EQ_16( n_chnls_dmx_old, n_chnls_dmx_new ) )
    1740             :     {
    1741             :         /* same dmx layout -> nothing to do */
    1742           0 :         return;
    1743             :     }
    1744             : 
    1745             :     Word16 Q_min_1_2, Q_min_0_1_2;
    1746             : 
    1747          39 :     Q_min_1_2 = s_min( dmx_Q[1], dmx_Q[2] );
    1748          39 :     Q_min_0_1_2 = s_min( dmx_Q[1], s_min( dmx_Q[2], dmx_Q[0] ) );
    1749             : 
    1750          39 :     IF( EQ_16( n_chnls_dmx_old, 1 ) )
    1751             :     {
    1752             :         /* split mono energy into identical channels */
    1753       17298 :         FOR( i = 0; i < n_samples; i++ )
    1754             :         {
    1755       17280 :             IF( EQ_16( n_chnls_dmx_new, 2 ) )
    1756             :             {
    1757        5760 :                 dmx_fx[1][i] = Mpy_32_16_1( dmx_fx[0][i], INV_SQRT2_FX_Q15 ); // dmx_q + Q15 - 15
    1758        5760 :                 dmx_fx[2][i] = dmx_fx[1][i];
    1759        5760 :                 move32();
    1760        5760 :                 move32();
    1761             :             }
    1762       11520 :             ELSE IF( EQ_16( n_chnls_dmx_new, 3 ) )
    1763             :             {
    1764       11520 :                 dmx_fx[0][i] = Mpy_32_16_1( dmx_fx[0][i], INV_SQRT3_FX ); // dmx_q + Q15 - 15
    1765       11520 :                 move32();
    1766             :             }
    1767             :         }
    1768             :     }
    1769          21 :     ELSE IF( EQ_16( n_chnls_dmx_old, 2 ) )
    1770             :     {
    1771        9610 :         FOR( i = 0; i < n_samples; i++ )
    1772             :         {
    1773        9600 :             IF( EQ_16( n_chnls_dmx_new, 1 ) )
    1774             :             {
    1775             :                 /* sum l and r */
    1776        6720 :                 dmx_fx[1][i] = L_shl( dmx_fx[1][i], sub( Q_min_1_2, dmx_Q[1] ) );
    1777        6720 :                 dmx_fx[2][i] = L_shl( dmx_fx[2][i], sub( Q_min_1_2, dmx_Q[2] ) );
    1778        6720 :                 move32();
    1779        6720 :                 move32();
    1780             : 
    1781        6720 :                 dmx_fx[0][i] = L_add( dmx_fx[1][i], dmx_fx[2][i] ); // dmx_q
    1782        6720 :                 move32();
    1783             :             }
    1784        2880 :             ELSE IF( EQ_16( n_chnls_dmx_new, 3 ) )
    1785             :             {
    1786        2880 :                 dmx_fx[1][i] = L_shl( dmx_fx[1][i], sub( Q_min_1_2, dmx_Q[1] ) );
    1787        2880 :                 dmx_fx[2][i] = L_shl( dmx_fx[2][i], sub( Q_min_1_2, dmx_Q[2] ) );
    1788        2880 :                 move32();
    1789        2880 :                 move32();
    1790             : 
    1791        2880 :                 dmx_fx[0][i] = L_shr( L_add( dmx_fx[1][i], dmx_fx[2][i] ), 1 );
    1792        2880 :                 dmx_fx[1][i] = L_sub( dmx_fx[1][i], dmx_fx[0][i] ); // dmx_q
    1793        2880 :                 dmx_fx[2][i] = L_sub( dmx_fx[2][i], dmx_fx[0][i] ); // dmx_q
    1794        2880 :                 move32();
    1795        2880 :                 move32();
    1796        2880 :                 move32();
    1797             :             }
    1798             :         }
    1799             :     }
    1800          11 :     ELSE IF( EQ_16( n_chnls_dmx_old, 3 ) )
    1801             :     {
    1802       10571 :         FOR( i = 0; i < n_samples; i++ )
    1803             :         {
    1804       10560 :             IF( EQ_16( n_chnls_dmx_new, 1 ) )
    1805             :             {
    1806             :                 /* sum all channels */
    1807             : 
    1808        6720 :                 dmx_fx[0][i] = L_shl( dmx_fx[0][i], sub( Q_min_0_1_2, dmx_Q[1] ) );
    1809        6720 :                 dmx_fx[1][i] = L_shl( dmx_fx[1][i], sub( Q_min_0_1_2, dmx_Q[1] ) );
    1810        6720 :                 dmx_fx[2][i] = L_shl( dmx_fx[2][i], sub( Q_min_0_1_2, dmx_Q[2] ) );
    1811        6720 :                 move32();
    1812        6720 :                 move32();
    1813        6720 :                 move32();
    1814             : 
    1815        6720 :                 dmx_fx[0][i] = L_add( L_add( dmx_fx[0][i], dmx_fx[1][i] ), dmx_fx[2][i] );
    1816        6720 :                 move32();
    1817             :             }
    1818        3840 :             ELSE IF( EQ_16( n_chnls_dmx_new, 2 ) )
    1819             :             {
    1820             : 
    1821        3840 :                 dmx_fx[0][i] = L_shl( dmx_fx[0][i], sub( Q_min_0_1_2, dmx_Q[1] ) );
    1822        3840 :                 dmx_fx[1][i] = L_shl( dmx_fx[1][i], sub( Q_min_0_1_2, dmx_Q[1] ) );
    1823        3840 :                 dmx_fx[2][i] = L_shl( dmx_fx[2][i], sub( Q_min_0_1_2, dmx_Q[2] ) );
    1824        3840 :                 move32();
    1825        3840 :                 move32();
    1826        3840 :                 move32();
    1827             : 
    1828             :                 /* mix center into sides */
    1829        3840 :                 dmx_fx[0][i] = Mpy_32_16_1( dmx_fx[0][i], INV_SQRT2_FX_Q15 );
    1830        3840 :                 dmx_fx[1][i] = L_add( dmx_fx[1][i], dmx_fx[0][i] ); // dmx_q
    1831        3840 :                 dmx_fx[2][i] = L_add( dmx_fx[2][i], dmx_fx[0][i] ); // dmx_q
    1832        3840 :                 move32();
    1833        3840 :                 move32();
    1834        3840 :                 move32();
    1835             :             }
    1836             :         }
    1837             :     }
    1838             : 
    1839             :     // Q updation for different channels
    1840             : 
    1841          39 :     IF( EQ_16( n_chnls_dmx_old, 1 ) )
    1842             :     {
    1843             :         /* split mono energy into identical channels */
    1844          18 :         IF( EQ_16( n_chnls_dmx_new, 2 ) )
    1845             :         {
    1846           6 :             dmx_Q[1] = dmx_Q[0];
    1847           6 :             move16();
    1848           6 :             dmx_Q[2] = dmx_Q[0];
    1849           6 :             move16();
    1850             :         }
    1851             :     }
    1852          21 :     ELSE IF( EQ_16( n_chnls_dmx_old, 2 ) )
    1853             :     {
    1854          10 :         dmx_Q[0] = Q_min_1_2;
    1855          10 :         move16();
    1856          10 :         dmx_Q[1] = Q_min_1_2;
    1857          10 :         move16();
    1858          10 :         dmx_Q[2] = Q_min_1_2;
    1859          10 :         move16();
    1860             :     }
    1861          11 :     ELSE IF( EQ_16( n_chnls_dmx_old, 3 ) )
    1862             :     {
    1863          11 :         dmx_Q[0] = Q_min_0_1_2;
    1864          11 :         move16();
    1865          11 :         dmx_Q[1] = Q_min_0_1_2;
    1866          11 :         move16();
    1867          11 :         dmx_Q[2] = Q_min_0_1_2;
    1868          11 :         move16();
    1869             :     }
    1870             : 
    1871             : 
    1872          39 :     return;
    1873             : }
    1874             : 
    1875             : 
    1876             : /*--------------------------------------------------------------------------*
    1877             :  * Local functions
    1878             :  *--------------------------------------------------------------------------*/
    1879             : /* Compute downmix */
    1880       11470 : static void ivas_mcmasa_dmx_fx(
    1881             :     MCMASA_ENC_HANDLE hMcMasa,
    1882             :     Word32 *data_fx[], // Q(31 - data_e)
    1883             :     Word16 data_e,
    1884             :     const Word16 input_frame,
    1885             :     const Word16 nchan_transport,
    1886             :     const Word16 nchan_inp )
    1887             : {
    1888             :     Word16 i, j;
    1889             :     Word16 numAnalysisChannels;
    1890             :     Word32 dmx_c_fx;
    1891             :     Word32 multiChEne_fx, downmixEne_fx;
    1892             :     Word32 prevEQ_fx, currEQ_fx, instEQ_fx;
    1893             :     Word32 alpha_fx, L_tmp, L_tmp1;
    1894       11470 :     Word16 multiChEne_e, scale, downmixEne_e = 0, prevEQ_e, tmp, currEQ_e, instEQ_e;
    1895       11470 :     move16();
    1896             : 
    1897       11470 :     numAnalysisChannels = sub( nchan_inp, 1 );
    1898       11470 :     IF( hMcMasa->separateChannelEnabled )
    1899             :     {
    1900         625 :         numAnalysisChannels = sub( nchan_inp, 2 );
    1901             :     }
    1902             : 
    1903       11470 :     multiChEne_fx = 0;
    1904       11470 :     move32();
    1905       11470 :     multiChEne_e = 0;
    1906       11470 :     move16();
    1907       76215 :     FOR( j = 0; j < numAnalysisChannels; j++ )
    1908             :     {
    1909    61899945 :         FOR( i = 0; i < input_frame; i++ )
    1910             :         {
    1911    61835200 :             L_tmp1 = BASOP_Util_Add_Mant32Exp( data_fx[j][i], data_e, 0, 0, &scale );
    1912    61835200 :             L_tmp = Mpy_32_32( L_tmp1, L_tmp1 ); // data_e + data_e
    1913    61835200 :             multiChEne_fx = BASOP_Util_Add_Mant32Exp( L_tmp, scale + scale, multiChEne_fx, multiChEne_e, &scale );
    1914    61835200 :             multiChEne_e = scale;
    1915    61835200 :             move16();
    1916             :         }
    1917             :     }
    1918             : 
    1919       11470 :     IF( EQ_16( nchan_transport, 2 ) )
    1920             :     {
    1921             :         Word16 numSideChannels; /* Channels other than left, right, center */
    1922             :         Word16 leftIndex, rightIndex;
    1923             : 
    1924        1045 :         numSideChannels = sub( shr( numAnalysisChannels, 1 ), 1 );
    1925        5045 :         FOR( j = 0; j < numSideChannels; j++ )
    1926             :         {
    1927        4000 :             IF( hMcMasa->separateChannelEnabled )
    1928             :             {
    1929        2480 :                 leftIndex = add( shl( j, 1 ), 2 );
    1930        2480 :                 rightIndex = add( shl( j, 1 ), 3 );
    1931             :             }
    1932             :             ELSE
    1933             :             {
    1934        1520 :                 leftIndex = add( shl( j, 1 ), 3 );
    1935        1520 :                 rightIndex = add( shl( j, 1 ), 4 );
    1936             :             }
    1937             : 
    1938     3844000 :             FOR( i = 0; i < input_frame; i++ )
    1939             :             {
    1940     3840000 :                 data_fx[0][i] = L_add( data_fx[0][i], data_fx[leftIndex][i] ); // data_e
    1941     3840000 :                 move32();
    1942     3840000 :                 data_fx[1][i] = L_add( data_fx[1][i], data_fx[rightIndex][i] );
    1943     3840000 :                 move32();
    1944             :             }
    1945             :         }
    1946             : 
    1947        1045 :         IF( !hMcMasa->separateChannelEnabled )
    1948             :         {
    1949      403620 :             FOR( i = 0; i < input_frame; i++ )
    1950             :             {
    1951      403200 :                 dmx_c_fx = W_extract_h( W_mult_32_32( INV_SQRT2_FX, data_fx[2][i] ) );
    1952      403200 :                 move32();
    1953      403200 :                 data_fx[0][i] = L_add( dmx_c_fx, data_fx[0][i] ); // data_e
    1954      403200 :                 move32();
    1955      403200 :                 data_fx[1][i] = L_add( dmx_c_fx, data_fx[1][i] ); // data_e
    1956      403200 :                 move32();
    1957             :             }
    1958             :         }
    1959             :     }
    1960       10425 :     ELSE IF( EQ_16( nchan_transport, 1 ) )
    1961             :     {
    1962     9954425 :         FOR( i = 0; i < input_frame; i++ )
    1963             :         {
    1964    51745600 :             FOR( j = 1; j < numAnalysisChannels; j++ )
    1965             :             {
    1966    41801600 :                 data_fx[0][i] = L_add( data_fx[0][i], data_fx[j][i] );
    1967    41801600 :                 move32();
    1968             :             }
    1969             :         }
    1970             :     }
    1971       11470 :     downmixEne_fx = 0;
    1972       11470 :     move32();
    1973       23985 :     FOR( j = 0; j < nchan_transport; j++ )
    1974             :     {
    1975    11962915 :         FOR( i = 0; i < input_frame; i++ )
    1976             :         {
    1977    11950400 :             L_tmp1 = BASOP_Util_Add_Mant32Exp( data_fx[j][i], data_e, 0, 0, &scale );
    1978    11950400 :             L_tmp = Mpy_32_32( L_tmp1, L_tmp1 ); // data_e + data_e
    1979    11950400 :             downmixEne_fx = BASOP_Util_Add_Mant32Exp( L_tmp, scale + scale, downmixEne_fx, downmixEne_e, &downmixEne_e );
    1980             :         }
    1981             :     }
    1982             : 
    1983       11470 :     alpha_fx = 214748364; // 0.1 in Q31
    1984       11470 :     move32();
    1985             : 
    1986       11470 :     L_tmp = Mpy_32_32( alpha_fx, multiChEne_fx );
    1987       11470 :     L_tmp1 = Mpy_32_32( 1932735284 /* 0.9f in Q31 */, hMcMasa->prevMultiChEne_fx );
    1988       11470 :     hMcMasa->prevMultiChEne_fx = BASOP_Util_Add_Mant32Exp( L_tmp, multiChEne_e, L_tmp1, hMcMasa->prevMultiChEne_e, &hMcMasa->prevMultiChEne_e );
    1989       11470 :     move32();
    1990             : 
    1991       11470 :     L_tmp = Mpy_32_32( alpha_fx, downmixEne_fx );
    1992       11470 :     L_tmp1 = Mpy_32_32( 1932735284 /* 0.9f in Q31 */, hMcMasa->prevDownmixEne_fx );
    1993       11470 :     hMcMasa->prevDownmixEne_fx = BASOP_Util_Add_Mant32Exp( L_tmp, downmixEne_e, L_tmp1, hMcMasa->prevDownmixEne_e, &hMcMasa->prevDownmixEne_e );
    1994       11470 :     move32();
    1995             : 
    1996       11470 :     prevEQ_fx = hMcMasa->prevEQ_fx;
    1997       11470 :     move32();
    1998       11470 :     prevEQ_e = hMcMasa->prevEQ_e;
    1999       11470 :     move16();
    2000             : 
    2001       11470 :     tmp = BASOP_Util_Divide3232_Scale( hMcMasa->prevMultiChEne_fx, L_add( hMcMasa->prevDownmixEne_fx, EPSILON_FX ), &scale );
    2002       11470 :     currEQ_e = add( scale, sub( hMcMasa->prevMultiChEne_e, hMcMasa->prevDownmixEne_e ) );
    2003       11470 :     currEQ_fx = Sqrt32( L_deposit_h( tmp ), &currEQ_e );
    2004             : 
    2005       11470 :     hMcMasa->prevEQ_fx = currEQ_fx;
    2006       11470 :     move32();
    2007       11470 :     hMcMasa->prevEQ_e = currEQ_e;
    2008       11470 :     move16();
    2009             : 
    2010    10958670 :     FOR( i = 0; i < input_frame; i++ )
    2011             :     {
    2012    10947200 :         L_tmp = Mpy_32_32( L_deposit_h( hMcMasa->interpolator_fx[i] ), currEQ_fx );
    2013    10947200 :         L_tmp1 = L_sub( 1073741824 /* 1 in Q30 */, L_lshr( L_deposit_h( hMcMasa->interpolator_fx[i] ), 1 ) );
    2014    10947200 :         L_tmp1 = Mpy_32_32( L_tmp1, prevEQ_fx );
    2015    10947200 :         instEQ_fx = BASOP_Util_Add_Mant32Exp( L_tmp, currEQ_e, L_tmp1, add( prevEQ_e, 1 ), &instEQ_e );
    2016             : 
    2017    22897600 :         FOR( j = 0; j < nchan_transport; j++ )
    2018             :         {
    2019    11950400 :             data_fx[j][i] = Mpy_32_32( instEQ_fx, data_fx[j][i] ); // data_e + instEQ_e - 31
    2020    11950400 :             move32();
    2021    11950400 :             move32();
    2022    11950400 :             data_fx[j][i] = L_shl( data_fx[j][i], instEQ_e ); // data_e + 2*instEQ_e - 31
    2023             :         }
    2024             :     }
    2025             : 
    2026       11470 :     return;
    2027             : }
    2028             : /* Compute covariance matrix, i.e., xT * conj(x), and accumulate to the output */
    2029    10947200 : static void compute_cov_mtx_fx(
    2030             :     Word32 sr[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i  : Input matrix, real, s[ch][freq]               (inp_exp) */
    2031             :     Word32 si[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i  : Input matrix, imag, s[ch][freq]               (inp_exp) */
    2032             :     const Word16 freq,                                      /* i  : Freq to process                                         */
    2033             :     const Word16 N,                                         /* i  : Number of channels                                      */
    2034             :     CovarianceMatrix *COVls,                                /* o  : Output matrix, contains upper part of cov mtx           */
    2035             :     Word16 inp_exp                                          /*Stores exponent for temp*/
    2036             : )
    2037             : {
    2038             :     Word16 i, j;
    2039             :     Word32 a, b, c, d;
    2040             :     Word32 temp;
    2041             :     Word16 norm_a, norm_b, norm_c, norm_d;
    2042             :     Word16 shift;
    2043    72782400 :     FOR( i = 0; i < N; i++ )
    2044             :     {
    2045    61835200 :         a = sr[i][freq];
    2046    61835200 :         move32();
    2047    61835200 :         b = si[i][freq];
    2048    61835200 :         move32();
    2049    61835200 :         norm_a = norm_l( a );
    2050    61835200 :         norm_b = norm_l( b );
    2051    61835200 :         a = L_shl( a, norm_a ); /*inp_exp-norm_a*/
    2052    61835200 :         b = L_shl( b, norm_b ); /*inp_exp-norm_b*/
    2053   282544000 :         FOR( j = i; j < N; j++ )
    2054             :         {
    2055   220708800 :             c = sr[j][freq];
    2056   220708800 :             move32();
    2057   220708800 :             d = si[j][freq];
    2058   220708800 :             move32();
    2059   220708800 :             norm_c = norm_l( c );
    2060   220708800 :             norm_d = norm_l( d );
    2061   220708800 :             c = L_shl( c, norm_c );                                                                                                                                                              /*inp_exp-norm_c*/
    2062   220708800 :             d = L_shl( d, norm_d );                                                                                                                                                              /*inp_exp-norm_d*/
    2063   220708800 :             temp = BASOP_Util_Add_Mant32Exp( Mult_32_32( a, c ), sub( shl( inp_exp, 1 ), add( norm_a, norm_c ) ), Mult_32_32( b, d ), sub( shl( inp_exp, 1 ), add( norm_b, norm_d ) ), &shift ); /*exp=inp_exp-norm_ab+inp_exp-norm_cd*/
    2064   220708800 :             COVls->xr_fx[i][j] = BASOP_Util_Add_Mant32Exp( COVls->xr_fx[i][j], COVls->xr_e[i][j], temp, shift, &COVls->xr_e[i][j] );
    2065   220708800 :             move32();
    2066   220708800 :             temp = BASOP_Util_Add_Mant32Exp( Mult_32_32( b, c ), sub( shl( inp_exp, 1 ), add( norm_b, norm_c ) ), L_negate( Mult_32_32( a, d ) ), sub( shl( inp_exp, 1 ), add( norm_a, norm_d ) ), &shift );
    2067   220708800 :             COVls->xi_fx[i][j] = BASOP_Util_Add_Mant32Exp( COVls->xi_fx[i][j], COVls->xi_e[i][j], temp, shift, &COVls->xi_e[i][j] );
    2068   220708800 :             move32();
    2069             :         }
    2070             :     }
    2071             : 
    2072    10947200 :     return;
    2073             : }
    2074       91760 : static void computeIntensityVector_enc_fx(
    2075             :     const Word16 *band_grouping,
    2076             :     Word32 Cldfb_RealBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX],
    2077             :     Word32 Cldfb_ImagBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX],
    2078             :     const Word16 enc_param_start_band, /* i  : first band to process */
    2079             :     const Word16 num_frequency_bands,
    2080             :     Word32 intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] )
    2081             : {
    2082             :     /* Reminder
    2083             :      * X = a + ib; Y = c + id
    2084             :      * X*Y = ac - bd + i(ad +bc)
    2085             :      */
    2086             :     Word16 i, j;
    2087             :     Word32 real, img;
    2088             :     Word16 brange[2];
    2089             : 
    2090      550560 :     FOR( i = enc_param_start_band; i < enc_param_start_band + num_frequency_bands; i++ )
    2091             :     {
    2092      458800 :         brange[0] = band_grouping[i];
    2093      458800 :         move16();
    2094      458800 :         brange[1] = band_grouping[i + 1];
    2095      458800 :         move16();
    2096             : 
    2097      458800 :         intensity_real[0][i] = 0;
    2098      458800 :         move32();
    2099      458800 :         intensity_real[1][i] = 0;
    2100      458800 :         move32();
    2101      458800 :         intensity_real[2][i] = 0;
    2102      458800 :         move32();
    2103             : 
    2104    22353200 :         FOR( j = brange[0]; j < brange[1]; j++ )
    2105             :         {
    2106    21894400 :             real = Cldfb_RealBuffer[0][j];
    2107    21894400 :             move32();
    2108    21894400 :             img = Cldfb_ImagBuffer[0][j];
    2109    21894400 :             move32();
    2110             :             /* Intensity is XYZ order, audio is WYZX order. */
    2111    21894400 :             intensity_real[0][i] = L_add( intensity_real[0][i], L_add( Mpy_32_32( Cldfb_RealBuffer[3][j], real ), Mpy_32_32( Cldfb_ImagBuffer[3][j], img ) ) ); // output Q= 2* input_q -31
    2112    21894400 :             move32();
    2113    21894400 :             intensity_real[1][i] = L_add( intensity_real[1][i], L_add( Mpy_32_32( Cldfb_RealBuffer[1][j], real ), Mpy_32_32( Cldfb_ImagBuffer[1][j], img ) ) ); // output Q= 2* input_q -31
    2114    21894400 :             move32();
    2115    21894400 :             intensity_real[2][i] = L_add( intensity_real[2][i], L_add( Mpy_32_32( Cldfb_RealBuffer[2][j], real ), Mpy_32_32( Cldfb_ImagBuffer[2][j], img ) ) ); // output Q= 2* input_q -31
    2116    21894400 :             move32();
    2117             :         }
    2118             :     }
    2119             : 
    2120       91760 :     return;
    2121             : }
    2122        6120 : static void computeVerticalDiffuseness_fx(
    2123             :     Word32 **buffer_intensity,     /* i  : Intensity vectors           */
    2124             :     const Word32 *buffer_energy,   /* i  : Energy                      */
    2125             :     const Word16 averaging_length, /* i  : Averaging length            */
    2126             :     const Word16 num_freq_bands,   /* i  : Number of frequency bands   */
    2127             :     Word32 *diffuseness,           /* o  : Estimated diffuseness   Q31 */
    2128             :     Word16 *buffer_intensity_q,
    2129             :     Word16 *buffer_energy_q )
    2130             : {
    2131             :     Word32 intensity_slow[MASA_FREQUENCY_BANDS];
    2132             :     Word32 intensity_slow_abs[MASA_FREQUENCY_BANDS];
    2133             :     Word32 energy_slow[MASA_FREQUENCY_BANDS];
    2134             :     Word16 i, k;
    2135        6120 :     Word32 tmp = 0;
    2136        6120 :     move32();
    2137             :     const Word32 *p_tmp_c;
    2138             :     Word16 intensity_slow_e[MASA_FREQUENCY_BANDS], energy_slow_e[MASA_FREQUENCY_BANDS];
    2139             : 
    2140             :     /* Set variables to zero */
    2141        6120 :     set32_fx( intensity_slow, 0, MASA_FREQUENCY_BANDS );
    2142        6120 :     set32_fx( energy_slow, 0, MASA_FREQUENCY_BANDS );
    2143        6120 :     set16_fx( intensity_slow_e, 0, MASA_FREQUENCY_BANDS );
    2144        6120 :     set16_fx( energy_slow_e, 0, MASA_FREQUENCY_BANDS );
    2145             : 
    2146       55080 :     FOR( i = 0; i < averaging_length; ++i )
    2147             :     {
    2148             :         /* Energy slow */
    2149       48960 :         p_tmp_c = buffer_energy + i_mult( i, num_freq_bands );
    2150      293760 :         FOR( k = 0; k < num_freq_bands; k++ )
    2151             :         {
    2152      244800 :             energy_slow[k] = BASOP_Util_Add_Mant32Exp( energy_slow[k], energy_slow_e[k], *( p_tmp_c ), sub( 31, buffer_energy_q[i] ), &energy_slow_e[k] ); /*q=min_q*/
    2153      244800 :             move32();
    2154      244800 :             p_tmp_c++;
    2155             :         }
    2156             : 
    2157             :         /* Intensity slow */
    2158      293760 :         FOR( k = 0; k < num_freq_bands; k++ )
    2159             :         {
    2160      244800 :             intensity_slow[k] = BASOP_Util_Add_Mant32Exp( intensity_slow[k], intensity_slow_e[k], buffer_intensity[i][k], sub( 31, buffer_intensity_q[i] ), &intensity_slow_e[k] ); /*q=min_q*/
    2161      244800 :             move32();
    2162             :         }
    2163             :     }
    2164             : 
    2165             :     /* Compute absolute value */
    2166       36720 :     FOR( k = 0; k < num_freq_bands; k++ )
    2167             :     {
    2168       30600 :         intensity_slow_abs[k] = L_abs( intensity_slow[k] ); /*min_q*/
    2169       30600 :         move32();
    2170             :     }
    2171             : 
    2172             :     /* Compute Diffuseness */
    2173       36720 :     FOR( i = 0; i < num_freq_bands; ++i )
    2174             :     {
    2175             :         Word16 tmp_e1, tmp_e2, tmp1;
    2176       30600 :         tmp = BASOP_Util_Divide3232_Scale( intensity_slow_abs[i], L_add( energy_slow[i], EPSILON_FX_SMALL ), &tmp_e1 );
    2177       30600 :         tmp_e1 = add( tmp_e1, sub( intensity_slow_e[i], energy_slow_e[i] ) );
    2178       30600 :         tmp_e1 = BASOP_Util_Add_MantExp( (Word16) tmp, tmp_e1, -VERTICAL_ENERGY_RATIO_OFFSET_FX, 0, &tmp1 );
    2179       30600 :         tmp = BASOP_Util_Divide3232_Scale( (Word32) tmp1, ONE_IN_Q15 - VERTICAL_ENERGY_RATIO_OFFSET_FX, &tmp_e2 ); /* Tuned to avoid effect due to ambience of vertically un-even setups */
    2180       30600 :         tmp_e2 = add( tmp_e2, tmp_e1 );
    2181       30600 :         tmp = L_sub( L_shl( 1, sub( 15, tmp_e2 ) ), tmp );
    2182       30600 :         IF( tmp < 0 )
    2183             :         {
    2184           1 :             tmp = 0;
    2185           1 :             move32();
    2186             :         }
    2187       30599 :         ELSE IF( GE_32( tmp, L_shl( 1, sub( 15, tmp_e2 ) ) ) )
    2188             :         {
    2189        1332 :             tmp = ONE_IN_Q31;
    2190        1332 :             move32();
    2191             :         }
    2192             :         ELSE
    2193             :         {
    2194       29267 :             tmp = L_shl( tmp, add( 16, tmp_e2 ) );
    2195             :         }
    2196       30600 :         diffuseness[i] = tmp; // Q31
    2197       30600 :         move32();
    2198             :     }
    2199             : 
    2200        6120 :     return;
    2201             : }
    2202         372 : static void computeEvenLayout_fx(
    2203             :     const Word32 *ls_azimuth, // Q22
    2204             :     Word32 *ls_azimuth_even,  // Q22
    2205             :     const Word16 numChannels )
    2206             : {
    2207             :     Word16 i;
    2208             :     Word16 j;
    2209             :     Word32 ls_azimuth_temp[MCMASA_MAX_ANA_CHANS];
    2210             :     Word32 ls_azimuth_even_ordered[MCMASA_MAX_ANA_CHANS];
    2211             :     Word16 ls_azimuth_order[MCMASA_MAX_ANA_CHANS];
    2212             :     Word32 smallestAzimuth;
    2213             :     Word16 smallestAzimuthIndex;
    2214             :     Word32 lsSpacing;
    2215             :     UWord8 oddLayout;
    2216             :     Word32 startAzimuth;
    2217             :     Word16 numChannelsHalf;
    2218             : 
    2219         372 :     lsSpacing = L_shl( L_mult0( 360, div_s( 1, numChannels ) ), 6 ); /*Q.21*/
    2220         372 :     oddLayout = (UWord8) s_and( numChannels, 1 );
    2221         372 :     move16();
    2222         372 :     numChannelsHalf = shr( numChannels, 1 );
    2223             : 
    2224         372 :     Copy32( ls_azimuth, ls_azimuth_temp, numChannels );
    2225         372 :     Scale_sig32( ls_azimuth_temp, numChannels, -1 ); /*Q.21*/
    2226        2265 :     FOR( i = 0; i < numChannels; i++ )
    2227             :     {
    2228        1893 :         smallestAzimuth = 1000 << 21; /*Q21*/
    2229        1893 :         move32();
    2230        1893 :         smallestAzimuthIndex = 0;
    2231        1893 :         move16();
    2232       11974 :         FOR( j = 0; j < numChannels; j++ )
    2233             :         {
    2234       10081 :             IF( LT_32( ls_azimuth_temp[j], smallestAzimuth ) )
    2235             :             {
    2236        3502 :                 smallestAzimuth = ls_azimuth_temp[j];
    2237        3502 :                 move32();
    2238        3502 :                 smallestAzimuthIndex = j;
    2239        3502 :                 move16();
    2240             :             }
    2241             :         }
    2242        1893 :         ls_azimuth_order[i] = smallestAzimuthIndex;
    2243        1893 :         move32();
    2244        1893 :         ls_azimuth_temp[smallestAzimuthIndex] = ( 1000 << 21 );
    2245        1893 :         move32();
    2246             :     }
    2247             : 
    2248         372 :     IF( oddLayout )
    2249             :     {
    2250         249 :         startAzimuth = W_extract_l( W_mult0_32_32( -lsSpacing, shl( numChannelsHalf, 1 ) ) ); /*Q.22*/
    2251             :     }
    2252             :     ELSE
    2253             :     {
    2254         123 :         startAzimuth = W_extract_l( W_mult0_32_32( -lsSpacing, sub( shl( numChannelsHalf, 1 ), 1 ) ) ); /*Q.22*/
    2255             :     }
    2256             : 
    2257        2265 :     FOR( i = 0; i < numChannels; i++ )
    2258             :     {
    2259        1893 :         ls_azimuth_even_ordered[i] = W_extract_l( W_add( W_mult_32_16( lsSpacing, i ), startAzimuth ) ); /*Q.22*/
    2260        1893 :         move32();
    2261             :     }
    2262             : 
    2263        2265 :     FOR( i = 0; i < numChannels; i++ )
    2264             :     {
    2265        1893 :         ls_azimuth_even[ls_azimuth_order[i]] = L_shl( L_shr( L_add( ls_azimuth_even_ordered[i], ONE_IN_Q21 ), 22 ), 22 ); /*((a+2^21)/2^22)*2^22*/
    2266        1893 :         move32();
    2267             :     }
    2268             : 
    2269         372 :     return;
    2270             : }
    2271       11470 : static void computeLfeEnergy_fx(
    2272             :     MCMASA_ENC_HANDLE hMcMasa,
    2273             :     Word32 *data_fx[], // q_inp
    2274             :     const Word16 input_frame,
    2275             :     Word16 q_inp )
    2276             : {
    2277             :     Word16 l_ts;
    2278             :     Word16 block_m_idx;
    2279             :     Word16 mrange[2];
    2280             :     Word16 separateChannelIndex;
    2281             :     Word16 lfeChannelIndex;
    2282             :     Word32 *pcm_in[1];
    2283       11470 :     Word16 inp_q = q_inp;
    2284       11470 :     move16();
    2285             : 
    2286       11470 :     l_ts = idiv1616( input_frame, MDFT_NO_COL_MAX );
    2287       11470 :     separateChannelIndex = hMcMasa->separateChannelIndex;
    2288       11470 :     move16();
    2289       11470 :     lfeChannelIndex = LFE_CHANNEL;
    2290       11470 :     move16();
    2291             : 
    2292       11470 :     IF( hMcMasa->separateChannelEnabled )
    2293             :     {
    2294         625 :         Copy32( data_fx[lfeChannelIndex], &( hMcMasa->delay_buffer_lfe[0][hMcMasa->num_samples_delay_comp - hMcMasa->offset_comp] ), hMcMasa->offset_comp );      // q_inp
    2295         625 :         Copy32( data_fx[separateChannelIndex], &( hMcMasa->delay_buffer_lfe[1][hMcMasa->num_samples_delay_comp - hMcMasa->offset_comp] ), hMcMasa->offset_comp ); // q_inp
    2296             :     }
    2297             :     ELSE
    2298             :     {
    2299       10845 :         pcm_in[0] = &data_fx[lfeChannelIndex][0];
    2300             :     }
    2301             : 
    2302             :     /* Reset variables */
    2303       11470 :     set32_fx( hMcMasa->lfeLfEne, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
    2304       11470 :     set16_fx( hMcMasa->lfeLfEne_e, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
    2305       11470 :     set32_fx( hMcMasa->totalLfEne, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
    2306       11470 :     set16_fx( hMcMasa->totalLfEne_e, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
    2307             : 
    2308             :     /* Compute low-frequency energies */
    2309       11470 :     IF( hMcMasa->separateChannelEnabled ) /* Using low-pass filter */
    2310             :     {
    2311             :         Word32 lowpassCoef;
    2312             :         Word16 lowPassSignal_q;
    2313             :         Word16 i, j;
    2314             :         Word32 delayedInputSignal[2][L_FRAME48k];
    2315             :         Word32 lowPassSignal[2][L_FRAME48k];
    2316             : 
    2317         625 :         Copy32( &( hMcMasa->delay_buffer_lfe[0][0] ), &( delayedInputSignal[0][0] ), hMcMasa->num_slots_delay_comp * l_ts );                                                                          // q_inp
    2318         625 :         Copy32( data_fx[lfeChannelIndex] + hMcMasa->offset_comp, &( delayedInputSignal[0][hMcMasa->num_slots_delay_comp * l_ts] ), ( MDFT_NO_COL_MAX - hMcMasa->num_slots_delay_comp ) * l_ts );      // q_inp
    2319         625 :         Copy32( &( hMcMasa->delay_buffer_lfe[1][0] ), &( delayedInputSignal[1][0] ), hMcMasa->num_slots_delay_comp * l_ts );                                                                          // q_inp
    2320         625 :         Copy32( data_fx[separateChannelIndex] + hMcMasa->offset_comp, &( delayedInputSignal[1][hMcMasa->num_slots_delay_comp * l_ts] ), ( MDFT_NO_COL_MAX - hMcMasa->num_slots_delay_comp ) * l_ts ); // q_inp
    2321             : 
    2322         625 :         lowpassCoef = L_shl( div_w( 1, (Word32) hMcMasa->ringBufferSize ), Q6 ); // Q.37(31+6)
    2323             : 
    2324      600625 :         FOR( i = 0; i < input_frame; i++ )
    2325             :         {
    2326     1800000 :             FOR( j = 0; j < 2; j++ )
    2327             :             {
    2328             :                 Word32 temp1, temp2;
    2329     1200000 :                 temp1 = Mpy_32_32( delayedInputSignal[j][i], lowpassCoef );                                 // Q(q_inp+6)
    2330     1200000 :                 temp2 = Mpy_32_32( hMcMasa->lfeAnaRingBuffer[j][hMcMasa->ringBufferPointer], lowpassCoef ); // Q(q_inp+6)
    2331     1200000 :                 hMcMasa->lowpassSum[j] = L_add( hMcMasa->lowpassSum[j], L_sub( temp1, temp2 ) );
    2332     1200000 :                 move32();
    2333     1200000 :                 lowPassSignal[j][i] = hMcMasa->lowpassSum[j];
    2334     1200000 :                 move32();
    2335     1200000 :                 hMcMasa->lfeAnaRingBuffer[j][hMcMasa->ringBufferPointer] = delayedInputSignal[j][i];
    2336     1200000 :                 move32();
    2337             :             }
    2338             : 
    2339      600000 :             hMcMasa->ringBufferPointer = sub( hMcMasa->ringBufferPointer, 1 );
    2340      600000 :             move16();
    2341      600000 :             IF( hMcMasa->ringBufferPointer < 0 )
    2342             :             {
    2343        2500 :                 hMcMasa->ringBufferPointer = sub( hMcMasa->ringBufferSize, 1 );
    2344             :             }
    2345             :         }
    2346         625 :         lowPassSignal_q = add( q_inp, Q6 );
    2347        3125 :         FOR( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
    2348             :         {
    2349        2500 :             mrange[0] = i_mult( hMcMasa->block_grouping[block_m_idx], l_ts );
    2350        2500 :             move16();
    2351        2500 :             mrange[1] = i_mult( hMcMasa->block_grouping[block_m_idx + 1], l_ts );
    2352        2500 :             move16();
    2353             : 
    2354      602500 :             FOR( i = mrange[0]; i < mrange[1]; i++ )
    2355             :             {
    2356      600000 :                 hMcMasa->lfeLfEne[block_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->lfeLfEne[block_m_idx], hMcMasa->lfeLfEne_e[block_m_idx], Mpy_32_32( lowPassSignal[0][i], lowPassSignal[0][i] ), sub( 31, sub( shl( lowPassSignal_q, 1 ), 31 ) ), &hMcMasa->lfeLfEne_e[block_m_idx] );
    2357      600000 :                 move32();
    2358      600000 :                 hMcMasa->totalLfEne[block_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->totalLfEne[block_m_idx], hMcMasa->totalLfEne_e[block_m_idx], Mpy_32_32( lowPassSignal[1][i], lowPassSignal[1][i] ), sub( 31, sub( shl( lowPassSignal_q, 1 ), 31 ) ), &hMcMasa->totalLfEne_e[block_m_idx] );
    2359      600000 :                 move32();
    2360             :             }
    2361        2500 :             hMcMasa->totalLfEne[block_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->totalLfEne[block_m_idx], hMcMasa->totalLfEne_e[block_m_idx], hMcMasa->lfeLfEne[block_m_idx], hMcMasa->lfeLfEne_e[block_m_idx], &hMcMasa->totalLfEne_e[block_m_idx] );
    2362        2500 :             move32();
    2363             :         }
    2364             :     }
    2365             :     ELSE /* Using CLDFB */
    2366             :     {
    2367             :         Word16 ts;
    2368             :         Word16 i;
    2369             :         Word32 Chnl_RealBuffer[2][DIRAC_NO_FB_BANDS_MAX];
    2370             :         Word32 Chnl_ImagBuffer[2][DIRAC_NO_FB_BANDS_MAX];
    2371             :         Word32 *p_Chnl_RealBuffer[2];
    2372             :         Word32 *p_Chnl_ImagBuffer[2];
    2373             : 
    2374       10845 :         p_Chnl_RealBuffer[0] = &Chnl_RealBuffer[0][0];
    2375       10845 :         p_Chnl_RealBuffer[1] = &Chnl_RealBuffer[1][0];
    2376       10845 :         p_Chnl_ImagBuffer[0] = &Chnl_ImagBuffer[0][0];
    2377       10845 :         p_Chnl_ImagBuffer[1] = &Chnl_ImagBuffer[1][0];
    2378             : 
    2379             : 
    2380       54225 :         FOR( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
    2381             :         {
    2382       43380 :             mrange[0] = hMcMasa->block_grouping[block_m_idx];
    2383       43380 :             move16();
    2384       43380 :             mrange[1] = hMcMasa->block_grouping[block_m_idx + 1];
    2385       43380 :             move16();
    2386             : 
    2387       86760 :             FOR( ts = mrange[0]; ts < mrange[1]; ts++ )
    2388             :             {
    2389       43380 :                 ivas_fb_mixer_get_windowed_fr_fx( hMcMasa->hFbMixerLfe, pcm_in, p_Chnl_RealBuffer, p_Chnl_ImagBuffer, l_ts, l_ts, hMcMasa->hFbMixerLfe->fb_cfg->num_in_chans, 0 );
    2390             : 
    2391       43380 :                 ivas_fb_mixer_update_prior_input_fx( hMcMasa->hFbMixerLfe, pcm_in, l_ts, hMcMasa->hFbMixerLfe->fb_cfg->num_in_chans );
    2392             : 
    2393       43380 :                 pcm_in[0] += l_ts;
    2394             : 
    2395             :                 /* Compute low frequency energy for LFE, for other channels it is computed in ivas_chnl_param_est_enc() */
    2396      216900 :                 FOR( i = 0; i < CLDFB_TO_MDFT_FAC; i++ )
    2397             :                 {
    2398      173520 :                     hMcMasa->lfeLfEne[block_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->lfeLfEne[block_m_idx], hMcMasa->lfeLfEne_e[block_m_idx], L_add( Mpy_32_32( Chnl_RealBuffer[0][i], Chnl_RealBuffer[0][i] ), Mpy_32_32( Chnl_ImagBuffer[0][i], Chnl_ImagBuffer[0][i] ) ), sub( 31, sub( shl( inp_q, 1 ), 31 ) ), &hMcMasa->lfeLfEne_e[block_m_idx] );
    2399      173520 :                     move32();
    2400             :                 }
    2401             :             }
    2402             :         }
    2403             :     }
    2404             : 
    2405       11470 :     IF( hMcMasa->separateChannelEnabled )
    2406             :     {
    2407         625 :         Copy32( data_fx[lfeChannelIndex] + ( input_frame - hMcMasa->num_samples_delay_comp + hMcMasa->offset_comp ), &( hMcMasa->delay_buffer_lfe[0][0] ), sub( hMcMasa->num_samples_delay_comp, hMcMasa->offset_comp ) );      // q_in
    2408         625 :         Copy32( data_fx[separateChannelIndex] + ( input_frame - hMcMasa->num_samples_delay_comp + hMcMasa->offset_comp ), &( hMcMasa->delay_buffer_lfe[1][0] ), sub( hMcMasa->num_samples_delay_comp, hMcMasa->offset_comp ) ); // q_in
    2409             :     }
    2410             : 
    2411       11470 :     return;
    2412             : }

Generated by: LCOV version 1.14