LCOV - code coverage report
Current view: top level - lib_enc - ivas_mcmasa_enc_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 574a190e3c6896c6c4ed10d7f23649709a0c4347 Lines: 1157 1228 94.2 %
Date: 2025-06-27 02:59:36 Functions: 12 12 100.0 %

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

Generated by: LCOV version 1.14