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

Generated by: LCOV version 1.14