LCOV - code coverage report
Current view: top level - lib_rend - ivas_dirac_dec_binaural_functions_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 574a190e3c6896c6c4ed10d7f23649709a0c4347 Lines: 2573 2805 91.7 %
Date: 2025-06-27 02:59:36 Functions: 25 25 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 <stdint.h>
      34             : #include "options.h"
      35             : #include <assert.h>
      36             : #include <math.h>
      37             : #include "prot_fx.h"
      38             : #include "ivas_prot_rend_fx.h"
      39             : #include "ivas_cnst.h"
      40             : #include "ivas_rom_binauralRenderer.h"
      41             : #include "ivas_rom_binaural_crend_head.h"
      42             : #include "ivas_rom_rend.h"
      43             : #include "ivas_rom_com.h"
      44             : #include "ivas_prot_fx.h"
      45             : 
      46             : #include "wmc_auto.h"
      47             : 
      48             : Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 };
      49             : 
      50             : /*-------------------------------------------------------------------------
      51             :  * Local constants
      52             :  *------------------------------------------------------------------------*/
      53             : 
      54             : #define CLDFB_HALF_BIN_FREQUENCY_OFFSET         0.5f
      55             : #define IVAS_TDET_DUCK_MULT_FAC_PARA_BIN        ( 2.0f )
      56             : #define IVAS_TDET_DUCK_MULT_FAC_PARA_BIN_LOW_BR ( 3.0f )
      57             : #define SBA_CARDI_TARGET_ENERGY_GAIN            0.5f
      58             : 
      59             : #define STEREO_PREPROCESS_IIR_FACTOR     ( 0.9f )
      60             : #define STEREO_PREPROCESS_IIR_FACTOR_Q15 ( 29491 )
      61             : /* powf(0.95f, 4.0f) for sub-frame smoothing instead of CLDFB slot */
      62             : #define ADAPT_HTPROTO_IIR_FAC 0.81450625f
      63             : 
      64             : #define ADAPT_HTPROTO_ILD_LIM_DB0  1.0f
      65             : #define ADAPT_HTPROTO_ILD_LIM_DB1  4.0f
      66             : #define ADAPT_HTPROTO_ROT_LIM_0    0.4f
      67             : #define ADAPT_HTPROTO_ROT_LIM_0_FX 429496736  // Q30
      68             : #define TWO_POINT_FIVE_IN_Q13      20480      // Q13
      69             : #define ADAPT_HTPROTO_IIR_FAC_FX   26689      // Q15
      70             : #define LOG_10_BASE_2_Q29          1783446528 // Q29
      71             : #define TAN_30_FX                  17157      // Q15
      72             : #define INV_TAN30_FX               28377      // Q14
      73             : #define EPSILON_MANT               1180591621 /* 1e-12 = 0.5497558*(2^-39) in Q70 */
      74             : #define EPSILON_EXP                ( -39 )
      75             : #define ONE_DIV_EPSILON_MANT       1953125000 /* 1e+12 = 0.9094947*(2^40) */
      76             : #define ONE_DIV_EPSILON_EXP        ( 40 )
      77             : #define ADAPT_HTPROTO_ROT_LIM_1    0.8f
      78             : 
      79             : #define MAX_GAIN_CACHE_SIZE ( ( MASA_MAXIMUM_DIRECTIONS * 3 ) + MAX_NUM_OBJECTS ) /* == different calls to get gains */
      80             : 
      81             : typedef struct hrtfGainCache
      82             : {
      83             :     Word16 azi;
      84             :     Word16 ele;
      85             : 
      86             :     Word32 shVec_fx[HRTF_SH_CHANNELS];
      87             : 
      88             : } PARAMBIN_HRTF_GAIN_CACHE;
      89             : 
      90             : typedef struct parambin_rend_config_data
      91             : {
      92             :     Word16 separateCenterChannelRendering;
      93             :     IVAS_FORMAT ivas_format;
      94             :     MC_MODE mc_mode;
      95             :     Word32 ivas_total_brate;
      96             :     Word16 nchan_transport;
      97             :     Word32 qualityBasedSmFactor_fx; /* Q31 */
      98             :     Word16 processReverb;
      99             :     ISM_MODE ism_mode;
     100             : } PARAMBIN_REND_CONFIG, *PARAMBIN_REND_CONFIG_HANDLE;
     101             : 
     102             : 
     103             : /*-------------------------------------------------------------------------
     104             :  * Local function prototypes
     105             :  *------------------------------------------------------------------------*/
     106             : 
     107             : static void ivas_dirac_dec_binaural_internal_fx( Decoder_Struct *st_ivas, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, Word32 *output_f[] /*Q11*/, const Word16 nchan_transport, const Word16 subframe );
     108             : 
     109             : static void ivas_dirac_dec_decorrelate_slot_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, const Word16 num_freq_bands, const Word16 slot, Word32 inRe[][CLDFB_SLOTS_PER_SUBFRAME] /*q_inp*/[CLDFB_NO_CHANNELS_MAX], Word32 inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /*q_inp*/, Word16 q_inp, Word32 decRe[][CLDFB_NO_CHANNELS_MAX] /*q_inp*/, Word32 decIm[] /*q_inp*/[CLDFB_NO_CHANNELS_MAX] );
     110             : 
     111             : static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, Word32 inRe_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /*q*/, Word32 inIm_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /*q*/, Word32 Rmat_fx[3][3] /*Q30*/, const Word16 subframe, const Word16 isHeadtracked, const MASA_ISM_DATA_HANDLE hMasaIsmData, Word16 q );
     112             : 
     113             : static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, const Word16 max_band_decorr, Word32 Rmat[3][3] /*Q30*/, const Word16 subframe, const Word16 isHeadtracked, const Word16 nchanSeparateChannels, const MASA_ISM_DATA_HANDLE hMasaIsmData );
     114             : 
     115             : static void ivas_dirac_dec_binaural_process_output_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, HANDLE_CLDFB_FILTER_BANK cldfbSynDec[MAX_OUTPUT_CHANNELS], Word32 *output_fx[] /*q_out*/, Word16 *q_out, Word32 inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /*q_inp*/, Word32 inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /*q_inp*/, const Word16 q_inp, const Word16 max_band_decorr, const Word16 numInChannels, const Word16 processReverb, const Word16 subframe, const Word16 q_mat );
     116             : 
     117             : static void adaptTransportSignalsHeadtracked_fx( COMBINED_ORIENTATION_HANDLE hHeadTrackData, Word32 inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /*q_inp*/, Word32 inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /*q_inp*/, Word16 q_inp, const Word16 nBins, const Word16 nSlots, Word32 Rmat[3][3] /*Q30*/ );
     118             : 
     119             : static void ivas_dirac_dec_binaural_check_and_switch_transports_headtracked_fx( COMBINED_ORIENTATION_HANDLE hHeadTrackData, Word32 inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], Word32 inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const Word16 nBins, const Word16 nSlots, Word32 Rmat[3][3] /*Q30*/ );
     120             : 
     121             : 
     122             : static void hrtfShGetHrtf_fx( const Word16 bin, const Word16 aziDeg, const Word16 eleDeg, Word32 *lRealp, Word32 *lImagp, Word32 *rRealp, Word32 *rImagp, PARAMBIN_HRTF_GAIN_CACHE *gainCache, const Word16 useCachedValue );
     123             : static void getDirectPartGains_fx( const Word16 bin, Word16 aziDeg, Word16 eleDeg, Word32 *lRealp, Word32 *lImagp, Word32 *rRealp, Word32 *rImagp, const UWord8 renderStereoOutputInsteadOfBinaural, Word32 Rmat[3][3] /*Q30*/, PARAMBIN_HRTF_GAIN_CACHE *gainCache, const Word16 isHeadtracked );
     124             : static void ivas_masa_ext_rend_parambin_internal_fx( MASA_EXT_REND_HANDLE hMasaExtRend, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, Word32 *output_fx[] /*Q11*/, const Word16 subframe );
     125             : static void formulate2x2MixingMatrix_fx( Word32 Ein1_fx /*q_Ein*/, Word32 Ein2_fx /*q_Ein*/, Word16 q_Ein, Word32 CinRe_fx /*q_Cin*/, Word32 CinIm_fx /*q_Cin*/, Word16 q_Cin, Word32 Eout1_fx /*q_Eout*/, Word32 Eout2_fx /*q_Eout*/, Word16 q_Eout, Word32 CoutRe_fx /*q_Cout*/, Word32 CoutIm_fx /*q_Cout*/, Word16 q_Cout, Word32 Q_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*Q31*/, Word32 Mre_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_M*/, Word32 Mim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_M*/, Word16 *q_M, const Word16 regularizationFactor_fx /*Q14*/ );
     126             : 
     127             : static void matrixMul_fx( Word32 Are[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_A*/, Word32 Aim[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_A*/, Word16 *q_A, Word32 Bre[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_B*/, Word32 Bim[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_B*/, Word16 *q_B, Word32 outRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/, Word32 outIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/, Word16 *q_out );
     128             : 
     129             : static void matrixTransp2Mul_fx(
     130             :     Word32 Are[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_A*/,
     131             :     Word32 Aim[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_A*/,
     132             :     Word16 *q_A,
     133             :     Word32 Bre[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_B*/,
     134             :     Word32 Bim[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_B*/,
     135             :     Word16 *q_B,
     136             :     Word32 Ascale,
     137             :     Word32 Bscale,
     138             :     Word32 outRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/,
     139             :     Word32 outIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/,
     140             :     Word16 *q_out );
     141             : 
     142             : /*-------------------------------------------------------------------------
     143             :  * ivas_dirac_dec_init_binaural_data()
     144             :  *
     145             :  * Initialize parametric binaural renderer
     146             :  *------------------------------------------------------------------------*/
     147         410 : ivas_error ivas_dirac_dec_init_binaural_data_fx(
     148             :     Decoder_Struct *st_ivas,            /* i/o: IVAS decoder structure                  */
     149             :     HRTFS_PARAMBIN_HANDLE hHrtfParambin /* i  : HRTF structure for rendering            */
     150             : )
     151             : {
     152             :     DIRAC_DEC_BIN_HANDLE hDiracDecBin;
     153             :     Word16 nBins;
     154             :     Word32 output_Fs;
     155             :     RENDERER_TYPE renderer_type;
     156             :     Word16 j, k, bin;
     157             :     Word32 binCenterFreq_fx;
     158             :     Word16 tmpFloat_fx;
     159             :     Word16 tmp;
     160             :     Word16 tmp_e;
     161             :     Word16 tmp2;
     162             :     ivas_error error;
     163         410 :     hDiracDecBin = st_ivas->hDiracDecBin;
     164             : 
     165         410 :     IF( hDiracDecBin == NULL )
     166             :     {
     167         410 :         IF( ( hDiracDecBin = (DIRAC_DEC_BIN_HANDLE) malloc( sizeof( DIRAC_DEC_BIN_DATA ) ) ) == NULL )
     168             :         {
     169           0 :             return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC binaural handle " );
     170             :         }
     171             : 
     172         410 :         hDiracDecBin->hTdDecorr = NULL;
     173         410 :         hDiracDecBin->hReverb = NULL;
     174         410 :         hDiracDecBin->h_freq_domain_decorr_ap_params = NULL;
     175         410 :         hDiracDecBin->h_freq_domain_decorr_ap_state = NULL;
     176             :     }
     177             : 
     178         410 :     output_Fs = st_ivas->hDecoderConfig->output_Fs;
     179         410 :     move32();
     180         410 :     nBins = st_ivas->hSpatParamRendCom->num_freq_bands;
     181         410 :     move16();
     182         410 :     renderer_type = st_ivas->renderer_type;
     183         410 :     move32();
     184             : 
     185        1230 :     FOR( j = 0; j < BINAURAL_CHANNELS; j++ )
     186             :     {
     187        5740 :         FOR( k = 0; k < BINAURAL_CHANNELS + MAX_NUM_OBJECTS; k++ )
     188             :         {
     189        4920 :             set16_fx( hDiracDecBin->processMtxRe_fx[j][k], 0, nBins );
     190        4920 :             set16_fx( hDiracDecBin->processMtxIm_fx[j][k], 0, nBins );
     191        4920 :             set16_fx( hDiracDecBin->processMtxRePrev_fx[j][k], 0, nBins );
     192        4920 :             set16_fx( hDiracDecBin->processMtxImPrev_fx[j][k], 0, nBins );
     193             :         }
     194             : 
     195        2460 :         FOR( k = 0; k < BINAURAL_CHANNELS; k++ )
     196             :         {
     197        1640 :             set16_fx( hDiracDecBin->processMtxDecRe_fx[j][k], 0, nBins );
     198        1640 :             set16_fx( hDiracDecBin->processMtxDecIm_fx[j][k], 0, nBins );
     199             :         }
     200         820 :         set32_fx( hDiracDecBin->ChEnePrev_fx[j], 0, nBins );
     201         820 :         set32_fx( hDiracDecBin->ChEneOutPrev_fx[j], 0, nBins );
     202         820 :         set16_fx( hDiracDecBin->ChEnePrev_e[j], 0, nBins );
     203         820 :         set16_fx( hDiracDecBin->ChEneOutPrev_e[j], 0, nBins );
     204             :     }
     205         410 :     set32_fx( hDiracDecBin->ChCrossRePrev_fx, 0, nBins );
     206         410 :     set32_fx( hDiracDecBin->ChCrossImPrev_fx, 0, nBins );
     207         410 :     set16_fx( hDiracDecBin->ChCrossRePrev_e, 0, nBins );
     208         410 :     set16_fx( hDiracDecBin->ChCrossImPrev_e, 0, nBins );
     209         410 :     set32_fx( hDiracDecBin->ChCrossReOutPrev_fx, 0, nBins );
     210         410 :     set32_fx( hDiracDecBin->ChCrossImOutPrev_fx, 0, nBins );
     211         410 :     set16_fx( hDiracDecBin->ChCrossReOutPrev_e, 0, nBins );
     212         410 :     set16_fx( hDiracDecBin->ChCrossImOutPrev_e, 0, nBins );
     213         410 :     hDiracDecBin->renderStereoOutputInsteadOfBinaural = 0;
     214         410 :     move16();
     215             : 
     216         410 :     hDiracDecBin->q_processMtx = Q15;
     217         410 :     hDiracDecBin->q_processMtxSCCR = Q15;
     218         410 :     hDiracDecBin->q_processMtxPrev = Q15;
     219         410 :     hDiracDecBin->q_processMtxPrevSCCR = Q15;
     220         410 :     hDiracDecBin->q_processMtxDec = Q15;
     221         410 :     hDiracDecBin->q_processMtxDecPrev = Q15;
     222         410 :     move16();
     223         410 :     move16();
     224         410 :     move16();
     225         410 :     move16();
     226         410 :     move16();
     227         410 :     move16();
     228             : 
     229       20210 :     FOR( bin = 0; bin < nBins; bin++ )
     230             :     {
     231       19800 :         binCenterFreq_fx = L_mult0( extract_l( L_shr( output_Fs, 1 ) ), div_s( add( shl( bin, 1 ), 1 ), shl( nBins, 1 ) ) ) /*( (float) bin + 0.5f ) / (float) nBins * ( (float) output_Fs / 2.0f )*/; /*Q15*/
     232             :         /* These formulas and values are from Christian Borss's publication for binaural diffuse field coherence */
     233       19800 :         tmp = BASOP_Util_Divide3232_Scale( binCenterFreq_fx, 2700 << Q15, &tmp_e );
     234       19800 :         IF( tmp_e < 0 )
     235             :         {
     236        1230 :             tmp = shl( tmp, tmp_e ); /*q15*/
     237        1230 :             tmp_e = 0;
     238        1230 :             move16();
     239             :         }
     240       19800 :         tmpFloat_fx = s_max( 0, sub( shl_sat( 1, sub( 15, tmp_e ) ), tmp ) ) /*max( 0.0f, 1.0f - binCenterFreq / 2700.0f )*/;                                                                                                                                                           /*Q15-tmp_e*/
     241       19800 :         tmp2 = extract_l( Mult_32_32( binCenterFreq_fx, 1952258 /*=2^31*180/(550)/360*/ ) % 32767 ); /* Q15 */                                                                                                                                                                          //*binCenterFreq_fx * EVS_PI / 550.0f*/
     242       19800 :         hDiracDecBin->diffuseFieldCoherence_fx[bin] = L_shl( L_mult0( divide3232( tmpFloat_fx, Mult_32_16( binCenterFreq_fx, 187 /*2^15*pi/550*/ ) ), getSineWord16R2( tmp2 ) ), tmp_e ); /*tmpFloat * sinf( binCenterFreq * EVS_PI / 550.0f ) / ( binCenterFreq * EVS_PI / 550.0f );*/ /* Q30 */
     243       19800 :         hDiracDecBin->diffuseFieldCoherence_fx[bin] = L_shl( hDiracDecBin->diffuseFieldCoherence_fx[bin], 1 );                                                                                                                                                                          /* Q31 */
     244       19800 :         move32();
     245       19800 :         move32();
     246             :     }
     247             : 
     248        4100 :     FOR( bin = 0; bin < BINAURAL_COHERENCE_DIFFERENCE_BINS; bin++ )
     249             :     {
     250        3690 :         hDiracDecBin->diffuseFieldCoherenceX_fx[bin] = L_add( hDiracDecBin->diffuseFieldCoherence_fx[bin], diffuseFieldCoherenceDifferenceX_fx[bin] );
     251        3690 :         hDiracDecBin->diffuseFieldCoherenceY_fx[bin] = L_add( hDiracDecBin->diffuseFieldCoherence_fx[bin], diffuseFieldCoherenceDifferenceY_fx[bin] );
     252        3690 :         hDiracDecBin->diffuseFieldCoherenceZ_fx[bin] = L_add( hDiracDecBin->diffuseFieldCoherence_fx[bin], diffuseFieldCoherenceDifferenceZ_fx[bin] );
     253        3690 :         move32();
     254        3690 :         move32();
     255        3690 :         move32();
     256             :     }
     257             : 
     258         410 :     IF( EQ_32( renderer_type, RENDERER_BINAURAL_PARAMETRIC ) ) /* Indication of binaural rendering without room effect */
     259             :     {
     260         128 :         set32_fx( hDiracDecBin->earlyPartEneCorrection_fx, ONE_IN_Q28, CLDFB_NO_CHANNELS_MAX );
     261         128 :         hDiracDecBin->q_earlyPartEneCorrection = Q28;
     262         128 :         move16();
     263         128 :         hDiracDecBin->hReverb = NULL;
     264             :     }
     265         282 :     ELSE IF( EQ_32( renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) /* Indication of binaural rendering with room effect */
     266             :     {
     267         271 :         Copy32( hHrtfParambin->parametricEarlyPartEneCorrection_fx, hDiracDecBin->earlyPartEneCorrection_fx, nBins );
     268         271 :         hDiracDecBin->q_earlyPartEneCorrection = Q28;
     269         271 :         move16();
     270             :         /* reconfiguration needed when Reverb. parameters are changed -> close and open the handle again */
     271         271 :         test();
     272         271 :         test();
     273         271 :         IF( hDiracDecBin->hReverb != NULL && ( ( NE_16( hDiracDecBin->hReverb->numBins, nBins ) ) ||
     274             :                                                ( NE_16( hDiracDecBin->hReverb->blockSize, CLDFB_SLOTS_PER_SUBFRAME ) ) ) )
     275             :         {
     276           0 :             ivas_binaural_reverb_close_fx( &( hDiracDecBin->hReverb ) );
     277             :         }
     278             : 
     279         271 :         IF( hDiracDecBin->hReverb == NULL )
     280             :         {
     281             :             /* Todo Philips: Room acoustics should be passed here once the underlying part works. Probably enough to pick it from st_ivas but you know best. */
     282         271 :             IF( NE_32( ( error = ivas_binaural_reverb_open_parambin( &hDiracDecBin->hReverb, nBins, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, NULL, output_Fs, st_ivas->hHrtfParambin ) ), IVAS_ERR_OK ) )
     283             :             {
     284           0 :                 return error;
     285             :             }
     286             :         }
     287             :     }
     288          11 :     ELSE IF( EQ_32( renderer_type, RENDERER_STEREO_PARAMETRIC ) )
     289             :     {
     290          11 :         set32_fx( hDiracDecBin->earlyPartEneCorrection_fx, ONE_IN_Q28, CLDFB_NO_CHANNELS_MAX );
     291          11 :         hDiracDecBin->q_earlyPartEneCorrection = Q28;
     292          11 :         hDiracDecBin->hReverb = NULL;
     293          11 :         hDiracDecBin->renderStereoOutputInsteadOfBinaural = 1;
     294          11 :         move16();
     295          11 :         move16();
     296             :     }
     297             :     ELSE /* Not valid renderer type for this renderer */
     298             :     {
     299           0 :         assert( false );
     300             :     }
     301             : 
     302         410 :     hDiracDecBin->hDiffuseDist = NULL; /* Memory is allocated from stack during runtime when needed */
     303             : 
     304         410 :     if ( hDiracDecBin->hTdDecorr == NULL )
     305             :     {
     306         410 :         hDiracDecBin->useTdDecorr = 0;
     307         410 :         move16();
     308             :     }
     309             : 
     310         410 :     IF( hDiracDecBin->h_freq_domain_decorr_ap_params != NULL )
     311             :     {
     312           0 :         ivas_dirac_dec_decorr_close_fx( &hDiracDecBin->h_freq_domain_decorr_ap_params, &hDiracDecBin->h_freq_domain_decorr_ap_state );
     313             :     }
     314             : 
     315         410 :     IF( NE_32( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( hDiracDecBin->hTdDecorr ), &( hDiracDecBin->useTdDecorr ) ) ), IVAS_ERR_OK ) )
     316             :     {
     317           0 :         return error;
     318             :     }
     319             : 
     320         410 :     test();
     321         410 :     test();
     322         410 :     IF( !hDiracDecBin->useTdDecorr && !( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) ) )
     323             :     {
     324             :         Word16 frequency_axis_fx[CLDFB_NO_CHANNELS_MAX];
     325         102 :         ivas_dirac_dec_get_frequency_axis_fx( frequency_axis_fx, output_Fs, nBins );
     326             : 
     327         102 :         IF( NE_32( ( error = ivas_dirac_dec_decorr_open_fx( &( hDiracDecBin->h_freq_domain_decorr_ap_params ),
     328             :                                                             &( hDiracDecBin->h_freq_domain_decorr_ap_state ),
     329             :                                                             nBins,
     330             :                                                             BINAURAL_CHANNELS,
     331             :                                                             BINAURAL_CHANNELS,
     332             :                                                             DIRAC_SYNTHESIS_PSD_LS,
     333             :                                                             frequency_axis_fx,
     334             :                                                             BINAURAL_CHANNELS,
     335             :                                                             output_Fs ) ),
     336             :                    IVAS_ERR_OK ) )
     337             :         {
     338           0 :             return error;
     339             :         }
     340             :     }
     341             : 
     342         410 :     hDiracDecBin->reqularizationFactor_fx = configure_reqularization_factor_fx( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate ); /* Q14 */
     343         410 :     move16();
     344             : 
     345         410 :     st_ivas->hDiracDecBin = hDiracDecBin;
     346             : 
     347             :     /* allocate transport channels */
     348         410 :     IF( st_ivas->hTcBuffer == NULL )
     349             :     {
     350             :         Word16 nchan_to_allocate;
     351             :         Word16 n_samples_granularity;
     352             : 
     353          60 :         nchan_to_allocate = 2 * BINAURAL_CHANNELS;
     354          60 :         move16();
     355          60 :         if ( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
     356             :         {
     357          15 :             nchan_to_allocate = 2 * BINAURAL_CHANNELS + 2;
     358          15 :             move16();
     359             :         }
     360             : 
     361          60 :         n_samples_granularity = NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS );
     362          60 :         test();
     363          60 :         test();
     364          60 :         IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) && EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) && EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
     365             :         {
     366           1 :             n_samples_granularity = NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ); /* Use the same granularity as tdrend */
     367             :         }
     368             : 
     369          60 :         IF( NE_32( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, TC_BUFFER_MODE_RENDERER, ivas_jbm_dec_get_num_tc_channels_fx( st_ivas ), nchan_to_allocate, nchan_to_allocate, n_samples_granularity ) ), IVAS_ERR_OK ) )
     370             :         {
     371           0 :             return error;
     372             :         }
     373             :     }
     374         410 :     return IVAS_ERR_OK;
     375             : }
     376             : 
     377             : /*-------------------------------------------------------------------------
     378             :  * ivas_dirac_dec_close_binaural_data()
     379             :  *
     380             :  * Close parametric binaural renderer
     381             :  *------------------------------------------------------------------------*/
     382        3012 : void ivas_dirac_dec_close_binaural_data(
     383             :     DIRAC_DEC_BIN_HANDLE *hBinaural /* i/o: decoder DirAC binaural data handle  */
     384             : )
     385             : {
     386             : 
     387        3012 :     test();
     388        3012 :     IF( hBinaural == NULL || *hBinaural == NULL )
     389             :     {
     390        2590 :         return;
     391             :     }
     392             : 
     393         422 :     IF( ( *hBinaural )->hReverb != NULL )
     394             :     {
     395         271 :         ivas_binaural_reverb_close_fx( &( ( *hBinaural )->hReverb ) );
     396             :     }
     397             : 
     398         422 :     ivas_td_decorr_dec_close( &( ( *hBinaural )->hTdDecorr ) );
     399         422 :     IF( ( *hBinaural )->h_freq_domain_decorr_ap_params != NULL )
     400             :     {
     401         119 :         ivas_dirac_dec_decorr_close_fx( &( *hBinaural )->h_freq_domain_decorr_ap_params, &( *hBinaural )->h_freq_domain_decorr_ap_state );
     402             :     }
     403             : 
     404         422 :     free( *hBinaural );
     405         422 :     *hBinaural = NULL;
     406             : 
     407         422 :     return;
     408             : }
     409             : /*-------------------------------------------------------------------------
     410             :  * ivas_dirac_dec_binaural_copy_hrtfs()
     411             :  *
     412             :  * Temporary function for copying HRTF data from rom tables if no binary
     413             :  * file was given.
     414             :  *------------------------------------------------------------------------*/
     415        1529 : ivas_error ivas_dirac_dec_binaural_copy_hrtfs_fx(
     416             :     HRTFS_PARAMBIN_HANDLE *hHrtfParambin /* i/o: HRTF structure for rendering */
     417             : )
     418             : {
     419             :     Word16 i, j;
     420        1529 :     test();
     421        1529 :     IF( hHrtfParambin != NULL && *hHrtfParambin != NULL )
     422             :     {
     423             :         /* Tables already loaded from file */
     424        1427 :         return IVAS_ERR_OK;
     425             :     }
     426             :     ELSE
     427             :     {
     428             :         /* Initialise tables from ROM */
     429             :         HRTFS_PARAMBIN *hrtfParambin;
     430         102 :         IF( ( hrtfParambin = (HRTFS_PARAMBIN *) malloc( sizeof( HRTFS_PARAMBIN ) ) ) == NULL )
     431             :         {
     432           0 :             return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate memory for parametric binauralizer HRTF tables" );
     433             :         }
     434         306 :         FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
     435             :         {
     436        3468 :             FOR( j = 0; j < HRTF_SH_CHANNELS; j++ )
     437             :             {
     438        3264 :                 Copy( hrtfShCoeffsRe_fx[i][j], hrtfParambin->hrtfShCoeffsRe_fx[i][j], HRTF_NUM_BINS ); /*Q14*/
     439        3264 :                 Copy( hrtfShCoeffsIm_fx[i][j], hrtfParambin->hrtfShCoeffsIm_fx[i][j], HRTF_NUM_BINS ); /*Q14*/
     440             :             }
     441             :         }
     442         102 :         Copy32( parametricReverberationTimes_fx, hrtfParambin->parametricReverberationTimes_fx, CLDFB_NO_CHANNELS_MAX );                   /*Q31*/
     443         102 :         Copy32( parametricReverberationEneCorrections_fx, hrtfParambin->parametricReverberationEneCorrections_fx, CLDFB_NO_CHANNELS_MAX ); /*Q31*/
     444         102 :         Copy32( parametricEarlyPartEneCorrection_fx, hrtfParambin->parametricEarlyPartEneCorrection_fx, CLDFB_NO_CHANNELS_MAX );           /*Q28*/
     445         102 :         *hHrtfParambin = hrtfParambin;
     446             :     }
     447             : 
     448         102 :     return IVAS_ERR_OK;
     449             : }
     450             : 
     451             : 
     452             : /*-------------------------------------------------------------------------
     453             :  * void ivas_dirac_dec_binaural_render_fx()
     454             :  *
     455             :  *
     456             :  *------------------------------------------------------------------------*/
     457       70018 : void ivas_dirac_dec_binaural_render_fx(
     458             :     Decoder_Struct *st_ivas,      /* i/o: IVAS decoder handle                      */
     459             :     const UWord16 nSamplesAsked,  /* i  : number of CLDFB slots requested          */
     460             :     UWord16 *nSamplesRendered,    /* o  : number of CLDFB slots rendered           */
     461             :     UWord16 *nSamplesAvailable,   /* o  : number of CLDFB slots still to render    */
     462             :     const Word16 nchan_transport, /* i  : number of transport channels             */
     463             :     Word32 *output_f[]            /* o  : rendered time signal, Q11                */
     464             : )
     465             : {
     466             :     Word16 slots_to_render, first_sf, last_sf, subframe_idx;
     467             :     UWord16 slot_size, ch;
     468             :     UWord16 nchan_out;
     469             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
     470             :     Word32 *output_fx_local[MAX_OUTPUT_CHANNELS];
     471             :     Word32 output_fx_local_buff[MAX_OUTPUT_CHANNELS][L_FRAME48k];
     472             :     Word16 output_length;
     473             : 
     474       70018 :     hSpatParamRendCom = st_ivas->hSpatParamRendCom;
     475       70018 :     nchan_out = BINAURAL_CHANNELS;
     476       70018 :     move16();
     477      210054 :     FOR( ch = 0; ch < nchan_out; ch++ )
     478             :     {
     479      140036 :         output_fx_local[ch] = output_fx_local_buff[ch];
     480             :     }
     481       70018 :     slot_size = NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS );
     482             : 
     483             :     /* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */
     484       70018 :     slots_to_render = s_min( sub( hSpatParamRendCom->num_slots, hSpatParamRendCom->slots_rendered ), idiv1616( (Word16) nSamplesAsked, (Word16) slot_size ) );
     485       70018 :     *nSamplesRendered = imult1616( slots_to_render, slot_size );
     486       70018 :     move16();
     487       70018 :     first_sf = hSpatParamRendCom->subframes_rendered;
     488       70018 :     last_sf = first_sf;
     489       70018 :     move16();
     490       70018 :     move16();
     491             : 
     492      337830 :     WHILE( slots_to_render > 0 )
     493             :     {
     494      267812 :         slots_to_render = sub( slots_to_render, hSpatParamRendCom->subframe_nbslots[last_sf] );
     495      267812 :         last_sf = add( last_sf, 1 );
     496             :     }
     497             : 
     498       70018 :     output_length = 0;
     499       70018 :     move16();
     500      337830 :     FOR( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ )
     501             :     {
     502      267812 :         Word16 n_samples_sf = imult1616( slot_size, hSpatParamRendCom->subframe_nbslots[subframe_idx] );
     503      267812 :         ivas_dirac_dec_binaural_internal_fx( st_ivas, st_ivas->hCombinedOrientationData, output_fx_local, nchan_transport, subframe_idx );
     504             : 
     505      803436 :         FOR( ch = 0; ch < nchan_out; ch++ )
     506             :         {
     507      535624 :             output_fx_local[ch] += n_samples_sf;
     508             :         }
     509             : 
     510      267812 :         output_length = add( output_length, n_samples_sf );
     511             : 
     512             :         /* update combined orientation access index */
     513      267812 :         ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_sf );
     514             :     }
     515             : 
     516      210054 :     FOR( ch = 0; ch < nchan_out; ch++ )
     517             :     {
     518      140036 :         Copy32( output_fx_local_buff[ch], output_f[ch], output_length );
     519             :     }
     520             : 
     521       70018 :     IF( EQ_16( hSpatParamRendCom->slots_rendered, hSpatParamRendCom->num_slots ) )
     522             :     {
     523       66517 :         hSpatParamRendCom->dirac_read_idx = add( hSpatParamRendCom->dirac_read_idx, DEFAULT_JBM_SUBFRAMES_5MS ) % hSpatParamRendCom->dirac_md_buffer_length;
     524       66517 :         move16();
     525             :     }
     526             : 
     527       70018 :     *nSamplesAvailable = imult1616( sub( hSpatParamRendCom->num_slots, hSpatParamRendCom->slots_rendered ), slot_size );
     528       70018 :     move16();
     529             : 
     530       70018 :     return;
     531             : }
     532             : 
     533             : /*-------------------------------------------------------------------------
     534             :  * ivas_dirac_dec_binaural_sba_gain()
     535             :  *
     536             :  * loudness correction for parametric binaural renderer
     537             :  *------------------------------------------------------------------------*/
     538       45009 : void ivas_dirac_dec_binaural_sba_gain_fx(
     539             :     Word32 *output[],            /* i/o: synthesized core-coder transport channels/DirAC output, inp Qx, out Qx-1    */
     540             :     const Word16 nchan_remapped, /* i  : num channels after remapping of TCs                                         */
     541             :     const Word16 output_frame    /* i  : output frame length                                                         */
     542             : )
     543             : {
     544             :     Word16 n;
     545             :     Word16 gain; /*Q-14*/
     546             : 
     547       45009 :     IF( EQ_16( nchan_remapped, 1 ) )
     548             :     {
     549       15805 :         gain = 23681; /*Q14*/
     550       15805 :         move16();
     551             :     }
     552             :     ELSE
     553             :     {
     554       29204 :         gain = 22376; /*Q14*/
     555       29204 :         move16();
     556             :     }
     557             : 
     558      119222 :     FOR( n = 0; n < nchan_remapped; n++ )
     559             :     {
     560       74213 :         v_multc_fixed_16( output[n], gain, output[n], output_frame ); /* Qx to Qx-1*/
     561             :     }
     562             : 
     563       45009 :     return;
     564             : }
     565             : 
     566             : 
     567             : /*-------------------------------------------------------------------------
     568             :  * Local functions
     569             :  *------------------------------------------------------------------------*/
     570      267812 : static void ivas_dirac_dec_binaural_internal_fx(
     571             :     Decoder_Struct *st_ivas,
     572             :     COMBINED_ORIENTATION_HANDLE hCombinedOrientationData,
     573             :     Word32 *output_fx[], /*Q11*/
     574             :     const Word16 nchan_transport,
     575             :     const Word16 subframe )
     576             : {
     577      267812 :     Word16 q_input = 11;
     578      267812 :     move16();
     579      267812 :     IF( st_ivas->hSCE[0] )
     580             :     {
     581      154288 :         Word16 shift = getScaleFactor32( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevel, FFTCLDFBLEN );
     582      154288 :         IF( LT_16( sub( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevelExp, shift ), 4 ) )
     583             :         {
     584       11303 :             shift = sub( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevelExp, 4 );
     585             :         }
     586      154288 :         scale_sig32( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevel, FFTCLDFBLEN, shift );
     587      154288 :         st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevelExp = sub( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->cngNoiseLevelExp, shift );
     588      154288 :         move16();
     589             :     }
     590             :     Word16 q_cldfb[6][CLDFB_SLOTS_PER_SUBFRAME];
     591     1874684 :     FOR( Word16 ind = 0; ind < 6; ind++ )
     592             :     {
     593     8034360 :         FOR( Word16 ind2 = 0; ind2 < 4; ind2++ )
     594             :         {
     595     6427488 :             q_cldfb[ind][ind2] = q_input;
     596     6427488 :             move16();
     597             :         }
     598             :     }
     599      267812 :     Word16 q_cldfb_temp = sub( q_input, 1 );
     600             :     DIRAC_DEC_BIN_HANDLE hDiracDecBin;
     601             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
     602             :     PARAMBIN_REND_CONFIG config_data;
     603             :     Word16 slot, ch, numInChannels;
     604             :     Word32 Cldfb_RealBuffer_in_fx[6][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
     605             :     Word32 Cldfb_ImagBuffer_in_fx[6][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
     606             :     Word16 nchanSeparateChannels;
     607             :     Word32 Rmat_fx[3][3];
     608             :     Word16 max_band_decorr;
     609             :     DIFFUSE_DISTRIBUTION_DATA diffuseDistData;
     610             :     Word16 nBins, offsetSamples;
     611             :     Word16 i, j;
     612             :     Word16 q_mat, q_out;
     613      267812 :     hDiracDecBin = st_ivas->hDiracDecBin;
     614      267812 :     assert( hDiracDecBin );
     615      267812 :     hSpatParamRendCom = st_ivas->hSpatParamRendCom;
     616      267812 :     nBins = hSpatParamRendCom->num_freq_bands;
     617      267812 :     move16();
     618      267812 :     offsetSamples = imult1616( hSpatParamRendCom->slots_rendered, nBins );
     619             :     Word32 tmp_arr[CLDFB_NO_CHANNELS_MAX];
     620             :     /* Setup internal config */
     621      267812 :     config_data.separateCenterChannelRendering = st_ivas->hOutSetup.separateChannelEnabled;
     622      267812 :     move16();
     623      267812 :     config_data.ivas_format = st_ivas->ivas_format;
     624      267812 :     move32();
     625      267812 :     config_data.mc_mode = st_ivas->mc_mode;
     626      267812 :     move32();
     627      267812 :     config_data.ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
     628      267812 :     move32();
     629      267812 :     config_data.nchan_transport = st_ivas->nchan_transport;
     630      267812 :     move16();
     631      267812 :     IF( st_ivas->hMasa != NULL )
     632             :     {
     633       86267 :         config_data.qualityBasedSmFactor_fx = L_deposit_h( st_ivas->hMasa->data.dir_decode_quality_fx ); // Q31
     634             :     }
     635             :     ELSE
     636             :     {
     637      181545 :         config_data.qualityBasedSmFactor_fx = ONE_IN_Q31;
     638             :     }
     639      267812 :     move32();
     640      267812 :     IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) )
     641             :     {
     642      112977 :         config_data.processReverb = 1;
     643             :     }
     644             :     ELSE
     645             :     {
     646      154835 :         config_data.processReverb = 0;
     647             :     }
     648      267812 :     move16();
     649      267812 :     IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
     650             :     {
     651        9985 :         config_data.ism_mode = st_ivas->ism_mode;
     652             :     }
     653             :     ELSE
     654             :     {
     655      257827 :         config_data.ism_mode = ISM_MODE_NONE;
     656             :     }
     657      267812 :     move32();
     658             : 
     659             :     /* The input channel number at this processing function (not nchan_transport) */
     660      267812 :     numInChannels = BINAURAL_CHANNELS;
     661      267812 :     move16();
     662      267812 :     test();
     663      267812 :     test();
     664      267812 :     test();
     665      267812 :     test();
     666      267812 :     test();
     667      267812 :     test();
     668      267812 :     IF( config_data.separateCenterChannelRendering || ( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) && ( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) ) ) )
     669             :     {
     670        6735 :         numInChannels = add( numInChannels, 1 );
     671             :     }
     672      261077 :     ELSE IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) && ( EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) )
     673             :     {
     674        2918 :         numInChannels = add( numInChannels, st_ivas->nchan_ism );
     675             :     }
     676             : 
     677      267812 :     Rmat_fx[0][0] = ONE_IN_Q30;
     678      267812 :     Rmat_fx[0][1] = 0;
     679      267812 :     Rmat_fx[0][2] = 0;
     680      267812 :     move32();
     681      267812 :     move32();
     682      267812 :     move32();
     683             : 
     684      267812 :     Rmat_fx[1][0] = 0;
     685      267812 :     Rmat_fx[1][1] = ONE_IN_Q30;
     686      267812 :     Rmat_fx[1][2] = 0;
     687      267812 :     move32();
     688      267812 :     move32();
     689      267812 :     move32();
     690             : 
     691      267812 :     Rmat_fx[2][0] = 0;
     692      267812 :     Rmat_fx[2][1] = 0;
     693      267812 :     Rmat_fx[2][2] = ONE_IN_Q30;
     694      267812 :     move32();
     695      267812 :     move32();
     696      267812 :     move32();
     697      267812 :     Word16 ch_len = s_max( 4, numInChannels );
     698     1874684 :     FOR( i = 0; i < 6; i++ )
     699             :     {
     700     8034360 :         FOR( j = 0; j < 4; j++ )
     701             :         {
     702     6427488 :             set32_fx( Cldfb_RealBuffer_in_fx[i][j], 0, 60 );
     703     6427488 :             set32_fx( Cldfb_ImagBuffer_in_fx[i][j], 0, 60 );
     704             :         }
     705             :     }
     706             :     /* CLDFB Analysis of input */
     707     1332133 :     FOR( slot = 0; slot < hSpatParamRendCom->subframe_nbslots[subframe]; slot++ )
     708             :     {
     709     3249982 :         FOR( ch = 0; ch < numInChannels; ch++ )
     710             :         {
     711     2185661 :             test();
     712     2185661 :             IF( ch == 0 || EQ_16( nchan_transport, 2 ) )
     713             :             {
     714     1721786 :                 q_cldfb[ch][slot] = q_cldfb_temp;
     715     1721786 :                 move16();
     716     1721786 :                 Copy_Scale_sig32( &( st_ivas->hTcBuffer->tc_fx[ch][nBins * slot + offsetSamples] ), tmp_arr, nBins, -1 );
     717     1721786 :                 scale_sig32( st_ivas->cldfbAnaDec[ch]->cldfb_state_fx, sub( st_ivas->cldfbAnaDec[ch]->p_filter_length, st_ivas->cldfbAnaDec[ch]->no_channels ), sub( q_cldfb_temp, st_ivas->cldfbAnaDec[ch]->Q_cldfb_state ) );
     718     1721786 :                 cldfbAnalysis_ts_fx_fixed_q(
     719             :                     tmp_arr,
     720     1721786 :                     Cldfb_RealBuffer_in_fx[ch][slot],
     721     1721786 :                     Cldfb_ImagBuffer_in_fx[ch][slot],
     722     1721786 :                     nBins, st_ivas->cldfbAnaDec[ch], &q_cldfb[ch][slot] );
     723     1721786 :                 scale_sig32( st_ivas->cldfbAnaDec[ch]->cldfb_state_fx, sub( st_ivas->cldfbAnaDec[ch]->p_filter_length, st_ivas->cldfbAnaDec[ch]->no_channels ), sub( q_input, st_ivas->cldfbAnaDec[ch]->Q_cldfb_state ) );
     724     1721786 :                 st_ivas->cldfbAnaDec[ch]->Q_cldfb_state = q_input;
     725     1721786 :                 scale_sig32( Cldfb_RealBuffer_in_fx[ch][slot], nBins, 1 ); // Q6
     726     1721786 :                 scale_sig32( Cldfb_ImagBuffer_in_fx[ch][slot], nBins, 1 ); // Q6
     727     1721786 :                 q_cldfb[ch][slot] = add( q_cldfb[ch][slot], 1 );
     728     1721786 :                 move16();
     729             :             }
     730      463875 :             ELSE IF( EQ_16( config_data.nchan_transport, 2 ) ) /* Stereo signal transmitted as mono with DFT stereo */
     731             :             {
     732             :                 /* At mono input duplicate the channel to dual-mono  */
     733       19402 :                 Copy32( Cldfb_RealBuffer_in_fx[0][slot], Cldfb_RealBuffer_in_fx[1][slot], nBins );
     734       19402 :                 Copy32( Cldfb_ImagBuffer_in_fx[0][slot], Cldfb_ImagBuffer_in_fx[1][slot], nBins );
     735       19402 :                 q_cldfb[1][slot] = q_cldfb[0][slot];
     736       19402 :                 move16();
     737             :             }
     738             :             ELSE /* when nchan_transport == 1 and ch == 1 */
     739             :             {
     740             :                 /* CNA and HB FD-CNG*/
     741      444473 :                 test();
     742      444473 :                 IF( st_ivas->hSCE[0]->hCoreCoder[0] != NULL && st_ivas->hSCE[0]->hCoreCoder[0]->cng_sba_flag )
     743      216572 :                 {
     744             :                     Word16 numCoreBands, b;
     745             :                     Word16 slotInFrame;
     746             : 
     747      216572 :                     numCoreBands = st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->numCoreBands;
     748      216572 :                     move16();
     749      216572 :                     slotInFrame = add( hSpatParamRendCom->slots_rendered, slot );
     750             : 
     751      649716 :                     generate_masking_noise_dirac_ivas_fx( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom,
     752             :                                                           st_ivas->cldfbAnaDec[1],
     753      216572 :                                                           st_ivas->hTcBuffer->tc_fx[nchan_transport],
     754      216572 :                                                           Cldfb_RealBuffer_in_fx[2][slot], Cldfb_ImagBuffer_in_fx[2][slot],
     755             :                                                           slotInFrame,
     756      216572 :                                                           st_ivas->hSCE[0]->hCoreCoder[0]->cna_dirac_flag && st_ivas->hSCE[0]->hCoreCoder[0]->flag_cna,
     757      216572 :                                                           ( st_ivas->hSCE[0]->hCoreCoder[0]->core_brate == FRAME_NO_DATA || st_ivas->hSCE[0]->hCoreCoder[0]->core_brate == SID_2k40 ) && ( st_ivas->hSCE[0]->hCoreCoder[0]->cng_type == FD_CNG ) && st_ivas->hSCE[0]->hCoreCoder[0]->cng_sba_flag,
     758      216572 :                                                           11, &q_cldfb[2][slot] );
     759             : 
     760      649716 :                     generate_masking_noise_dirac_ivas_fx( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom,
     761             :                                                           st_ivas->cldfbAnaDec[1], /*nothing will be analyzed, just get cnst*/
     762             :                                                           NULL,
     763      216572 :                                                           Cldfb_RealBuffer_in_fx[1][slot], Cldfb_ImagBuffer_in_fx[1][slot],
     764             :                                                           slotInFrame,
     765      216572 :                                                           st_ivas->hSCE[0]->hCoreCoder[0]->cna_dirac_flag && st_ivas->hSCE[0]->hCoreCoder[0]->flag_cna,
     766      216572 :                                                           ( st_ivas->hSCE[0]->hCoreCoder[0]->core_brate == FRAME_NO_DATA || st_ivas->hSCE[0]->hCoreCoder[0]->core_brate == SID_2k40 ) && ( st_ivas->hSCE[0]->hCoreCoder[0]->cng_type == FD_CNG ) && st_ivas->hSCE[0]->hCoreCoder[0]->cng_sba_flag,
     767      216572 :                                                           0, &q_cldfb[1][slot] );
     768             : 
     769      216572 :                     scale_sig32( Cldfb_RealBuffer_in_fx[1][slot], CLDFB_NO_CHANNELS_MAX, negate( add( sub( q_cldfb[1][slot], q_input ), 5 ) ) );
     770      216572 :                     scale_sig32( Cldfb_ImagBuffer_in_fx[1][slot], CLDFB_NO_CHANNELS_MAX, negate( add( sub( q_cldfb[1][slot], q_input ), 5 ) ) );
     771             : 
     772             :                     /* LB: Copy first channel + LB-CNG to first and second channels with same scaling (dual-mono)*/
     773     4486700 :                     FOR( b = 0; b < numCoreBands; b++ )
     774             :                     {
     775     4270128 :                         Cldfb_RealBuffer_in_fx[0][slot][b] = Mpy_32_16_1( L_add( L_shr( Cldfb_RealBuffer_in_fx[0][slot][b], add( sub( q_cldfb[0][slot], q_input ), 5 ) ), L_shr( Cldfb_RealBuffer_in_fx[2][slot][b], add( sub( q_cldfb[2][slot], q_input ), 5 ) ) ), 23170 /* INV_SQRT2 in Q15*/ );
     776     4270128 :                         Cldfb_RealBuffer_in_fx[1][slot][b] = Cldfb_RealBuffer_in_fx[0][slot][b];
     777     4270128 :                         move32();
     778     4270128 :                         move32();
     779     4270128 :                         Cldfb_ImagBuffer_in_fx[0][slot][b] = Mpy_32_16_1( L_add( L_shr( Cldfb_ImagBuffer_in_fx[0][slot][b], add( sub( q_cldfb[0][slot], q_input ), 5 ) ), L_shr( Cldfb_ImagBuffer_in_fx[2][slot][b], add( sub( q_cldfb[2][slot], q_input ), 5 ) ) ), 23170 );
     780     4270128 :                         Cldfb_ImagBuffer_in_fx[1][slot][b] = Cldfb_ImagBuffer_in_fx[0][slot][b];
     781     4270128 :                         move32();
     782     4270128 :                         move32();
     783             :                     }
     784      216572 :                     q_cldfb[1][slot] = sub( q_input, 5 );
     785      216572 :                     q_cldfb[0][slot] = sub( q_input, 5 );
     786      216572 :                     move16();
     787      216572 :                     move16();
     788             :                     /* HB: Copy first channel to second channel and add HB-CNGs with different scalings*/
     789     8287964 :                     FOR( ; b < nBins; b++ )
     790             :                     {
     791     8071392 :                         Cldfb_RealBuffer_in_fx[0][slot][b] = Mpy_32_16_1( Cldfb_RealBuffer_in_fx[0][slot][b], 23170 );
     792     8071392 :                         Cldfb_RealBuffer_in_fx[1][slot][b] = L_add( L_add( Cldfb_RealBuffer_in_fx[0][slot][b], L_shr( Cldfb_RealBuffer_in_fx[1][slot][b], 1 ) ), Cldfb_RealBuffer_in_fx[0][slot][b] );
     793     8071392 :                         Cldfb_RealBuffer_in_fx[0][slot][b] = L_add( Cldfb_RealBuffer_in_fx[0][slot][b], L_shr( Cldfb_RealBuffer_in_fx[2][slot][b], 1 ) );
     794             : 
     795     8071392 :                         Cldfb_ImagBuffer_in_fx[0][slot][b] = Mpy_32_16_1( Cldfb_ImagBuffer_in_fx[0][slot][b], 23170 );
     796     8071392 :                         Cldfb_ImagBuffer_in_fx[1][slot][b] = L_add( Cldfb_ImagBuffer_in_fx[0][slot][b], L_shr( Cldfb_ImagBuffer_in_fx[1][slot][b], 1 ) );
     797     8071392 :                         Cldfb_ImagBuffer_in_fx[0][slot][b] = L_add( Cldfb_ImagBuffer_in_fx[0][slot][b], L_shr( Cldfb_ImagBuffer_in_fx[2][slot][b], 1 ) );
     798     8071392 :                         move32();
     799     8071392 :                         move32();
     800     8071392 :                         move32();
     801     8071392 :                         move32();
     802     8071392 :                         move32();
     803     8071392 :                         move32();
     804             :                     }
     805             :                 }
     806             :                 ELSE
     807             :                 {
     808             :                     /* At mono input duplicate the channel to dual-mono, and apply gain
     809             :                     correction to ensure same overall level as in stereo mode  */
     810      227901 :                     v_multc_fixed_16( Cldfb_RealBuffer_in_fx[0][slot], 23170, Cldfb_RealBuffer_in_fx[0][slot], nBins );
     811      227901 :                     v_multc_fixed_16( Cldfb_ImagBuffer_in_fx[0][slot], 23170, Cldfb_ImagBuffer_in_fx[0][slot], nBins );
     812             : 
     813      227901 :                     Copy32( Cldfb_RealBuffer_in_fx[0][slot], Cldfb_RealBuffer_in_fx[1][slot], nBins );
     814      227901 :                     Copy32( Cldfb_ImagBuffer_in_fx[0][slot], Cldfb_ImagBuffer_in_fx[1][slot], nBins );
     815      227901 :                     q_cldfb[1][slot] = q_cldfb[0][slot];
     816      227901 :                     move16();
     817             :                 }
     818             :             }
     819             :         }
     820             : 
     821     1064321 :         IF( hDiracDecBin->useTdDecorr )
     822             :         {
     823     1227381 :             FOR( ch = BINAURAL_CHANNELS; ch < ( 2 * BINAURAL_CHANNELS ); ch++ )
     824             :             {
     825      818254 :                 q_cldfb[ch][slot] = sub( q_input, 1 );
     826      818254 :                 move16();
     827             : 
     828      818254 :                 Copy_Scale_sig32( &( st_ivas->hTcBuffer->tc_fx[ch][nBins * slot + offsetSamples] ), tmp_arr, 60, -1 );
     829      818254 :                 scale_sig32( st_ivas->cldfbAnaDec[ch]->cldfb_state_fx, sub( st_ivas->cldfbAnaDec[ch]->p_filter_length, st_ivas->cldfbAnaDec[ch]->no_channels ), sub( sub( q_input, 1 ), st_ivas->cldfbAnaDec[ch]->Q_cldfb_state ) );
     830      818254 :                 st_ivas->cldfbAnaDec[ch]->Q_cldfb_state = sub( q_input, 1 );
     831      818254 :                 move16();
     832             : 
     833      818254 :                 cldfbAnalysis_ts_fx_fixed_q(
     834             :                     tmp_arr,
     835      818254 :                     Cldfb_RealBuffer_in_fx[ch][slot],
     836      818254 :                     Cldfb_ImagBuffer_in_fx[ch][slot],
     837      818254 :                     nBins, st_ivas->cldfbAnaDec[ch], &q_cldfb[ch][slot] );
     838             : 
     839      818254 :                 scale_sig32( st_ivas->cldfbAnaDec[ch]->cldfb_state_fx, sub( st_ivas->cldfbAnaDec[ch]->p_filter_length, st_ivas->cldfbAnaDec[ch]->no_channels ), sub( q_input, st_ivas->cldfbAnaDec[ch]->Q_cldfb_state ) );
     840      818254 :                 st_ivas->cldfbAnaDec[ch]->Q_cldfb_state = q_input;
     841      818254 :                 move16();
     842             : 
     843      818254 :                 test();
     844      818254 :                 test();
     845      818254 :                 IF( EQ_16( config_data.nchan_transport, 1 ) &&
     846             :                     ( EQ_32( config_data.ivas_format, SBA_FORMAT ) || EQ_32( config_data.ivas_format, SBA_ISM_FORMAT ) ) )
     847             :                 {
     848      505722 :                     v_multc_fixed_16( Cldfb_RealBuffer_in_fx[ch][slot], 23170, Cldfb_RealBuffer_in_fx[ch][slot], nBins );
     849      505722 :                     v_multc_fixed_16( Cldfb_ImagBuffer_in_fx[ch][slot], 23170, Cldfb_ImagBuffer_in_fx[ch][slot], nBins );
     850             :                 }
     851             :             }
     852             :         }
     853             :     }
     854             : 
     855      267812 :     test();
     856      267812 :     IF( EQ_32( config_data.ivas_format, SBA_FORMAT ) || EQ_32( config_data.ivas_format, SBA_ISM_FORMAT ) )
     857             :     {
     858      149652 :         hDiracDecBin->hDiffuseDist = &diffuseDistData;
     859      149652 :         ivas_spar_param_to_masa_param_mapping_fx( st_ivas, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, q_cldfb, subframe );
     860             : 
     861      149652 :         Scale_sig( st_ivas->hSpar->hFbMixer->cldfb_cross_fade_fx, CLDFB_NO_COL_MAX, Q15 - st_ivas->hSpar->hFbMixer->cldfb_cross_fade_q );
     862      149652 :         st_ivas->hSpar->hFbMixer->cldfb_cross_fade_q = Q15;
     863      149652 :         move16();
     864      149652 :         ivas_sba_prototype_renderer_fx( st_ivas, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, q_cldfb, subframe );
     865             :     }
     866             : 
     867      267812 :     Word16 q_inp = Q6;
     868      267812 :     move16();
     869     1341188 :     FOR( Word16 cha = 0; cha < ch_len; cha++ )
     870             :     {
     871     5366880 :         FOR( slot = 0; slot < 4; slot++ )
     872             :         {
     873     4293504 :             Word16 q_diff = sub( q_inp, q_cldfb[cha][slot] );
     874     4293504 :             IF( q_diff != 0 )
     875             :             {
     876     3293519 :                 Scale_sig32( Cldfb_RealBuffer_in_fx[cha][slot], 60, q_diff ); // Q6
     877     3293519 :                 Scale_sig32( Cldfb_ImagBuffer_in_fx[cha][slot], 60, q_diff ); // Q6
     878     3293519 :                 q_cldfb[cha][slot] = 6;
     879             :             }
     880     4293504 :             move16();
     881             :         }
     882             :     }
     883             : 
     884      267812 :     test();
     885      267812 :     test();
     886      267812 :     test();
     887      267812 :     IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) && EQ_16( nchan_transport, 2 ) && NE_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) && NE_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
     888             :     {
     889             :         /* Un-tested function. No test-case is hitting.*/
     890        2391 :         ivas_omasa_preProcessStereoTransportsForMovedObjects_fx( st_ivas, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, &q_inp, nBins, subframe );
     891             :     }
     892             : 
     893      267812 :     IF( hCombinedOrientationData )
     894             :     {
     895      402560 :         FOR( i = 0; i < 3; i++ )
     896             :         {
     897     1207680 :             FOR( j = 0; j < 3; j++ )
     898             :             {
     899      905760 :                 Rmat_fx[i][j] = hCombinedOrientationData->Rmat_fx[hCombinedOrientationData->subframe_idx][i][j]; // Q30//
     900      905760 :                 move32();
     901             :             }
     902             :         }
     903             : 
     904      100640 :         IF( EQ_16( nchan_transport, 2 ) )
     905             :         {
     906       70800 :             adaptTransportSignalsHeadtracked_fx( hCombinedOrientationData, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, q_inp, nBins, hSpatParamRendCom->subframe_nbslots[subframe], Rmat_fx );
     907       70800 :             ivas_dirac_dec_binaural_check_and_switch_transports_headtracked_fx( hCombinedOrientationData, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, nBins, hSpatParamRendCom->subframe_nbslots[subframe], Rmat_fx );
     908             :         }
     909             :     }
     910             : 
     911      267812 :     test();
     912      267812 :     ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, Rmat_fx, subframe, hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, st_ivas->hMasaIsmData, q_inp );
     913             : 
     914      267812 :     IF( EQ_32( config_data.ivas_format, ISM_FORMAT ) )
     915             :     {
     916       31893 :         max_band_decorr = 0;
     917       31893 :         move16();
     918             :     }
     919      235919 :     ELSE IF( hDiracDecBin->useTdDecorr )
     920             :     {
     921      103536 :         max_band_decorr = CLDFB_NO_CHANNELS_MAX;
     922      103536 :         move16();
     923             :     }
     924             :     ELSE
     925             :     {
     926      132383 :         max_band_decorr = hDiracDecBin->h_freq_domain_decorr_ap_params->max_band_decorr;
     927      132383 :         move16();
     928             :     }
     929             : 
     930             : 
     931      267812 :     nchanSeparateChannels = 0;
     932      267812 :     move16();
     933      267812 :     test();
     934      267812 :     test();
     935      267812 :     test();
     936      267812 :     test();
     937      267812 :     test();
     938      267812 :     test();
     939      267812 :     IF( config_data.separateCenterChannelRendering || ( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) && ( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) ) ) )
     940             :     {
     941        6735 :         nchanSeparateChannels = 1;
     942        6735 :         move16();
     943             :     }
     944      261077 :     ELSE IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) && ( EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) )
     945             :     {
     946        2918 :         nchanSeparateChannels = (UWord8) st_ivas->nchan_ism;
     947        2918 :         move16();
     948             :     }
     949             : 
     950      267812 :     ivas_dirac_dec_binaural_determine_processing_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, max_band_decorr, Rmat_fx, subframe, hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, nchanSeparateChannels, st_ivas->hMasaIsmData );
     951             : 
     952      267812 :     q_inp = Q6;
     953      267812 :     move16();
     954      803436 :     FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
     955             :     {
     956      535624 :         st_ivas->cldfbSynDec[ch]->Q_cldfb_state = Q11;
     957      535624 :         move16();
     958             :     }
     959             : 
     960      267812 :     q_mat = hDiracDecBin->q_processMtx;
     961      267812 :     move16();
     962      267812 :     q_mat = s_min( q_mat, hDiracDecBin->q_processMtxPrev );
     963      267812 :     q_mat = s_min( q_mat, hDiracDecBin->q_processMtxDec );
     964      267812 :     q_mat = s_min( q_mat, hDiracDecBin->q_processMtxDecPrev );
     965             : 
     966      803436 :     FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
     967             :     {
     968     1606872 :         FOR( slot = 0; slot < BINAURAL_CHANNELS; slot++ )
     969             :         {
     970     1071248 :             Scale_sig( hDiracDecBin->processMtxRe_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) );               // scaling to q_mat
     971     1071248 :             Scale_sig( hDiracDecBin->processMtxIm_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) );               // scaling to q_mat
     972     1071248 :             Scale_sig( hDiracDecBin->processMtxRePrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) );       // scaling to q_mat
     973     1071248 :             Scale_sig( hDiracDecBin->processMtxImPrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) );       // scaling to q_mat
     974     1071248 :             Scale_sig( hDiracDecBin->processMtxDecRe_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDec ) );         // scaling to q_mat
     975     1071248 :             Scale_sig( hDiracDecBin->processMtxDecIm_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDec ) );         // scaling to q_mat
     976     1071248 :             Scale_sig( hDiracDecBin->processMtxDecRePrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDecPrev ) ); // scaling to q_mat
     977     1071248 :             Scale_sig( hDiracDecBin->processMtxDecImPrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDecPrev ) ); // scaling to q_mat
     978             :         }
     979      564322 :         FOR( slot = 0; slot < nchanSeparateChannels; slot++ )
     980             :         {
     981       28698 :             Scale_sig( hDiracDecBin->processMtxRe_fx[ch][slot + BINAURAL_CHANNELS], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) );         // scaling to q_mat
     982       28698 :             Scale_sig( hDiracDecBin->processMtxIm_fx[ch][slot + BINAURAL_CHANNELS], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) );         // scaling to q_mat
     983       28698 :             Scale_sig( hDiracDecBin->processMtxRePrev_fx[ch][slot + BINAURAL_CHANNELS], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); // scaling to q_mat
     984       28698 :             Scale_sig( hDiracDecBin->processMtxImPrev_fx[ch][slot + BINAURAL_CHANNELS], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); // scaling to q_mat
     985             :         }
     986             :     }
     987      267812 :     hDiracDecBin->q_processMtx = q_mat;
     988      267812 :     move16();
     989      267812 :     hDiracDecBin->q_processMtxPrev = q_mat;
     990      267812 :     move16();
     991      267812 :     hDiracDecBin->q_processMtxDec = q_mat;
     992      267812 :     move16();
     993      267812 :     hDiracDecBin->q_processMtxDecPrev = q_mat;
     994      267812 :     move16();
     995             : 
     996      267812 :     ivas_dirac_dec_binaural_process_output_fx( hDiracDecBin, hSpatParamRendCom, st_ivas->cldfbSynDec, output_fx, &q_out, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, q_inp, max_band_decorr, numInChannels, config_data.processReverb, subframe, q_mat );
     997             : 
     998      267812 :     hDiracDecBin->hDiffuseDist = NULL;
     999             : 
    1000      267812 :     hSpatParamRendCom->slots_rendered = add( hSpatParamRendCom->slots_rendered, hSpatParamRendCom->subframe_nbslots[subframe] );
    1001      267812 :     hSpatParamRendCom->subframes_rendered = add( hSpatParamRendCom->subframes_rendered, 1 );
    1002             : 
    1003      267812 :     move16();
    1004      267812 :     move16();
    1005      803436 :     FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
    1006             :     {
    1007      535624 :         scale_sig32( output_fx[ch], imult1616( nBins, hSpatParamRendCom->subframe_nbslots[subframe] ), sub( 11, q_out ) ); // Scaling to Q11
    1008      535624 :         scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->cldfb_size, sub( Q11, st_ivas->cldfbSynDec[ch]->Q_cldfb_state ) );
    1009      535624 :         st_ivas->cldfbSynDec[ch]->Q_cldfb_state = Q11;
    1010      535624 :         move16();
    1011             :     }
    1012             : 
    1013      267812 :     return;
    1014             : }
    1015             : 
    1016             : 
    1017      556721 : static void ivas_dirac_dec_decorrelate_slot_fx(
    1018             :     DIRAC_DEC_BIN_HANDLE hDiracDecBin,
    1019             :     const Word16 num_freq_bands,
    1020             :     const Word16 slot,
    1021             :     Word32 inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*q_inp*/
    1022             :     Word32 inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*q_inp*/
    1023             :     Word16 q_inp,
    1024             :     Word32 decRe[][CLDFB_NO_CHANNELS_MAX], /*q_inp*/
    1025             :     Word32 decIm[][CLDFB_NO_CHANNELS_MAX] /*q_inp*/ )
    1026             : {
    1027             :     Word16 offset, ch, bin;
    1028             :     Word32 onset_filter_fx[BINAURAL_CHANNELS * CLDFB_NO_CHANNELS_MAX];                     /* 2 ch, 60 bins */
    1029             :     Word32 decorrelatedFrameInterleaved_fx[2 * BINAURAL_CHANNELS * CLDFB_NO_CHANNELS_MAX]; /* 2 ch, real + imag, 60 bins */
    1030             :     Word32 protoFrame_fx[2 * BINAURAL_CHANNELS * CLDFB_NO_CHANNELS_MAX];                   /* 2 ch, real + imag, 60 bins */
    1031             :     Word16 q_decorrelatedFrameInterleaved, q_protoFrame;
    1032      556721 :     const Word16 protoIndexDir[BINAURAL_CHANNELS] = { 0, 1 };
    1033      556721 :     move16();
    1034      556721 :     q_protoFrame = q_inp;
    1035      556721 :     move16();
    1036             :     /* Decorrelation needs interleaved data. Copy left and right signals to proto_frame_f */
    1037     1670163 :     FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
    1038             :     {
    1039     1113442 :         offset = imult1616( imult1616( num_freq_bands, BINAURAL_CHANNELS ), ch );
    1040    53780602 :         FOR( bin = 0; bin < num_freq_bands; bin++ )
    1041             :         {
    1042    52667160 :             protoFrame_fx[add( imult1616( bin, BINAURAL_CHANNELS ), offset )] = inRe[ch][slot][bin];           // q_protoFrame
    1043    52667160 :             protoFrame_fx[add( imult1616( bin, BINAURAL_CHANNELS ), add( offset, 1 ) )] = inIm[ch][slot][bin]; // q_protoFrame
    1044    52667160 :             move32();
    1045    52667160 :             move32();
    1046             :         }
    1047             :     }
    1048             : 
    1049             :     /* Decorrelate proto signal to decorrelatedFrameInterleaved */
    1050      556721 :     ivas_dirac_dec_decorr_process_fx( num_freq_bands,
    1051             :                                       BINAURAL_CHANNELS,
    1052             :                                       BINAURAL_CHANNELS,
    1053             :                                       DIRAC_SYNTHESIS_PSD_LS,
    1054             :                                       BINAURAL_CHANNELS,
    1055             :                                       protoFrame_fx,
    1056             :                                       q_protoFrame,
    1057             :                                       BINAURAL_CHANNELS,
    1058             :                                       protoIndexDir,
    1059             :                                       decorrelatedFrameInterleaved_fx,
    1060             :                                       &q_decorrelatedFrameInterleaved,
    1061             :                                       onset_filter_fx,
    1062             :                                       hDiracDecBin->h_freq_domain_decorr_ap_params,
    1063             :                                       hDiracDecBin->h_freq_domain_decorr_ap_state );
    1064             : 
    1065             :     /* De-interleave decorrelated signals*/
    1066     1670163 :     FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
    1067             :     {
    1068     1113442 :         offset = imult1616( imult1616( num_freq_bands, BINAURAL_CHANNELS ), ch );
    1069    53780602 :         FOR( bin = 0; bin < num_freq_bands; bin++ )
    1070             :         {
    1071    52667160 :             decRe[ch][bin] = decorrelatedFrameInterleaved_fx[add( imult1616( bin, BINAURAL_CHANNELS ), offset )];           // q_inp
    1072    52667160 :             decIm[ch][bin] = decorrelatedFrameInterleaved_fx[add( imult1616( bin, BINAURAL_CHANNELS ), add( offset, 1 ) )]; // q_inp
    1073    52667160 :             move32();
    1074    52667160 :             move32();
    1075             :         }
    1076             :     }
    1077             :     // q_decorrelatedFrameInterleaved will be same as q_inp/q_protoFrame //
    1078      556721 :     return;
    1079             : }
    1080             : 
    1081      275012 : static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_fx(
    1082             :     DIRAC_DEC_BIN_HANDLE hDiracDecBin,
    1083             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom,
    1084             :     PARAMBIN_REND_CONFIG_HANDLE hConfig,
    1085             :     Word32 inRe_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*q*/
    1086             :     Word32 inIm_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*q*/
    1087             :     Word32 Rmat_fx[3][3],                                              /*Q30*/
    1088             :     const Word16 subframe,
    1089             :     const Word16 isHeadtracked,
    1090             :     const MASA_ISM_DATA_HANDLE hMasaIsmData,
    1091             :     Word16 q )
    1092             : {
    1093             :     Word16 ch, slot, bin;
    1094             :     Word16 separateCenterChannelRendering;
    1095             :     Word16 nBins, idx, shift;
    1096             :     Word32 frameMeanDiffusenessEneWeight_fx[CLDFB_NO_CHANNELS_MAX];
    1097             :     Word32 IIReneLimiterFactor_fx; // Q26
    1098             :     Word32 qualityBasedSmFactor_fx;
    1099             :     Word32 lowBitRateEQ_fx[CLDFB_NO_CHANNELS_MAX];
    1100             :     UWord8 applyLowBitRateEQ;
    1101             :     Word16 dirac_read_idx;
    1102             :     Word32 subFrameTotalEne_fx[CLDFB_NO_CHANNELS_MAX];
    1103             :     Word16 subFrameTotalEne_e[CLDFB_NO_CHANNELS_MAX];
    1104             :     PARAMBIN_HRTF_GAIN_CACHE gainCache[MAX_GAIN_CACHE_SIZE];
    1105             :     IVAS_FORMAT ivas_format;
    1106             :     MC_MODE mc_mode;
    1107             :     Word32 ivas_total_brate;
    1108             :     Word16 nchan_transport;
    1109             :     Word16 gainCacheBaseIndex;
    1110             :     Word16 q_earlyPartEneCorrection;
    1111             :     Word16 exp, exp1;
    1112             :     Word64 temp64;
    1113             :     Word32 temp;
    1114             : 
    1115      275012 :     separateCenterChannelRendering = hConfig->separateCenterChannelRendering;
    1116      275012 :     move16();
    1117      275012 :     ivas_format = hConfig->ivas_format;
    1118      275012 :     move32();
    1119      275012 :     mc_mode = hConfig->mc_mode;
    1120      275012 :     move32();
    1121      275012 :     ivas_total_brate = hConfig->ivas_total_brate;
    1122      275012 :     move32();
    1123      275012 :     nchan_transport = hConfig->nchan_transport;
    1124      275012 :     move16();
    1125      275012 :     qualityBasedSmFactor_fx = hConfig->qualityBasedSmFactor_fx; /*Q31*/
    1126      275012 :     move32();
    1127      275012 :     qualityBasedSmFactor_fx = Mpy_32_32( qualityBasedSmFactor_fx, qualityBasedSmFactor_fx ); /*Q31*/
    1128             : 
    1129      275012 :     nBins = hSpatParamRendCom->num_freq_bands; /* Actually bins */
    1130      275012 :     move16();
    1131             : 
    1132      275012 :     q_earlyPartEneCorrection = s_min( Q31, add( getScaleFactor32( hDiracDecBin->earlyPartEneCorrection_fx, nBins ), hDiracDecBin->q_earlyPartEneCorrection ) );
    1133      275012 :     scale_sig32( hDiracDecBin->earlyPartEneCorrection_fx, nBins, sub( q_earlyPartEneCorrection, hDiracDecBin->q_earlyPartEneCorrection ) );
    1134      275012 :     hDiracDecBin->q_earlyPartEneCorrection = q_earlyPartEneCorrection;
    1135      275012 :     move16();
    1136             : 
    1137      275012 :     set32_fx( hDiracDecBin->ChCrossRe_fx, 0, nBins );
    1138      275012 :     set32_fx( hDiracDecBin->ChCrossIm_fx, 0, nBins );
    1139      275012 :     set32_fx( hDiracDecBin->ChCrossReOut_fx, 0, nBins );
    1140      275012 :     set32_fx( hDiracDecBin->ChCrossImOut_fx, 0, nBins );
    1141             : 
    1142      275012 :     set16_fx( hDiracDecBin->ChCrossRe_e, 0, nBins );
    1143      275012 :     set16_fx( hDiracDecBin->ChCrossIm_e, 0, nBins );
    1144      275012 :     set16_fx( hDiracDecBin->ChCrossReOut_e, 0, nBins );
    1145      275012 :     set16_fx( hDiracDecBin->ChCrossImOut_e, 0, nBins );
    1146      825036 :     FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
    1147             :     {
    1148      550024 :         set32_fx( hDiracDecBin->ChEne_fx[ch], 0, nBins );
    1149      550024 :         set32_fx( hDiracDecBin->ChEneOut_fx[ch], 0, nBins );
    1150             : 
    1151      550024 :         set16_fx( hDiracDecBin->ChEne_e[ch], 0, nBins );
    1152      550024 :         set16_fx( hDiracDecBin->ChEneOut_e[ch], 0, nBins );
    1153             :     }
    1154      275012 :     set32_fx( hDiracDecBin->frameMeanDiffuseness_fx, 0, nBins );
    1155             : 
    1156      275012 :     set32_fx( frameMeanDiffusenessEneWeight_fx, 0, CLDFB_NO_CHANNELS_MAX );
    1157             : 
    1158      275012 :     set16_fx( subFrameTotalEne_e, 0, CLDFB_NO_CHANNELS_MAX );
    1159             : 
    1160     3025132 :     FOR( idx = 0; idx < MAX_GAIN_CACHE_SIZE; idx++ )
    1161             :     {
    1162     2750120 :         gainCache[idx].azi = -1000; /* Use -1000 as value for uninitialized cache. */
    1163     2750120 :         move16();
    1164             :     }
    1165             : 
    1166             :     /* Determine EQ for low bit rates (13.2 and 16.4 kbps) */
    1167      275012 :     applyLowBitRateEQ = 0;
    1168      275012 :     move16();
    1169      275012 :     test();
    1170      275012 :     test();
    1171      275012 :     IF( ( EQ_32( ivas_format, MASA_FORMAT ) || EQ_32( ivas_format, MC_FORMAT ) ) && LT_32( ivas_total_brate, MASA_STEREO_MIN_BITRATE ) )
    1172             :     {
    1173       10957 :         applyLowBitRateEQ = 1;
    1174       10957 :         move16();
    1175       10957 :         IF( EQ_32( ivas_total_brate, IVAS_16k4 ) )
    1176             :         {
    1177       77922 :             FOR( bin = 0; bin < LOW_BIT_RATE_BINAURAL_EQ_BINS; bin++ )
    1178             :             {
    1179       73593 :                 lowBitRateEQ_fx[bin + LOW_BIT_RATE_BINAURAL_EQ_OFFSET] = L_add( L_shr( lowBitRateBinauralEQ_fx[bin], 1 ), ONE_IN_Q30 ); // Q31
    1180       73593 :                 move32();
    1181             :             }
    1182             :         }
    1183             :         ELSE
    1184             :         {
    1185      119304 :             FOR( bin = 0; bin < LOW_BIT_RATE_BINAURAL_EQ_BINS; bin++ )
    1186             :             {
    1187      112676 :                 lowBitRateEQ_fx[bin + LOW_BIT_RATE_BINAURAL_EQ_OFFSET] = lowBitRateBinauralEQ_fx[bin]; // Q31
    1188      112676 :                 move32();
    1189             :             }
    1190             :         }
    1191             :     }
    1192             : 
    1193             :     /* Formulate input and target covariance matrices for this subframe */
    1194      275012 :     set32_fx( subFrameTotalEne_fx, 0, CLDFB_NO_CHANNELS_MAX );
    1195      275012 :     dirac_read_idx = hSpatParamRendCom->render_to_md_map[subframe];
    1196      275012 :     move16();
    1197             : 
    1198      275012 :     exp = sub( 63, shl( q, 1 ) ); // exp for the energy (inRe_fx * inRe_fx + inIm_fx * inIm_fx) computed below
    1199             : 
    1200             :     /* Calculate input covariance matrix */
    1201     1368133 :     FOR( slot = 0; slot < hSpatParamRendCom->subframe_nbslots[subframe]; slot++ )
    1202             :     {
    1203    54943281 :         FOR( bin = 0; bin < nBins; bin++ )
    1204             :         {
    1205   161550480 :             FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
    1206             :             {
    1207             :                 Word32 instEne_fx;
    1208   107700320 :                 temp64 = W_mult0_32_32( inRe_fx[ch][slot][bin], inRe_fx[ch][slot][bin] );                  // 2q
    1209   107700320 :                 temp64 = W_add( temp64, W_mult0_32_32( inIm_fx[ch][slot][bin], inIm_fx[ch][slot][bin] ) ); // 2q
    1210   107700320 :                 exp1 = W_norm( temp64 );
    1211   107700320 :                 instEne_fx = W_extract_h( W_shl( temp64, exp1 ) ); // 2q - 32 + exp1
    1212             :                 /* exp of instEne_fx = 31 - (2q -32 + exp1) = 63 - 2q - exp1 = exp - exp1*/
    1213             : 
    1214   107700320 :                 hDiracDecBin->ChEne_fx[ch][bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChEne_fx[ch][bin], hDiracDecBin->ChEne_e[ch][bin], instEne_fx, sub( exp, exp1 ), &hDiracDecBin->ChEne_e[ch][bin] );
    1215   107700320 :                 subFrameTotalEne_fx[bin] = BASOP_Util_Add_Mant32Exp( subFrameTotalEne_fx[bin], subFrameTotalEne_e[bin], instEne_fx, sub( exp, exp1 ), &subFrameTotalEne_e[bin] );
    1216   107700320 :                 move32();
    1217   107700320 :                 move32();
    1218             :             }
    1219    53850160 :             temp64 = W_mult0_32_32( inRe_fx[0][slot][bin], inRe_fx[1][slot][bin] );                  // 2q
    1220    53850160 :             temp64 = W_add( temp64, W_mult0_32_32( inIm_fx[0][slot][bin], inIm_fx[1][slot][bin] ) ); // 2q
    1221    53850160 :             exp1 = W_norm( temp64 );
    1222    53850160 :             temp = W_extract_h( W_shl( temp64, exp1 ) ); // // 2q - 32 + exp1
    1223    53850160 :             hDiracDecBin->ChCrossRe_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossRe_fx[bin], hDiracDecBin->ChCrossRe_e[bin], temp, sub( exp, exp1 ), &hDiracDecBin->ChCrossRe_e[bin] );
    1224    53850160 :             move32();
    1225             : 
    1226    53850160 :             temp64 = W_mult0_32_32( inRe_fx[0][slot][bin], inIm_fx[1][slot][bin] );                  // 2q
    1227    53850160 :             temp64 = W_sub( temp64, W_mult0_32_32( inIm_fx[0][slot][bin], inRe_fx[1][slot][bin] ) ); // 2q
    1228    53850160 :             exp1 = W_norm( temp64 );
    1229    53850160 :             temp = W_extract_h( W_shl( temp64, exp1 ) ); // // 2q - 32 + exp1
    1230    53850160 :             hDiracDecBin->ChCrossIm_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossIm_fx[bin], hDiracDecBin->ChCrossIm_e[bin], temp, sub( exp, exp1 ), &hDiracDecBin->ChCrossIm_e[bin] );
    1231    53850160 :             move32();
    1232             :         }
    1233             :     }
    1234             : 
    1235             :     /* Apply EQ at low bit rates */
    1236      275012 :     IF( applyLowBitRateEQ != 0 )
    1237             :     {
    1238       10957 :         Word16 lastEqBin = LOW_BIT_RATE_BINAURAL_EQ_OFFSET + LOW_BIT_RATE_BINAURAL_EQ_BINS - 1;
    1239             : 
    1240      186269 :         FOR( bin = LOW_BIT_RATE_BINAURAL_EQ_OFFSET; bin < lastEqBin; bin++ )
    1241             :         {
    1242      175312 :             subFrameTotalEne_fx[bin] = Mpy_32_32( subFrameTotalEne_fx[bin], lowBitRateEQ_fx[bin] ); // exp = subFrameTotalEne_e[bin]
    1243      175312 :             move32();
    1244             :         }
    1245      275237 :         FOR( ; bin < nBins; bin++ )
    1246             :         {
    1247      264280 :             subFrameTotalEne_fx[bin] = Mpy_32_32( subFrameTotalEne_fx[bin], lowBitRateEQ_fx[lastEqBin] ); // exp = subFrameTotalEne_e[bin]
    1248      264280 :             move32();
    1249             :         }
    1250             :     }
    1251             : 
    1252      275012 :     test();
    1253      275012 :     test();
    1254      275012 :     IF( ( EQ_32( ivas_format, SBA_FORMAT ) || EQ_32( ivas_format, SBA_ISM_FORMAT ) ) && EQ_16( nchan_transport, 2 ) )
    1255             :     {
    1256             :         Word32 tempRe, tempIm;
    1257             :         Word32 subFrameSumEne_fx[CLDFB_NO_CHANNELS_MAX];
    1258             :         Word16 subFrameSumEne_e[CLDFB_NO_CHANNELS_MAX];
    1259             : 
    1260       85245 :         set32_fx( subFrameSumEne_fx, 0, CLDFB_NO_CHANNELS_MAX );
    1261       85245 :         set16_fx( subFrameSumEne_e, 0, CLDFB_NO_CHANNELS_MAX );
    1262      425234 :         FOR( slot = 0; slot < hSpatParamRendCom->subframe_nbslots[subframe]; slot++ )
    1263             :         {
    1264    15004929 :             FOR( bin = 0; bin < nBins; bin++ )
    1265             :             {
    1266    14664940 :                 tempRe = L_add( inRe_fx[0][slot][bin], inRe_fx[1][slot][bin] );                     // q
    1267    14664940 :                 tempIm = L_add( inIm_fx[0][slot][bin], inIm_fx[1][slot][bin] );                     // q
    1268    14664940 :                 temp64 = W_add( W_mult0_32_32( tempRe, tempRe ), W_mult0_32_32( tempIm, tempIm ) ); // 2q
    1269    14664940 :                 exp1 = W_norm( temp64 );
    1270    14664940 :                 temp64 = W_shl( temp64, exp1 ); // 2q + exp1
    1271    14664940 :                 subFrameSumEne_fx[bin] = BASOP_Util_Add_Mant32Exp( subFrameSumEne_fx[bin], subFrameSumEne_e[bin], W_extract_h( temp64 ), sub( exp /* 63 - 2q */, exp1 ) /*31 - (2q + exp1 - 32)*/, &subFrameSumEne_e[bin] );
    1272    14664940 :                 move32();
    1273             :             }
    1274             :         }
    1275     3766345 :         FOR( bin = 0; bin < nBins; bin++ )
    1276             :         {
    1277     3681100 :             subFrameTotalEne_e[bin] = sub( subFrameTotalEne_e[bin], 1 );
    1278     3681100 :             move16();
    1279     3681100 :             temp = L_shl_sat( subFrameTotalEne_fx[bin], sub( subFrameTotalEne_e[bin], subFrameSumEne_e[bin] ) ); // subFrameSumEne_e[bin]
    1280     3681100 :             IF( GT_32( subFrameSumEne_fx[bin], temp ) )
    1281             :             {
    1282     3557463 :                 subFrameTotalEne_fx[bin] = subFrameSumEne_fx[bin];
    1283     3557463 :                 move32();
    1284     3557463 :                 subFrameTotalEne_e[bin] = subFrameSumEne_e[bin];
    1285     3557463 :                 move16();
    1286             :             }
    1287             :         }
    1288             :     }
    1289             : 
    1290             :     /* Determine target covariance matrix containing target binaural properties */
    1291    13835732 :     FOR( bin = 0; bin < nBins; bin++ )
    1292             :     {
    1293    13560720 :         Word32 diffuseness_fx = ONE_IN_Q30; /* ratio1 and ratio2 are subtracted from diffuseness further below */
    1294    13560720 :         Word32 diffusenessValForDecorrelationReduction_fx = ONE_IN_Q30;
    1295             :         Word32 diffEneValForDecorrelationReduction_fx;
    1296             :         Word16 q_diffEneValForDecorrelationReduction;
    1297    13560720 :         Word16 surCoh_fx = 0, spreadCoh_fx = 0; /* Default values if spreadSurroundCoherenceApplied == false */
    1298             :         Word32 diffEne_fx, dirEne_fx, meanEnePerCh_fx;
    1299             :         Word16 q_meanEnePerCh;
    1300             :         Word16 q_diffEne, q_dirEne;
    1301             :         Word16 dirIndex;
    1302    13560720 :         move16();
    1303    13560720 :         move16();
    1304    13560720 :         move32();
    1305    13560720 :         move32();
    1306             : 
    1307             :         /* When BINAURAL_ROOM is not indicated, hBinaural->earlyPartEneCorrection[bin] values are all 1.0f.
    1308             :          * When BINAURAL_ROOM is indicated, the binaural audio output is based on combined use of the
    1309             :          * HRTF data set and a BRIR-based data set. The HRTF data set is spectrally corrected to match
    1310             :          * the early spectrum of the BRIR data, using the spectral correction data in
    1311             :          * hBinaural->earlyPartEneCorrection[bin], based on the BRIR set. */
    1312    13560720 :         meanEnePerCh_fx = Mpy_32_32( hDiracDecBin->earlyPartEneCorrection_fx[bin], subFrameTotalEne_fx[bin] ); // Q( q_meanEnePerCh )
    1313    13560720 :         q_meanEnePerCh = add( sub( q_earlyPartEneCorrection, subFrameTotalEne_e[bin] ), 1 );                   // q_earlyPartEneCorrection + 31 - subFrameTotalEne_e[bin] - 31 + Q1(0.5f)
    1314             :         /* Determine direct part target covariance matrix (for 1 or 2 directions) */
    1315    30082460 :         FOR( dirIndex = 0; dirIndex < hSpatParamRendCom->numSimultaneousDirections; dirIndex++ )
    1316             :         {
    1317             :             Word16 aziDeg, eleDeg;
    1318             :             Word32 lRealp_fx, lImagp_fx, rRealp_fx, rImagp_fx;
    1319             :             Word32 lRealpTmp_fx, lImagpTmp_fx, rRealpTmp_fx, rImagpTmp_fx;
    1320             :             Word32 hrtfEne_fx[BINAURAL_CHANNELS], hrtfCrossRe_fx, hrtfCrossIm_fx, ratio_fx;
    1321    16521740 :             UWord8 isIsmDirection = 0;
    1322    16521740 :             move16();
    1323             : 
    1324    16521740 :             test();
    1325    16521740 :             test();
    1326    16521740 :             IF( dirIndex == 0 ) /* For first of the two simultaneous directions */
    1327             :             {
    1328    13560720 :                 aziDeg = hSpatParamRendCom->azimuth[dirac_read_idx][bin];
    1329    13560720 :                 move16();
    1330    13560720 :                 eleDeg = hSpatParamRendCom->elevation[dirac_read_idx][bin];
    1331    13560720 :                 move16();
    1332    13560720 :                 ratio_fx = hSpatParamRendCom->energy_ratio1_fx[dirac_read_idx][bin];
    1333    13560720 :                 move32();
    1334    13560720 :                 spreadCoh_fx = hSpatParamRendCom->spreadCoherence_fx[dirac_read_idx][bin];
    1335    13560720 :                 move16();
    1336    13560720 :                 gainCacheBaseIndex = 0;
    1337    13560720 :                 move16();
    1338             :             }
    1339     2961020 :             ELSE IF( NE_32( ivas_format, MASA_ISM_FORMAT ) || ( EQ_32( ivas_format, MASA_ISM_FORMAT ) && LT_16( dirIndex, hSpatParamRendCom->numParametricDirections ) ) ) /* For second of the two simultaneous directions */
    1340             :             {
    1341     2624420 :                 IF( LT_32( ( ratio_fx = hSpatParamRendCom->energy_ratio2_fx[dirac_read_idx][bin] ), 10737418 /* 0.01 in Q30 */ ) )
    1342             :                 {
    1343             :                     /* This touches only MASA path where second direction always has smaller ratio and
    1344             :                      * for non-2dir it is zero. As the whole direction contribution is multiplied with
    1345             :                      * the ratio, a very small ratio does not contribute any energy to output. Thus,
    1346             :                      * it is better to save complexity. */
    1347     1040953 :                     CONTINUE;
    1348             :                 }
    1349     1583467 :                 aziDeg = hSpatParamRendCom->azimuth2[dirac_read_idx][bin];
    1350     1583467 :                 move16();
    1351     1583467 :                 eleDeg = hSpatParamRendCom->elevation2[dirac_read_idx][bin];
    1352     1583467 :                 move16();
    1353     1583467 :                 spreadCoh_fx = hSpatParamRendCom->spreadCoherence2_fx[dirac_read_idx][bin];
    1354     1583467 :                 move16();
    1355     1583467 :                 gainCacheBaseIndex = 3;
    1356     1583467 :                 move16();
    1357             :             }
    1358             :             ELSE /* For object directions of MASA_ISM_FORMAT */
    1359             :             {
    1360      336600 :                 isIsmDirection = 1;
    1361      336600 :                 move16();
    1362             :                 UWord16 ismDirIndex;
    1363      336600 :                 ismDirIndex = sub( dirIndex, hSpatParamRendCom->numParametricDirections );
    1364      336600 :                 assert( hMasaIsmData != NULL && "hMasaIsmData should not be NULL if we use it" );
    1365      336600 :                 IF( hMasaIsmData->ism_is_edited[ismDirIndex] )
    1366             :                 {
    1367           0 :                     aziDeg = hMasaIsmData->azimuth_ism_edited[ismDirIndex];
    1368           0 :                     move16();
    1369           0 :                     eleDeg = hMasaIsmData->elevation_ism_edited[ismDirIndex];
    1370           0 :                     move16();
    1371             :                 }
    1372             :                 ELSE
    1373             :                 {
    1374      336600 :                     aziDeg = hMasaIsmData->azimuth_ism[ismDirIndex][dirac_read_idx];
    1375      336600 :                     move16();
    1376      336600 :                     eleDeg = hMasaIsmData->elevation_ism[ismDirIndex][dirac_read_idx];
    1377      336600 :                     move16();
    1378             :                 }
    1379      336600 :                 ratio_fx = hMasaIsmData->energy_ratio_ism_fx[ismDirIndex][dirac_read_idx][bin];
    1380      336600 :                 move32();
    1381      336600 :                 spreadCoh_fx = 0;
    1382      336600 :                 move16();
    1383      336600 :                 gainCacheBaseIndex = add( 6, ismDirIndex );
    1384             :             }
    1385             : 
    1386    15480787 :             diffuseness_fx = L_sub( diffuseness_fx, ratio_fx ); /* diffuseness = 1 - ratio1 - ratio2 */
    1387             : 
    1388    15480787 :             if ( diffuseness_fx < 0 )
    1389             :             {
    1390       13445 :                 diffuseness_fx = 0;
    1391       13445 :                 move32();
    1392             :             }
    1393    15480787 :             IF( isIsmDirection )
    1394             :             {
    1395             :                 /* Objects cause lesser decorrelation reduction, to avoid removing all decorrelation when only objects are present */
    1396      336600 :                 diffusenessValForDecorrelationReduction_fx = L_sub( diffusenessValForDecorrelationReduction_fx, L_shr( ratio_fx, 1 ) ); /*Q30*/
    1397             :             }
    1398             :             ELSE
    1399             :             {
    1400    15144187 :                 diffusenessValForDecorrelationReduction_fx = L_sub( diffusenessValForDecorrelationReduction_fx, ratio_fx ); /*Q30*/
    1401             :             }
    1402             : 
    1403    15480787 :             IF( separateCenterChannelRendering )
    1404             :             {
    1405             :                 /* In masa + mono rendering mode, the center directions originate from phantom sources, so the
    1406             :                  * spread coherence is increased */
    1407             :                 Word16 azi_scaled, ele_scaled;
    1408             :                 Word32 doaVectorX_fx, num, den;
    1409        6000 :                 Word16 e = 0, spatialAngleDeg_fx, altSpreadCoh_fx;
    1410        6000 :                 move16();
    1411             : 
    1412        6000 :                 azi_scaled = i_mult( aziDeg, 91 );
    1413        6000 :                 ele_scaled = i_mult( eleDeg, 91 );
    1414        6000 :                 doaVectorX_fx = L_mult( getCosWord16R2( azi_scaled ), getCosWord16R2( ele_scaled ) ); /*Q31*/
    1415        6000 :                 num = Sqrt32( L_sub( ONE_IN_Q31, Mpy_32_32( doaVectorX_fx, doaVectorX_fx ) ), &e );
    1416        6000 :                 den = doaVectorX_fx;
    1417        6000 :                 move32();
    1418        6000 :                 spatialAngleDeg_fx = BASOP_util_atan2( num, den, e ); // Q13
    1419        6000 :                 Word16 numr, num_e = 0, denr, den_e;
    1420        6000 :                 move16();
    1421        6000 :                 num_e = sub( norm_s( spatialAngleDeg_fx ), 1 );
    1422        6000 :                 numr = shl( spatialAngleDeg_fx, num_e );
    1423        6000 :                 denr = 17157;
    1424        6000 :                 move16();
    1425        6000 :                 den_e = 4;
    1426        6000 :                 move16();
    1427        6000 :                 altSpreadCoh_fx = sub( 32767, shl_sat( div_s( numr, denr ), sub( den_e, num_e ) ) ); // 4289 = pi/6 in Q13
    1428        6000 :                 spreadCoh_fx = s_max( spreadCoh_fx, altSpreadCoh_fx );
    1429             :             }
    1430             : 
    1431    15480787 :             getDirectPartGains_fx( bin, aziDeg, eleDeg, &lRealp_fx, &lImagp_fx, &rRealp_fx, &rImagp_fx, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat_fx, &gainCache[gainCacheBaseIndex], isHeadtracked );
    1432             : 
    1433    15480787 :             Word16 q_lr = Q28;
    1434    15480787 :             move16();
    1435    15480787 :             if ( hDiracDecBin->renderStereoOutputInsteadOfBinaural )
    1436             :             {
    1437             :                 /* Synthesizing spread coherence is not needed for stereo loudspeaker output,
    1438             :                  * as directional sound is reproduced with two loudspeakers in any case */
    1439     1243646 :                 spreadCoh_fx = 0;
    1440     1243646 :                 move32();
    1441             :             }
    1442             : 
    1443    15480787 :             IF( spreadCoh_fx > 0 )
    1444             :             {
    1445             :                 Word32 centerMul_fx, sidesMul_fx;
    1446             :                 Word32 hrtfEneCenter_fx, hrtfEneSides_fx, hrtfEneRealized_fx;
    1447             :                 Word16 eneCorrectionFactor_fx, eneCorrectionFactor_e;
    1448             :                 Word16 w1_fx, w2_fx, w3_fx, eq_fx;
    1449             : 
    1450     1817485 :                 hrtfEneCenter_fx = L_add( Mpy_32_32( lRealp_fx, lRealp_fx ),                     // Q25
    1451             :                                           L_add( Mpy_32_32( lImagp_fx, lImagp_fx ),              // Q25
    1452             :                                                  L_add( Mpy_32_32( rRealp_fx, rRealp_fx ),       // Q25
    1453             :                                                         Mpy_32_32( rImagp_fx, rImagp_fx ) ) ) ); // Q25
    1454             : 
    1455             :                 /* Spread coherence is synthesized as coherent sources at 30 degree horizontal spacing.
    1456             :                  * The following formulas determine the gains for these sources.
    1457             :                  * spreadCoh = 0: Only panning
    1458             :                  * spreadCoh = 0.5: Three sources coherent panning (e.g. 30 0 -30 deg azi)
    1459             :                  * spreadCoh = 1.0: Two sources coherent panning with gap (as above, but center is silent) */
    1460     1817485 :                 IF( LT_16( spreadCoh_fx, 16384 ) )
    1461             :                 {
    1462             :                     /* 0.0f < spreadCoh < 0.5f */
    1463     1441623 :                     sidesMul_fx = L_mult0( spreadCoh_fx, 9459 ); /* 2*sqrt(1/3) in Q13 = 9459 */         // Q28
    1464     1441623 :                     centerMul_fx = L_add( L_sub( ONE_IN_Q28, L_shl( spreadCoh_fx, 14 ) ), sidesMul_fx ); // Q28
    1465             :                 }
    1466             :                 ELSE
    1467             :                 {
    1468             :                     /* 0.5f <= spreadCoh < 1.0f */
    1469             :                     // centerMul = 2.0f - ( 2.0f * spreadCoh );
    1470      375862 :                     centerMul_fx = L_shl( sub( 32767, spreadCoh_fx ), 14 );                    // Q28
    1471      375862 :                     sidesMul_fx = Isqrt( L_add( L_shr( centerMul_fx, 22 ), L_shl( 2, Q6 ) ) ); // Q28
    1472      375862 :                     centerMul_fx = L_shl( Mpy_32_32( centerMul_fx, sidesMul_fx ), 3 );         // Q28
    1473             :                 }
    1474             : 
    1475             :                 /* Apply the gain for the center source of the three coherent sources */
    1476     1817485 :                 lRealp_fx = Mpy_32_32( lRealp_fx, centerMul_fx ); // Q25
    1477     1817485 :                 lImagp_fx = Mpy_32_32( lImagp_fx, centerMul_fx ); // Q25
    1478     1817485 :                 rRealp_fx = Mpy_32_32( rRealp_fx, centerMul_fx ); // Q25
    1479     1817485 :                 rImagp_fx = Mpy_32_32( rImagp_fx, centerMul_fx ); // Q25
    1480             : 
    1481             :                 /* Apply the gain for the left source of the three coherent sources */
    1482     1817485 :                 getDirectPartGains_fx( bin, add( aziDeg, 30 ), eleDeg, &lRealpTmp_fx, &lImagpTmp_fx, &rRealpTmp_fx, &rImagpTmp_fx, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat_fx, &gainCache[gainCacheBaseIndex + 1], isHeadtracked );
    1483             : 
    1484     1817485 :                 hrtfEneSides_fx = L_add( Mpy_32_32( lRealpTmp_fx, lRealpTmp_fx ),                     // Q25
    1485             :                                          L_add( Mpy_32_32( lImagpTmp_fx, lImagpTmp_fx ),              // Q25
    1486             :                                                 L_add( Mpy_32_32( rRealpTmp_fx, rRealpTmp_fx ),       // Q25
    1487             :                                                        Mpy_32_32( rImagpTmp_fx, rImagpTmp_fx ) ) ) ); // Q25
    1488     1817485 :                 lRealp_fx = L_add( lRealp_fx, Mpy_32_32( sidesMul_fx, lRealpTmp_fx ) );               // Q25
    1489     1817485 :                 lImagp_fx = L_add( lImagp_fx, Mpy_32_32( sidesMul_fx, lImagpTmp_fx ) );               // Q25
    1490     1817485 :                 rRealp_fx = L_add( rRealp_fx, Mpy_32_32( sidesMul_fx, rRealpTmp_fx ) );               // Q25
    1491     1817485 :                 rImagp_fx = L_add( rImagp_fx, Mpy_32_32( sidesMul_fx, rImagpTmp_fx ) );               // Q25
    1492             : 
    1493             :                 /* Apply the gain for the right source of the three coherent sources.
    1494             :                  * -30 degrees to 330 wrapping due to internal functions. */
    1495             : 
    1496     1817485 :                 getDirectPartGains_fx( bin, aziDeg + 330, eleDeg, &lRealpTmp_fx, &lImagpTmp_fx, &rRealpTmp_fx, &rImagpTmp_fx, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat_fx, &gainCache[gainCacheBaseIndex + 2], isHeadtracked );
    1497             : 
    1498     1817485 :                 hrtfEneSides_fx = L_add( hrtfEneSides_fx,
    1499             :                                          L_add( Mpy_32_32( lRealpTmp_fx, lRealpTmp_fx ),                       // Q25
    1500             :                                                 L_add( Mpy_32_32( lImagpTmp_fx, lImagpTmp_fx ),                // Q25
    1501             :                                                        L_add( Mpy_32_32( rRealpTmp_fx, rRealpTmp_fx ),         // Q25
    1502             :                                                               Mpy_32_32( rImagpTmp_fx, rImagpTmp_fx ) ) ) ) ); // Q25
    1503     1817485 :                 lRealp_fx = L_add( lRealp_fx, Mpy_32_32( sidesMul_fx, lRealpTmp_fx ) );                        // Q25
    1504     1817485 :                 lImagp_fx = L_add( lImagp_fx, Mpy_32_32( sidesMul_fx, lImagpTmp_fx ) );                        // Q25
    1505     1817485 :                 rRealp_fx = L_add( rRealp_fx, Mpy_32_32( sidesMul_fx, rRealpTmp_fx ) );                        // Q25
    1506     1817485 :                 rImagp_fx = L_add( rImagp_fx, Mpy_32_32( sidesMul_fx, rImagpTmp_fx ) );                        // Q25
    1507             : 
    1508             :                 /* Formulate an eneCorrectionFactor that compensates for the coherent summation of the HRTFs */
    1509     1817485 :                 hrtfEneRealized_fx = L_add( Mpy_32_32( lRealp_fx, lRealp_fx ),                     // Q19
    1510             :                                             L_add( Mpy_32_32( lImagp_fx, lImagp_fx ),              // Q19
    1511             :                                                    L_add( Mpy_32_32( rRealp_fx, rRealp_fx ),       // Q19
    1512             :                                                           Mpy_32_32( rImagp_fx, rImagp_fx ) ) ) ); // Q19
    1513             : 
    1514     1817485 :                 eneCorrectionFactor_fx = BASOP_Util_Divide3232_Scale( L_add( Mpy_32_32( hrtfEneSides_fx, Mpy_32_32( sidesMul_fx, sidesMul_fx ) ),
    1515             :                                                                              Mpy_32_32( hrtfEneCenter_fx, Mpy_32_32( centerMul_fx, centerMul_fx ) ) ),
    1516             :                                                                       L_max( 1, hrtfEneRealized_fx ), &eneCorrectionFactor_e );
    1517             : 
    1518             :                 /* Weighting factors to determine appropriate target spectrum for spread coherent sound */
    1519     1817485 :                 IF( LT_16( spreadCoh_fx, 16384 ) )
    1520             :                 {
    1521     1441623 :                     w1_fx = sub( 32767, shl( spreadCoh_fx, 1 ) ); /*Q15*/
    1522     1441623 :                     w2_fx = shl( spreadCoh_fx, 1 );               /*Q15*/
    1523     1441623 :                     w3_fx = 0;
    1524     1441623 :                     move16();
    1525             :                 }
    1526             :                 ELSE
    1527             :                 {
    1528      375862 :                     w1_fx = 0;
    1529      375862 :                     move16();
    1530      375862 :                     w2_fx = shl( sub( 32767, spreadCoh_fx ), 1 ); /*Q15*/
    1531      375862 :                     w3_fx = shl( sub( spreadCoh_fx, 16384 ), 1 ); /*Q15*/
    1532             :                 }
    1533             : 
    1534     1817485 :                 test();
    1535     1817485 :                 IF( ( EQ_32( ivas_format, MC_FORMAT ) && EQ_32( mc_mode, MC_MODE_MCMASA ) ) )
    1536             :                 {
    1537      655175 :                     idx = s_min( bin, MASA_NUM_DEFINED_SUR_SPR_COH_ENE_BINS - 1 );
    1538             : 
    1539             :                     /* Apply the target spectrum to the eneCorrectionFactor */
    1540      655175 :                     IF( separateCenterChannelRendering ) /* spreadCoh mostly originates from phantom sources in separate channel rendering mode */
    1541             :                     {
    1542        3514 :                         eneCorrectionFactor_fx = mult_r( eneCorrectionFactor_fx, add( mult_r( w1_fx, 8192 ), shr( mult_r( add( w2_fx, w3_fx ), spreadCohEne1_fx[idx] ), 1 ) ) );
    1543        3514 :                         eneCorrectionFactor_e = add( eneCorrectionFactor_e, 2 );
    1544             :                     }
    1545             :                     ELSE
    1546             :                     {
    1547      651661 :                         eneCorrectionFactor_fx = mult_r( eneCorrectionFactor_fx, add( mult_r( w1_fx, 4096 ), add( shr( mult_r( w2_fx, spreadCohEne05_fx[idx] ), 1 ), shr( mult_r( w3_fx, spreadCohEne1_fx[idx] ), 2 ) ) ) );
    1548      651661 :                         eneCorrectionFactor_e = add( eneCorrectionFactor_e, 3 );
    1549             :                     }
    1550             :                 }
    1551             : 
    1552             :                 /* Equalize the spread coherent combined HRTFs */
    1553             :                 Word16 tmp, tmp_e;
    1554     1817485 :                 tmp_e = eneCorrectionFactor_e;
    1555     1817485 :                 move16();
    1556     1817485 :                 tmp = Sqrt16( eneCorrectionFactor_fx, &tmp_e );
    1557     1817485 :                 IF( GE_16( shr( tmp, sub( 15, tmp_e ) ), 4 ) )
    1558             :                 {
    1559           2 :                     eq_fx = 32767; // Q13
    1560           2 :                     move16();
    1561             :                 }
    1562             :                 ELSE
    1563             :                 {
    1564     1817483 :                     eq_fx = shl( tmp, sub( tmp_e, 2 ) ); // Q13
    1565             :                 }
    1566             : 
    1567     1817485 :                 lRealp_fx = Mpy_32_16_1( lRealp_fx, eq_fx ); // Q23
    1568     1817485 :                 lImagp_fx = Mpy_32_16_1( lImagp_fx, eq_fx ); // Q23
    1569     1817485 :                 rRealp_fx = Mpy_32_16_1( rRealp_fx, eq_fx ); // Q23
    1570     1817485 :                 rImagp_fx = Mpy_32_16_1( rImagp_fx, eq_fx ); // Q23
    1571     1817485 :                 q_lr = Q23;
    1572     1817485 :                 move16();
    1573             :             }
    1574             : 
    1575    15480787 :             hrtfEne_fx[0] = L_add( Mpy_32_32( lRealp_fx, lRealp_fx ), Mpy_32_32( lImagp_fx, lImagp_fx ) ); // Q( 2*q_lr - 31 )
    1576    15480787 :             hrtfEne_fx[1] = L_add( Mpy_32_32( rRealp_fx, rRealp_fx ), Mpy_32_32( rImagp_fx, rImagp_fx ) ); // Q( 2*q_lr - 31 )
    1577    15480787 :             move32();
    1578    15480787 :             move32();
    1579    15480787 :             hrtfCrossRe_fx = L_add( Mpy_32_32( lRealp_fx, rRealp_fx ), Mpy_32_32( lImagp_fx, rImagp_fx ) );  // Q( 2*q_lr - 31 )
    1580    15480787 :             hrtfCrossIm_fx = L_add( Mpy_32_32( -lImagp_fx, rRealp_fx ), Mpy_32_32( lRealp_fx, rImagp_fx ) ); // Q( 2*q_lr - 31 )
    1581             : 
    1582             :             /* Add direct part (1 or 2) covariance matrix */
    1583    15480787 :             dirEne_fx = Mpy_32_32( ratio_fx, meanEnePerCh_fx ); // Q(q_meanEnePerCh - 1)
    1584    15480787 :             shift = norm_l( dirEne_fx );
    1585    15480787 :             dirEne_fx = L_shl( dirEne_fx, shift );
    1586    15480787 :             q_dirEne = add( sub( q_meanEnePerCh, 1 ), shift );
    1587             : 
    1588    15480787 :             hDiracDecBin->ChEneOut_fx[0][bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChEneOut_fx[0][bin], hDiracDecBin->ChEneOut_e[0][bin], Mpy_32_32( dirEne_fx, hrtfEne_fx[0] ), sub( 31, sub( add( q_dirEne, shl( q_lr, 1 ) ), 62 ) ), &hDiracDecBin->ChEneOut_e[0][bin] ); /* Dir ene part*/
    1589    15480787 :             hDiracDecBin->ChEneOut_fx[1][bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChEneOut_fx[1][bin], hDiracDecBin->ChEneOut_e[1][bin], Mpy_32_32( dirEne_fx, hrtfEne_fx[1] ), sub( 31, sub( add( q_dirEne, shl( q_lr, 1 ) ), 62 ) ), &hDiracDecBin->ChEneOut_e[1][bin] );
    1590    15480787 :             hDiracDecBin->ChCrossReOut_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossReOut_fx[bin], hDiracDecBin->ChCrossReOut_e[bin], Mpy_32_32( dirEne_fx, hrtfCrossRe_fx ), sub( 31, sub( add( q_dirEne, shl( q_lr, 1 ) ), 62 ) ), &hDiracDecBin->ChCrossReOut_e[bin] ); /* Dir cross re */
    1591    15480787 :             hDiracDecBin->ChCrossImOut_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossImOut_fx[bin], hDiracDecBin->ChCrossImOut_e[bin], Mpy_32_32( dirEne_fx, hrtfCrossIm_fx ), sub( 31, sub( add( q_dirEne, shl( q_lr, 1 ) ), 62 ) ), &hDiracDecBin->ChCrossImOut_e[bin] ); /* Dir cross im */
    1592    15480787 :             move32();
    1593    15480787 :             move32();
    1594    15480787 :             move32();
    1595    15480787 :             move32();
    1596             :         }
    1597             : 
    1598             :         /* Add diffuse / ambient part covariance matrix */
    1599    13560720 :         diffuseness_fx = L_max( 0, diffuseness_fx );               // Q30
    1600    13560720 :         diffEne_fx = Mpy_32_32( diffuseness_fx, meanEnePerCh_fx ); // Q(2q - 32)
    1601    13560720 :         shift = norm_l( diffEne_fx );
    1602    13560720 :         diffEne_fx = L_shl( diffEne_fx, shift );
    1603    13560720 :         q_diffEne = add( shift, sub( q_meanEnePerCh, 1 ) );
    1604             : 
    1605    13560720 :         surCoh_fx = hSpatParamRendCom->surroundingCoherence_fx[dirac_read_idx][bin]; // Q15
    1606    13560720 :         move16();
    1607             : 
    1608    13560720 :         diffusenessValForDecorrelationReduction_fx = L_max( 0, diffusenessValForDecorrelationReduction_fx );               // Q30
    1609    13560720 :         diffEneValForDecorrelationReduction_fx = Mpy_32_32( diffusenessValForDecorrelationReduction_fx, meanEnePerCh_fx ); // resulting Q = q_meanEnePerCh - 1
    1610    13560720 :         q_diffEneValForDecorrelationReduction = sub( q_meanEnePerCh, 1 );
    1611             : 
    1612    13560720 :         test();
    1613    13560720 :         IF( ( EQ_32( ivas_format, MC_FORMAT ) && EQ_32( mc_mode, MC_MODE_MCMASA ) ) )
    1614             :         {
    1615     1340800 :             IF( !hDiracDecBin->renderStereoOutputInsteadOfBinaural )
    1616             :             {
    1617             :                 Word32 spectrumModVal;
    1618             : 
    1619     1340800 :                 idx = s_min( bin, MASA_NUM_DEFINED_SUR_SPR_COH_ENE_BINS - 1 );
    1620             :                 /* Apply target spectrum that emphasizes low frequencies when the sound is surround coherent */
    1621     1340800 :                 spectrumModVal = L_add( L_sub( ONE_IN_Q29, L_shl( surCoh_fx, 14 ) ), L_mult( surCoh_fx, surCohEne_fx[idx] ) ); // Q29
    1622     1340800 :                 diffEne_fx = Mpy_32_32( diffEne_fx, spectrumModVal );                                                          // Q-2
    1623     1340800 :                 q_diffEne = sub( q_diffEne, 2 );
    1624             :                 /* Modify also the value for decorrelation reduction */
    1625     1340800 :                 diffEneValForDecorrelationReduction_fx = Mpy_32_32( diffEneValForDecorrelationReduction_fx, spectrumModVal ); // Q-2
    1626     1340800 :                 q_diffEneValForDecorrelationReduction = sub( q_diffEneValForDecorrelationReduction, 2 );
    1627             :             }
    1628             :         }
    1629    13560720 :         hDiracDecBin->ChEneOut_fx[0][bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChEneOut_fx[0][bin], hDiracDecBin->ChEneOut_e[0][bin], diffEne_fx, sub( 31, q_diffEne ), &hDiracDecBin->ChEneOut_e[0][bin] ); /* Diff ene part*/
    1630    13560720 :         hDiracDecBin->ChEneOut_fx[1][bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChEneOut_fx[1][bin], hDiracDecBin->ChEneOut_e[1][bin], diffEne_fx, sub( 31, q_diffEne ), &hDiracDecBin->ChEneOut_e[1][bin] );
    1631             : 
    1632    13560720 :         move32();
    1633    13560720 :         move32();
    1634    13560720 :         IF( hDiracDecBin->renderStereoOutputInsteadOfBinaural )
    1635             :         {
    1636             :             /* When rendering stereo, ambience (except for surround coherent sound) has zero ICC. */
    1637     1025180 :             hDiracDecBin->ChCrossReOut_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossReOut_fx[bin], hDiracDecBin->ChCrossReOut_e[bin], Mpy_32_16_1( diffEne_fx, surCoh_fx ), sub( 31, q_diffEne ), &hDiracDecBin->ChCrossReOut_e[bin] );
    1638     1025180 :             move32();
    1639             :         }
    1640             :         ELSE /* When rendering binaural, ambience has frequency dependent ICC. */
    1641             :         {
    1642    12535540 :             test();
    1643    12535540 :             test();
    1644    12535540 :             IF( ( EQ_32( ivas_format, SBA_FORMAT ) || EQ_32( ivas_format, SBA_ISM_FORMAT ) ) && LT_16( bin, BINAURAL_COHERENCE_DIFFERENCE_BINS ) )
    1645     1346868 :             {
    1646             :                 Word32 diffuseFieldCoherence_fx;
    1647             :                 Word16 tmp_exp;
    1648     1346868 :                 temp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( hDiracDecBin->hDiffuseDist->diffuseRatioX_fx[bin], hDiracDecBin->diffuseFieldCoherenceX_fx[bin] ), 0, Mpy_32_32( hDiracDecBin->hDiffuseDist->diffuseRatioY_fx[bin], hDiracDecBin->diffuseFieldCoherenceY_fx[bin] ), 0, &tmp_exp );
    1649     1346868 :                 diffuseFieldCoherence_fx = BASOP_Util_Add_Mant32Exp( temp, tmp_exp, Mpy_32_32( hDiracDecBin->hDiffuseDist->diffuseRatioZ_fx[bin], hDiracDecBin->diffuseFieldCoherenceZ_fx[bin] ), 0, &tmp_exp );
    1650     1346868 :                 temp = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( diffuseFieldCoherence_fx, sub( 32767, surCoh_fx ) ), tmp_exp, L_shl( surCoh_fx, 16 ), 0, &tmp_exp );
    1651     1346868 :                 hDiracDecBin->ChCrossReOut_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossReOut_fx[bin], hDiracDecBin->ChCrossReOut_e[bin], Mpy_32_32( temp, diffEne_fx ), add( tmp_exp, sub( 31, q_diffEne ) ), &hDiracDecBin->ChCrossReOut_e[bin] );
    1652             :             }
    1653             :             ELSE
    1654             :             {
    1655    11188672 :                 hDiracDecBin->ChCrossReOut_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossReOut_fx[bin], hDiracDecBin->ChCrossReOut_e[bin], Mpy_32_32( L_add( Mpy_32_16_1( hDiracDecBin->diffuseFieldCoherence_fx[bin], sub( 32767, surCoh_fx ) ), L_shl( surCoh_fx, 16 ) ), diffEne_fx ), sub( 31, q_diffEne ), &hDiracDecBin->ChCrossReOut_e[bin] );
    1656             :             }
    1657    12535540 :             move32();
    1658             :         }
    1659             : 
    1660             :         /* Store parameters for formulating average diffuseness over frame */
    1661    13560720 :         Word32 frameMeanDiffuseness = BASOP_Util_Add_Mant32Exp( hDiracDecBin->frameMeanDiffuseness_fx[bin], 2 /*Q29*/, diffEneValForDecorrelationReduction_fx, sub( 31, q_diffEneValForDecorrelationReduction ), &exp1 ); // exp = exp1
    1662    13560720 :         frameMeanDiffusenessEneWeight_fx[bin] = L_add( frameMeanDiffusenessEneWeight_fx[bin], meanEnePerCh_fx );
    1663    13560720 :         move32();
    1664             : 
    1665             :         /* Formulate average diffuseness over frame */
    1666    13560720 :         frameMeanDiffuseness = BASOP_Util_Divide3232_Scale_newton( frameMeanDiffuseness, L_max( EPSILLON_FX, frameMeanDiffusenessEneWeight_fx[bin] ), &exp ); // exp = exp + 31 - q_meanEnePerCh - exp1
    1667    13560720 :         exp = sub( exp, sub( sub( 31, q_meanEnePerCh ), exp1 ) );
    1668    13560720 :         hDiracDecBin->frameMeanDiffuseness_fx[bin] = L_shl( frameMeanDiffuseness, sub( exp, 2 ) ); // Q29
    1669    13560720 :         move32();
    1670             :     }
    1671             : 
    1672      275012 :     test();
    1673             :     /* Temporal IIR-type smoothing of covariance matrices. Also apply encoding quality based smoothing factor. */
    1674      275012 :     IF( EQ_32( ivas_format, MASA_FORMAT ) && LT_32( ivas_total_brate, MASA_STEREO_MIN_BITRATE ) )
    1675             :     {
    1676        9537 :         IIReneLimiterFactor_fx = L_add( L_shl( 16, Q26 ), L_sub( L_shl( 1, Q26 ), L_shr( qualityBasedSmFactor_fx, 5 ) ) ); // Q26
    1677             :     }
    1678             :     ELSE
    1679             :     {
    1680      265475 :         IIReneLimiterFactor_fx = L_add( L_shl( 8, Q26 ), L_sub( L_shl( 1, Q26 ), L_shr( qualityBasedSmFactor_fx, 5 ) ) ); // Q26
    1681             :     }
    1682             : 
    1683    13835732 :     FOR( bin = 0; bin < nBins; bin++ )
    1684             :     {
    1685             :         Word32 IIReneLimiter_fx;
    1686             : 
    1687             :         /* Temporally smooth cov mtx estimates for resulting mixing matrix stability. The design principle is that
    1688             :          * the energy history (IIR) must not be more than double of the current frame energy. This provides more
    1689             :          * robust performance at energy offsets when compared to typical IIR averaging. */
    1690             :         Word16 num_e, den_e;
    1691             :         Word32 num, den;
    1692    13560720 :         num = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChEne_fx[0][bin], hDiracDecBin->ChEne_e[0][bin], hDiracDecBin->ChEne_fx[1][bin], hDiracDecBin->ChEne_e[1][bin], &num_e );
    1693    13560720 :         num = Mpy_32_32( num, IIReneLimiterFactor_fx ); /*Q = (31 - num_e + 26 - 31) = (26 - num_e)*/
    1694    13560720 :         den_e = 0;
    1695    13560720 :         move16();
    1696    13560720 :         den = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChEnePrev_fx[0][bin], hDiracDecBin->ChEnePrev_e[0][bin], hDiracDecBin->ChEnePrev_fx[1][bin], hDiracDecBin->ChEnePrev_e[1][bin], &den_e );
    1697    13560720 :         den = L_max( 1, den );
    1698    13560720 :         IIReneLimiter_fx = BASOP_Util_Divide3232_Scale_newton( num, den, &exp );
    1699    13560720 :         exp = add( sub( num_e, den_e ), add( 5, exp ) );
    1700    13560720 :         IF( L_shr_sat( IIReneLimiter_fx, sub( 31, exp ) ) > 0 )
    1701             :         {
    1702     8419201 :             IIReneLimiter_fx = ONE_IN_Q31; /*Q31*/
    1703     8419201 :             move32();
    1704             :         }
    1705             :         ELSE
    1706             :         {
    1707     5141519 :             IIReneLimiter_fx = L_shl( IIReneLimiter_fx, exp ); /*Q31*/
    1708             :         }
    1709             : 
    1710    13560720 :         hDiracDecBin->ChCrossRe_fx[bin] = Mpy_32_32( hDiracDecBin->ChCrossRe_fx[bin], qualityBasedSmFactor_fx );
    1711    13560720 :         hDiracDecBin->ChCrossIm_fx[bin] = Mpy_32_32( hDiracDecBin->ChCrossIm_fx[bin], qualityBasedSmFactor_fx );
    1712    13560720 :         hDiracDecBin->ChCrossReOut_fx[bin] = Mpy_32_32( hDiracDecBin->ChCrossReOut_fx[bin], qualityBasedSmFactor_fx );
    1713    13560720 :         hDiracDecBin->ChCrossImOut_fx[bin] = Mpy_32_32( hDiracDecBin->ChCrossImOut_fx[bin], qualityBasedSmFactor_fx );
    1714    13560720 :         move32();
    1715    13560720 :         move32();
    1716    13560720 :         move32();
    1717    13560720 :         move32();
    1718             : 
    1719    40682160 :         FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
    1720             :         {
    1721    27121440 :             hDiracDecBin->ChEne_fx[ch][bin] = Mpy_32_32( hDiracDecBin->ChEne_fx[ch][bin], qualityBasedSmFactor_fx );
    1722    27121440 :             hDiracDecBin->ChEneOut_fx[ch][bin] = Mpy_32_32( hDiracDecBin->ChEneOut_fx[ch][bin], qualityBasedSmFactor_fx );
    1723    27121440 :             move32();
    1724    27121440 :             move32();
    1725             :         }
    1726             : 
    1727    13560720 :         hDiracDecBin->ChCrossRe_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossRe_fx[bin], hDiracDecBin->ChCrossRe_e[bin], Mpy_32_32( hDiracDecBin->ChCrossRePrev_fx[bin], IIReneLimiter_fx ), hDiracDecBin->ChCrossRePrev_e[bin], &hDiracDecBin->ChCrossRe_e[bin] );
    1728    13560720 :         hDiracDecBin->ChCrossIm_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossIm_fx[bin], hDiracDecBin->ChCrossIm_e[bin], Mpy_32_32( hDiracDecBin->ChCrossImPrev_fx[bin], IIReneLimiter_fx ), hDiracDecBin->ChCrossImPrev_e[bin], &hDiracDecBin->ChCrossIm_e[bin] );
    1729    13560720 :         hDiracDecBin->ChCrossReOut_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossReOut_fx[bin], hDiracDecBin->ChCrossReOut_e[bin], Mpy_32_32( hDiracDecBin->ChCrossReOutPrev_fx[bin], IIReneLimiter_fx ), hDiracDecBin->ChCrossReOutPrev_e[bin], &hDiracDecBin->ChCrossReOut_e[bin] );
    1730    13560720 :         hDiracDecBin->ChCrossImOut_fx[bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChCrossImOut_fx[bin], hDiracDecBin->ChCrossImOut_e[bin], Mpy_32_32( hDiracDecBin->ChCrossImOutPrev_fx[bin], IIReneLimiter_fx ), hDiracDecBin->ChCrossImOutPrev_e[bin], &hDiracDecBin->ChCrossImOut_e[bin] );
    1731    13560720 :         move32();
    1732    13560720 :         move32();
    1733    13560720 :         move32();
    1734    13560720 :         move32();
    1735             : 
    1736    40682160 :         FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
    1737             :         {
    1738    27121440 :             hDiracDecBin->ChEne_fx[ch][bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChEne_fx[ch][bin], hDiracDecBin->ChEne_e[ch][bin], Mpy_32_32( hDiracDecBin->ChEnePrev_fx[ch][bin], IIReneLimiter_fx ), hDiracDecBin->ChEnePrev_e[ch][bin], &hDiracDecBin->ChEne_e[ch][bin] );
    1739    27121440 :             hDiracDecBin->ChEneOut_fx[ch][bin] = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChEneOut_fx[ch][bin], hDiracDecBin->ChEneOut_e[ch][bin], Mpy_32_32( hDiracDecBin->ChEneOutPrev_fx[ch][bin], IIReneLimiter_fx ), hDiracDecBin->ChEneOutPrev_e[ch][bin], &hDiracDecBin->ChEneOut_e[ch][bin] );
    1740    27121440 :             move32();
    1741    27121440 :             move32();
    1742             :         }
    1743             : 
    1744             :         /* Store energy values and coefficients for next round */
    1745    13560720 :         hDiracDecBin->ChCrossRePrev_fx[bin] = hDiracDecBin->ChCrossRe_fx[bin];
    1746    13560720 :         move32();
    1747    13560720 :         hDiracDecBin->ChCrossImPrev_fx[bin] = hDiracDecBin->ChCrossIm_fx[bin];
    1748    13560720 :         move32();
    1749    13560720 :         hDiracDecBin->ChCrossReOutPrev_fx[bin] = hDiracDecBin->ChCrossReOut_fx[bin];
    1750    13560720 :         move32();
    1751    13560720 :         hDiracDecBin->ChCrossImOutPrev_fx[bin] = hDiracDecBin->ChCrossImOut_fx[bin];
    1752    13560720 :         move32();
    1753    13560720 :         hDiracDecBin->ChCrossRePrev_e[bin] = hDiracDecBin->ChCrossRe_e[bin];
    1754    13560720 :         move16();
    1755    13560720 :         hDiracDecBin->ChCrossImPrev_e[bin] = hDiracDecBin->ChCrossIm_e[bin];
    1756    13560720 :         move16();
    1757    13560720 :         hDiracDecBin->ChCrossReOutPrev_e[bin] = hDiracDecBin->ChCrossReOut_e[bin];
    1758    13560720 :         move16();
    1759    13560720 :         hDiracDecBin->ChCrossImOutPrev_e[bin] = hDiracDecBin->ChCrossImOut_e[bin];
    1760    13560720 :         move16();
    1761             : 
    1762    40682160 :         FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
    1763             :         {
    1764    27121440 :             hDiracDecBin->ChEnePrev_fx[ch][bin] = hDiracDecBin->ChEne_fx[ch][bin];
    1765    27121440 :             move32();
    1766    27121440 :             hDiracDecBin->ChEneOutPrev_fx[ch][bin] = hDiracDecBin->ChEneOut_fx[ch][bin];
    1767    27121440 :             move32();
    1768    27121440 :             hDiracDecBin->ChEnePrev_e[ch][bin] = hDiracDecBin->ChEne_e[ch][bin];
    1769    27121440 :             move16();
    1770    27121440 :             hDiracDecBin->ChEneOutPrev_e[ch][bin] = hDiracDecBin->ChEneOut_e[ch][bin];
    1771    27121440 :             move16();
    1772             :         }
    1773             :     }
    1774             : 
    1775      275012 :     return;
    1776             : }
    1777             : 
    1778      275012 : static void ivas_dirac_dec_binaural_determine_processing_matrices_fx(
    1779             :     DIRAC_DEC_BIN_HANDLE hDiracDecBin,
    1780             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom,
    1781             :     PARAMBIN_REND_CONFIG_HANDLE hConfig,
    1782             :     const Word16 max_band_decorr,
    1783             :     Word32 Rmat[3][3], /*Q30*/
    1784             :     const Word16 subframe,
    1785             :     const Word16 isHeadtracked,
    1786             :     const Word16 nchanSeparateChannels,
    1787             :     const MASA_ISM_DATA_HANDLE hMasaIsmData )
    1788             : {
    1789             :     Word16 chA, chB, bin;
    1790             :     Word16 separateCenterChannelRendering;
    1791             :     Word16 nBins;
    1792             :     Word16 dirac_read_idx;
    1793             :     PARAMBIN_HRTF_GAIN_CACHE gainCache[MAX_NUM_OBJECTS];
    1794             :     Word16 idx;
    1795             :     ISM_MODE ism_mode;
    1796             :     IVAS_FORMAT ivas_format;
    1797             :     MC_MODE mc_mode;
    1798             :     Word32 ivas_total_brate;
    1799             :     Word16 nchan_transport;
    1800             :     Word16 exp;
    1801             :     Word16 q_processMtx[CLDFB_NO_CHANNELS_MAX], q_processMtxPrev[CLDFB_NO_CHANNELS_MAX];
    1802             :     Word16 q_processMtx_SCCR[CLDFB_NO_CHANNELS_MAX], q_processMtxPrev_SCCR[CLDFB_NO_CHANNELS_MAX];
    1803             :     Word16 q_processMtxDec[CLDFB_NO_CHANNELS_MAX], q_processMtxDecPrev[CLDFB_NO_CHANNELS_MAX];
    1804      275012 :     set16_fx( q_processMtx, hDiracDecBin->q_processMtx, CLDFB_NO_CHANNELS_MAX );
    1805      275012 :     set16_fx( q_processMtxPrev, hDiracDecBin->q_processMtxPrev, CLDFB_NO_CHANNELS_MAX );
    1806      275012 :     set16_fx( q_processMtx_SCCR, hDiracDecBin->q_processMtx, CLDFB_NO_CHANNELS_MAX );
    1807      275012 :     set16_fx( q_processMtxPrev_SCCR, hDiracDecBin->q_processMtxPrev, CLDFB_NO_CHANNELS_MAX );
    1808      275012 :     set16_fx( q_processMtxDec, hDiracDecBin->q_processMtxDec, CLDFB_NO_CHANNELS_MAX );
    1809      275012 :     set16_fx( q_processMtxDecPrev, hDiracDecBin->q_processMtxDecPrev, CLDFB_NO_CHANNELS_MAX );
    1810             : 
    1811      275012 :     ivas_format = hConfig->ivas_format;
    1812      275012 :     move32();
    1813      275012 :     separateCenterChannelRendering = extract_l( GT_16( nchanSeparateChannels, 0 ) );
    1814      275012 :     move16();
    1815      275012 :     mc_mode = hConfig->mc_mode;
    1816      275012 :     move32();
    1817      275012 :     ivas_total_brate = hConfig->ivas_total_brate;
    1818      275012 :     move32();
    1819      275012 :     nchan_transport = hConfig->nchan_transport;
    1820      275012 :     move16();
    1821      275012 :     nBins = hSpatParamRendCom->num_freq_bands; /* Actually bins */
    1822      275012 :     move16();
    1823             : 
    1824      275012 :     ism_mode = hConfig->ism_mode;
    1825      275012 :     move32();
    1826             : 
    1827      275012 :     dirac_read_idx = hSpatParamRendCom->render_to_md_map[subframe];
    1828      275012 :     move16();
    1829             : 
    1830     1375060 :     FOR( idx = 0; idx < MAX_NUM_OBJECTS; idx++ )
    1831             :     {
    1832     1100048 :         gainCache[idx].azi = -1000; /* Use -1000 as value for uninitialized cache. */
    1833     1100048 :         move16();
    1834             :     }
    1835             : 
    1836    13835732 :     FOR( bin = 0; bin < nBins; bin++ )
    1837             :     {
    1838             :         Word32 tmpMtxRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], tmpMtxIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], resultMtxRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], resultMtxIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], gain_fx;
    1839             :         Word32 CxRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], CxIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; /* Input covariance matrix */
    1840             :         Word32 realizedOutputEne_fx, targetOutputEne_fx, missingOutputEne_fx;
    1841             :         Word32 CrEneL_fx, CrEneR_fx; /* Cr = residual decorrelated sound covariance matrix */
    1842             :         Word32 CrCrossRe_fx, CrCrossIm_fx;
    1843             :         Word32 Mre_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], Mim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], MdecRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], MdecIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; /* M = mixing matrix; Mdec = residual decorrelated signal mixing matrix */
    1844    13560720 :         Word32 prototypeMtx_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] = { { ONE_IN_Q31, 107374182 }, { 107374182, ONE_IN_Q31 } };
    1845    13560720 :         move32();
    1846    13560720 :         Word16 q_M, q_Cx, q_tmp, q_res, q_CrEne, q_CrCross, q_Mdec = 0;
    1847    13560720 :         move16();
    1848             :         Word32 tmp1, tmp2, res1, res2;
    1849             :         Word16 q_tmp1, q_tmp2, q_realizedOutputEne, q_targetOutputEne, q_missingOutputEne, q_gain;
    1850             :         Word16 exp1, exp2, q_processMtx_bin, q_processMtxDec_bin;
    1851             : 
    1852    13560720 :         CrEneL_fx = 0;
    1853    13560720 :         move32();
    1854    13560720 :         CrEneR_fx = 0;
    1855    13560720 :         move32();
    1856    13560720 :         q_CrEne = Q31;
    1857    13560720 :         move16();
    1858             : 
    1859    13560720 :         Word16 q_diff = sub( hDiracDecBin->ChEne_e[0][bin], hDiracDecBin->ChEne_e[1][bin] );
    1860             : 
    1861    13560720 :         IF( q_diff > 0 )
    1862             :         {
    1863     1899521 :             hDiracDecBin->ChEne_fx[1][bin] = L_shr( hDiracDecBin->ChEne_fx[1][bin], q_diff );
    1864     1899521 :             hDiracDecBin->q_ChEne = sub( 31, hDiracDecBin->ChEne_e[0][bin] );
    1865     1899521 :             hDiracDecBin->ChEne_e[1][bin] = hDiracDecBin->ChEne_e[0][bin];
    1866             :         }
    1867             :         ELSE
    1868             :         {
    1869    11661199 :             hDiracDecBin->ChEne_fx[0][bin] = L_shl( hDiracDecBin->ChEne_fx[0][bin], q_diff );
    1870    11661199 :             hDiracDecBin->q_ChEne = sub( 31, hDiracDecBin->ChEne_e[1][bin] );
    1871    11661199 :             hDiracDecBin->ChEne_e[0][bin] = hDiracDecBin->ChEne_e[1][bin];
    1872             :         }
    1873    13560720 :         move32();
    1874    13560720 :         move16();
    1875    13560720 :         move16();
    1876             : 
    1877    13560720 :         q_diff = sub( hDiracDecBin->ChEneOut_e[0][bin], hDiracDecBin->ChEneOut_e[1][bin] );
    1878    13560720 :         IF( q_diff > 0 )
    1879             :         {
    1880     3035076 :             hDiracDecBin->ChEneOut_fx[1][bin] = L_shr( hDiracDecBin->ChEneOut_fx[1][bin], q_diff );
    1881     3035076 :             hDiracDecBin->q_ChEneOut = sub( 31, hDiracDecBin->ChEneOut_e[0][bin] );
    1882     3035076 :             hDiracDecBin->ChEneOut_e[1][bin] = hDiracDecBin->ChEneOut_e[0][bin];
    1883             :         }
    1884             :         ELSE
    1885             :         {
    1886    10525644 :             hDiracDecBin->ChEneOut_fx[0][bin] = L_shl( hDiracDecBin->ChEneOut_fx[0][bin], q_diff );
    1887    10525644 :             hDiracDecBin->q_ChEneOut = sub( 31, hDiracDecBin->ChEneOut_e[1][bin] );
    1888    10525644 :             hDiracDecBin->ChEneOut_e[0][bin] = hDiracDecBin->ChEneOut_e[1][bin];
    1889             :         }
    1890    13560720 :         move32();
    1891    13560720 :         move16();
    1892    13560720 :         move16();
    1893             : 
    1894    13560720 :         q_diff = sub( hDiracDecBin->ChCrossRe_e[bin], hDiracDecBin->ChCrossIm_e[bin] );
    1895    13560720 :         IF( q_diff > 0 )
    1896             :         {
    1897    11384047 :             hDiracDecBin->ChCrossIm_fx[bin] = L_shr( hDiracDecBin->ChCrossIm_fx[bin], q_diff );
    1898    11384047 :             hDiracDecBin->q_ChCross = sub( 31, hDiracDecBin->ChCrossRe_e[bin] );
    1899    11384047 :             hDiracDecBin->ChCrossIm_e[bin] = hDiracDecBin->ChCrossRe_e[bin];
    1900             :         }
    1901             :         ELSE
    1902             :         {
    1903     2176673 :             hDiracDecBin->ChCrossRe_fx[bin] = L_shl( hDiracDecBin->ChCrossRe_fx[bin], q_diff );
    1904     2176673 :             hDiracDecBin->q_ChCross = sub( 31, hDiracDecBin->ChCrossIm_e[bin] );
    1905     2176673 :             hDiracDecBin->ChCrossRe_e[bin] = hDiracDecBin->ChCrossIm_e[bin];
    1906             :         }
    1907    13560720 :         move32();
    1908    13560720 :         move16();
    1909    13560720 :         move16();
    1910             : 
    1911    13560720 :         q_diff = sub( hDiracDecBin->ChCrossReOut_e[bin], hDiracDecBin->ChCrossImOut_e[bin] );
    1912    13560720 :         IF( q_diff > 0 )
    1913             :         {
    1914    12123109 :             hDiracDecBin->ChCrossImOut_fx[bin] = L_shr( hDiracDecBin->ChCrossImOut_fx[bin], q_diff );
    1915    12123109 :             hDiracDecBin->q_ChCrossOut = sub( 31, hDiracDecBin->ChCrossReOut_e[bin] );
    1916    12123109 :             hDiracDecBin->ChCrossImOut_e[bin] = hDiracDecBin->ChCrossReOut_e[bin];
    1917             :         }
    1918             :         ELSE
    1919             :         {
    1920     1437611 :             hDiracDecBin->ChCrossReOut_fx[bin] = L_shl( hDiracDecBin->ChCrossReOut_fx[bin], q_diff );
    1921     1437611 :             hDiracDecBin->q_ChCrossOut = sub( 31, hDiracDecBin->ChCrossImOut_e[bin] );
    1922     1437611 :             hDiracDecBin->ChCrossReOut_e[bin] = hDiracDecBin->ChCrossImOut_e[bin];
    1923             :         }
    1924    13560720 :         move32();
    1925    13560720 :         move16();
    1926    13560720 :         move16();
    1927             : 
    1928    13560720 :         formulate2x2MixingMatrix_fx( hDiracDecBin->ChEne_fx[0][bin], hDiracDecBin->ChEne_fx[1][bin],
    1929    13560720 :                                      hDiracDecBin->q_ChEne,
    1930             :                                      hDiracDecBin->ChCrossRe_fx[bin], hDiracDecBin->ChCrossIm_fx[bin],
    1931    13560720 :                                      hDiracDecBin->q_ChCross,
    1932             :                                      hDiracDecBin->ChEneOut_fx[0][bin], hDiracDecBin->ChEneOut_fx[1][bin],
    1933    13560720 :                                      hDiracDecBin->q_ChEneOut,
    1934             :                                      hDiracDecBin->ChCrossReOut_fx[bin], hDiracDecBin->ChCrossImOut_fx[bin],
    1935    13560720 :                                      hDiracDecBin->q_ChCrossOut,
    1936    13560720 :                                      prototypeMtx_fx, Mre_fx, Mim_fx, &q_M, hDiracDecBin->reqularizationFactor_fx );
    1937             : 
    1938    13560720 :         IF( LT_16( hDiracDecBin->q_ChEne, hDiracDecBin->q_ChCross ) )
    1939             :         {
    1940     7813697 :             CxRe_fx[0][0] = hDiracDecBin->ChEne_fx[0][bin];
    1941     7813697 :             move32();
    1942     7813697 :             CxRe_fx[1][1] = hDiracDecBin->ChEne_fx[1][bin];
    1943     7813697 :             move32();
    1944     7813697 :             CxRe_fx[1][0] = L_shr( hDiracDecBin->ChCrossRe_fx[bin], sub( hDiracDecBin->q_ChCross, hDiracDecBin->q_ChEne ) );
    1945     7813697 :             move32();
    1946     7813697 :             CxRe_fx[0][1] = L_shr( hDiracDecBin->ChCrossRe_fx[bin], sub( hDiracDecBin->q_ChCross, hDiracDecBin->q_ChEne ) );
    1947     7813697 :             move32();
    1948     7813697 :             CxIm_fx[0][0] = 0;
    1949     7813697 :             move32();
    1950     7813697 :             CxIm_fx[1][1] = 0;
    1951     7813697 :             move32();
    1952     7813697 :             CxIm_fx[1][0] = L_shr( hDiracDecBin->ChCrossIm_fx[bin], sub( hDiracDecBin->q_ChCross, hDiracDecBin->q_ChEne ) );
    1953     7813697 :             move32();
    1954     7813697 :             CxIm_fx[0][1] = L_shr( L_negate( hDiracDecBin->ChCrossIm_fx[bin] ), sub( hDiracDecBin->q_ChCross, hDiracDecBin->q_ChEne ) );
    1955     7813697 :             move32();
    1956     7813697 :             q_Cx = hDiracDecBin->q_ChEne;
    1957     7813697 :             move16();
    1958             :         }
    1959             :         ELSE
    1960             :         {
    1961     5747023 :             CxRe_fx[0][0] = L_shr( hDiracDecBin->ChEne_fx[0][bin], sub( hDiracDecBin->q_ChEne, hDiracDecBin->q_ChCross ) );
    1962     5747023 :             move32();
    1963     5747023 :             CxRe_fx[1][1] = L_shr( hDiracDecBin->ChEne_fx[1][bin], sub( hDiracDecBin->q_ChEne, hDiracDecBin->q_ChCross ) );
    1964     5747023 :             move32();
    1965     5747023 :             CxRe_fx[1][0] = hDiracDecBin->ChCrossRe_fx[bin];
    1966     5747023 :             move32();
    1967     5747023 :             CxRe_fx[0][1] = hDiracDecBin->ChCrossRe_fx[bin];
    1968     5747023 :             move32();
    1969     5747023 :             CxIm_fx[0][0] = 0;
    1970     5747023 :             move32();
    1971     5747023 :             CxIm_fx[1][1] = 0;
    1972     5747023 :             move32();
    1973     5747023 :             CxIm_fx[1][0] = hDiracDecBin->ChCrossIm_fx[bin];
    1974     5747023 :             move32();
    1975     5747023 :             CxIm_fx[0][1] = L_negate( hDiracDecBin->ChCrossIm_fx[bin] );
    1976     5747023 :             move32();
    1977     5747023 :             q_Cx = hDiracDecBin->q_ChCross;
    1978     5747023 :             move16();
    1979             :         }
    1980             : 
    1981             :         /* Make matrix multiplication M*Cx*M' to determine resulting covariance matrix of processing input with M */
    1982    13560720 :         matrixMul_fx( Mre_fx, Mim_fx, &q_M, CxRe_fx, CxIm_fx, &q_Cx, tmpMtxRe_fx, tmpMtxIm_fx, &q_tmp );
    1983    13560720 :         matrixTransp2Mul_fx(
    1984             :             tmpMtxRe_fx, tmpMtxIm_fx, &q_tmp, Mre_fx, Mim_fx, &q_M,
    1985             :             1 /*int Ascale*/,
    1986             :             0 /*int Bscale*/,
    1987             :             resultMtxRe_fx, resultMtxIm_fx, &q_res );
    1988             : 
    1989             :         /* When below the frequency limit where decorrelation is applied, we inject the decorrelated
    1990             :          * residual (or missing) signal component. The procedure is active when there are not enough independent
    1991             :          * signal energy to synthesize a signal with the target covariance matrix from the non-decorrelated signals */
    1992    13560720 :         IF( LT_16( bin, max_band_decorr ) )
    1993             :         {
    1994             :             Word32 decorrelationReductionFactor_fx;
    1995             :             Word16 q_decorrelationReductionFactor;
    1996             : 
    1997             :             /* Subtract the resulting covariance matrix from the target covariance matrix to determine
    1998             :              * what signal component is missing. The result is the target covariance matrix for the residual signal, i.e.,
    1999             :              * a residual covariance matrix. */
    2000     7198065 :             exp = sub( get_min_scalefactor( hDiracDecBin->ChEneOut_fx[0][bin], hDiracDecBin->ChEneOut_fx[1][bin] ), 3 );
    2001     7198065 :             tmp1 = L_shl( hDiracDecBin->ChEneOut_fx[0][bin], exp );
    2002     7198065 :             tmp2 = L_shl( hDiracDecBin->ChEneOut_fx[1][bin], exp );
    2003     7198065 :             q_tmp1 = add( hDiracDecBin->q_ChEneOut, exp );
    2004             : 
    2005     7198065 :             exp = sub( get_min_scalefactor( resultMtxRe_fx[0][0], resultMtxRe_fx[1][1] ), 3 );
    2006     7198065 :             res1 = L_shl( resultMtxRe_fx[0][0], exp );
    2007     7198065 :             res2 = L_shl( resultMtxRe_fx[1][1], exp );
    2008     7198065 :             q_tmp2 = add( q_res, exp );
    2009             : 
    2010     7198065 :             IF( LT_16( q_tmp1, q_tmp2 ) )
    2011             :             {
    2012     2406106 :                 CrEneL_fx = L_max( 0, L_sub( tmp1, L_shr( res1, sub( q_tmp2, q_tmp1 ) ) ) );
    2013     2406106 :                 CrEneR_fx = L_max( 0, L_sub( tmp2, L_shr( res2, sub( q_tmp2, q_tmp1 ) ) ) );
    2014     2406106 :                 q_CrEne = q_tmp1;
    2015     2406106 :                 move16();
    2016             :             }
    2017             :             ELSE
    2018             :             {
    2019     4791959 :                 CrEneL_fx = L_max( 0, L_sub( L_shr( tmp1, sub( q_tmp1, q_tmp2 ) ), res1 ) );
    2020     4791959 :                 CrEneR_fx = L_max( 0, L_sub( L_shr( tmp2, sub( q_tmp1, q_tmp2 ) ), res2 ) );
    2021     4791959 :                 q_CrEne = q_tmp2;
    2022     4791959 :                 move16();
    2023             :             }
    2024             : 
    2025     7198065 :             exp = sub( get_min_scalefactor( hDiracDecBin->ChCrossReOut_fx[bin], hDiracDecBin->ChCrossImOut_fx[bin] ), 3 );
    2026     7198065 :             tmp1 = L_shl( hDiracDecBin->ChCrossReOut_fx[bin], exp );
    2027     7198065 :             tmp2 = L_shl( hDiracDecBin->ChCrossImOut_fx[bin], exp );
    2028     7198065 :             q_tmp1 = add( hDiracDecBin->q_ChCrossOut, exp );
    2029             : 
    2030     7198065 :             exp = sub( get_min_scalefactor( resultMtxRe_fx[1][0], resultMtxIm_fx[1][0] ), 3 );
    2031     7198065 :             res1 = L_shl( resultMtxRe_fx[1][0], exp );
    2032     7198065 :             res2 = L_shl( resultMtxIm_fx[1][0], exp );
    2033     7198065 :             q_tmp2 = add( q_res, exp );
    2034             : 
    2035     7198065 :             IF( LT_16( q_tmp1, q_tmp2 ) )
    2036             :             {
    2037      237021 :                 CrCrossRe_fx = L_sub( tmp1, L_shr( res1, sub( q_tmp2, q_tmp1 ) ) );
    2038      237021 :                 CrCrossIm_fx = L_sub( tmp2, L_shr( res2, sub( q_tmp2, q_tmp1 ) ) );
    2039      237021 :                 q_CrCross = q_tmp1;
    2040      237021 :                 move16();
    2041             :             }
    2042             :             ELSE
    2043             :             {
    2044     6961044 :                 CrCrossRe_fx = L_sub( L_shr( tmp1, sub( q_tmp1, q_tmp2 ) ), res1 );
    2045     6961044 :                 CrCrossIm_fx = L_sub( L_shr( tmp2, sub( q_tmp1, q_tmp2 ) ), res2 );
    2046     6961044 :                 q_CrCross = q_tmp2;
    2047     6961044 :                 move16();
    2048             :             }
    2049             : 
    2050             :             /* The amount of the decorrelated sound is further controlled based on the spatial metadata,
    2051             :              * by determining an energy-suppressed residual covariance matrix that is a control parameter
    2052             :              * that guides the processing of the decorrelated sound to a residual signal.
    2053             :              * The procedure improves quality in e.g. double-talk 2-direction rendering situations.*/
    2054     7198065 :             test();
    2055     7198065 :             IF( EQ_16( ivas_format, MASA_FORMAT ) && LT_32( ivas_total_brate, MASA_STEREO_MIN_BITRATE ) )
    2056             :             {
    2057      514780 :                 decorrelationReductionFactor_fx = ONE_IN_Q30;
    2058      514780 :                 move32();
    2059      514780 :                 q_decorrelationReductionFactor = Q30;
    2060      514780 :                 move16();
    2061             :             }
    2062     6683285 :             ELSE IF( L_or( L_and( EQ_16( ivas_format, MC_FORMAT ), EQ_16( mc_mode, MC_MODE_MCMASA ) ), L_and( EQ_16( ivas_format, MASA_FORMAT ), EQ_16( nchan_transport, 1 ) ) ) )
    2063             :             {
    2064     2005525 :                 exp = 31 - 29;
    2065     2005525 :                 move16();
    2066     2005525 :                 decorrelationReductionFactor_fx = Sqrt32( L_max( 0, hDiracDecBin->frameMeanDiffuseness_fx[bin] ), &exp );
    2067     2005525 :                 q_decorrelationReductionFactor = sub( 31, exp );
    2068             :             }
    2069     4677760 :             ELSE IF( L_and( L_or( EQ_16( ivas_format, SBA_FORMAT ), EQ_16( ivas_format, SBA_ISM_FORMAT ) ), EQ_16( nchan_transport, 1 ) ) )
    2070             :             {
    2071     2855620 :                 decorrelationReductionFactor_fx = ONE_IN_Q30;
    2072     2855620 :                 move32();
    2073     2855620 :                 q_decorrelationReductionFactor = Q30;
    2074     2855620 :                 move16();
    2075             :             }
    2076             :             ELSE
    2077             :             {
    2078     1822140 :                 decorrelationReductionFactor_fx = L_max( 0, hDiracDecBin->frameMeanDiffuseness_fx[bin] );
    2079     1822140 :                 q_decorrelationReductionFactor = 29;
    2080     1822140 :                 move16();
    2081             :             }
    2082             : 
    2083     7198065 :             CrEneL_fx = Mpy_32_32( CrEneL_fx, decorrelationReductionFactor_fx );
    2084     7198065 :             CrEneR_fx = Mpy_32_32( CrEneR_fx, decorrelationReductionFactor_fx );
    2085     7198065 :             q_CrEne = sub( add( q_CrEne, q_decorrelationReductionFactor ), 31 );
    2086     7198065 :             CrCrossRe_fx = Mpy_32_32( CrCrossRe_fx, decorrelationReductionFactor_fx );
    2087     7198065 :             CrCrossIm_fx = Mpy_32_32( CrCrossIm_fx, decorrelationReductionFactor_fx );
    2088     7198065 :             q_CrCross = sub( add( q_CrCross, q_decorrelationReductionFactor ), 31 );
    2089             : 
    2090     7198065 :             formulate2x2MixingMatrix_fx( hDiracDecBin->ChEne_fx[0][bin], hDiracDecBin->ChEne_fx[1][bin],
    2091     7198065 :                                          hDiracDecBin->q_ChEne,
    2092             :                                          0, 0, /* Decorrelated signal has ideally no cross-terms */
    2093             :                                          Q31, CrEneL_fx, CrEneR_fx, q_CrEne,
    2094             :                                          CrCrossRe_fx, CrCrossIm_fx, q_CrCross,
    2095             :                                          prototypeMtx_fx, MdecRe_fx, MdecIm_fx, &q_Mdec, 3277 ); // 3277 = 0.2 in Q14
    2096             :         }
    2097             :         ELSE
    2098             :         {
    2099    19087965 :             FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ )
    2100             :             {
    2101    12725310 :                 set_zero_fx( MdecRe_fx[chA], BINAURAL_CHANNELS );
    2102    12725310 :                 set_zero_fx( MdecIm_fx[chA], BINAURAL_CHANNELS );
    2103             :             }
    2104     6362655 :             q_Mdec = Q31;
    2105     6362655 :             move16();
    2106             :         }
    2107             : 
    2108             :         /* The regularizations at determining mixing matrices cause signal energy to be lost to some degree, which is compensated for here */
    2109    13560720 :         tmp1 = L_add( CrEneL_fx, CrEneR_fx );
    2110    13560720 :         exp = sub( get_min_scalefactor( resultMtxRe_fx[0][0], resultMtxRe_fx[1][1] ), 2 );
    2111    13560720 :         tmp2 = L_add( L_shl( resultMtxRe_fx[0][0], exp ), L_shl( resultMtxRe_fx[1][1], exp ) );
    2112    13560720 :         q_tmp2 = add( q_res, exp );
    2113             : 
    2114             :         /*Limiting value to Q63*/
    2115    13560720 :         IF( GT_16( q_tmp2, 63 ) )
    2116             :         {
    2117       53701 :             tmp2 = L_shl( tmp2, sub( 63, q_tmp2 ) );
    2118       53701 :             q_tmp2 = 63;
    2119       53701 :             move16();
    2120       53701 :             IF( EQ_32( tmp2, -1 ) )
    2121             :             {
    2122           2 :                 tmp2 = 0;
    2123           2 :                 move32();
    2124           2 :                 q_tmp2 = 31;
    2125           2 :                 move16();
    2126             :             }
    2127             :         }
    2128    13560720 :         IF( LT_16( q_CrEne, q_tmp2 ) )
    2129             :         {
    2130     7318567 :             realizedOutputEne_fx = L_add( tmp1, L_shr( tmp2, sub( q_tmp2, q_CrEne ) ) );
    2131     7318567 :             q_realizedOutputEne = q_CrEne;
    2132     7318567 :             move16();
    2133             :         }
    2134             :         ELSE
    2135             :         {
    2136     6242153 :             realizedOutputEne_fx = L_add( L_shr( tmp1, sub( q_CrEne, q_tmp2 ) ), tmp2 );
    2137     6242153 :             q_realizedOutputEne = q_tmp2;
    2138     6242153 :             move16();
    2139             :         }
    2140             : 
    2141    13560720 :         exp = sub( get_min_scalefactor( hDiracDecBin->ChEneOut_fx[0][bin], hDiracDecBin->ChEneOut_fx[1][bin] ), 1 );
    2142    13560720 :         targetOutputEne_fx = L_add( L_shl( hDiracDecBin->ChEneOut_fx[0][bin], exp ), L_shl( hDiracDecBin->ChEneOut_fx[1][bin], exp ) );
    2143    13560720 :         q_targetOutputEne = add( hDiracDecBin->q_ChEneOut, exp );
    2144             : 
    2145    13560720 :         exp = sub( norm_l( targetOutputEne_fx ), 2 );
    2146    13560720 :         targetOutputEne_fx = L_shl( targetOutputEne_fx, exp );
    2147    13560720 :         q_targetOutputEne = add( q_targetOutputEne, exp );
    2148    13560720 :         exp = sub( norm_l( -realizedOutputEne_fx ), 2 );
    2149    13560720 :         realizedOutputEne_fx = L_shl( -realizedOutputEne_fx, exp );
    2150    13560720 :         q_realizedOutputEne = add( q_realizedOutputEne, exp );
    2151    13560720 :         IF( LT_16( q_realizedOutputEne, q_targetOutputEne ) )
    2152             :         {
    2153      105931 :             missingOutputEne_fx = L_max( 0, L_add( L_shr( targetOutputEne_fx, sub( q_targetOutputEne, q_realizedOutputEne ) ), realizedOutputEne_fx ) );
    2154      105931 :             q_missingOutputEne = q_realizedOutputEne;
    2155      105931 :             move16();
    2156             :         }
    2157             :         ELSE
    2158             :         {
    2159    13454789 :             missingOutputEne_fx = L_max( 0, L_add( targetOutputEne_fx, L_shr( realizedOutputEne_fx, sub( q_realizedOutputEne, q_targetOutputEne ) ) ) );
    2160    13454789 :             q_missingOutputEne = q_targetOutputEne;
    2161    13454789 :             move16();
    2162             :         }
    2163             : 
    2164    13560720 :         tmp1 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), missingOutputEne_fx, sub( 31, q_missingOutputEne ), &exp1 );
    2165             : 
    2166             :         {
    2167    13560720 :             tmp2 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), EPSILON_MANT, EPSILON_EXP, &exp2 );
    2168    13560720 :             tmp2 = ISqrt32( tmp2, &exp2 );
    2169    13560720 :             gain_fx = Mpy_32_32( tmp2, Sqrt32( tmp1, &exp1 ) );
    2170    13560720 :             q_gain = sub( 31, add( exp2, exp1 ) );
    2171             :         }
    2172             : 
    2173             : 
    2174             :         // 1073741824 = 4 in Q28
    2175    13560720 :         IF( LT_16( q_gain, Q28 ) )
    2176             :         {
    2177      325421 :             gain_fx = L_min( gain_fx, L_shr( 1073741824, sub( Q28, q_gain ) ) );
    2178             :         }
    2179             :         ELSE
    2180             :         {
    2181    13235299 :             gain_fx = L_min( L_shr( gain_fx, sub( q_gain, Q28 ) ), 1073741824 );
    2182    13235299 :             q_gain = Q28;
    2183    13235299 :             move16();
    2184             :         }
    2185             : 
    2186    40682160 :         FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ )
    2187             :         {
    2188    81364320 :             FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ )
    2189             :             {
    2190    54242880 :                 Mre_fx[chA][chB] = Mpy_32_32( Mre_fx[chA][chB], gain_fx );
    2191    54242880 :                 move32();
    2192    54242880 :                 Mim_fx[chA][chB] = Mpy_32_32( Mim_fx[chA][chB], gain_fx );
    2193    54242880 :                 move32();
    2194             :             }
    2195             :         }
    2196    13560720 :         q_M = sub( add( q_M, q_gain ), 31 );
    2197             : 
    2198    13560720 :         exp = s_min( L_norm_arr( Mre_fx[0], BINAURAL_CHANNELS * BINAURAL_CHANNELS ), L_norm_arr( Mim_fx[0], BINAURAL_CHANNELS * BINAURAL_CHANNELS ) );
    2199    13560720 :         scale_sig32( Mre_fx[0], BINAURAL_CHANNELS * BINAURAL_CHANNELS, exp );
    2200    13560720 :         scale_sig32( Mim_fx[0], BINAURAL_CHANNELS * BINAURAL_CHANNELS, exp );
    2201    13560720 :         q_M = add( q_M, exp );
    2202             : 
    2203    13560720 :         exp = s_min( L_norm_arr( MdecRe_fx[0], BINAURAL_CHANNELS * BINAURAL_CHANNELS ), L_norm_arr( MdecIm_fx[0], BINAURAL_CHANNELS * BINAURAL_CHANNELS ) );
    2204    13560720 :         scale_sig32( MdecRe_fx[0], BINAURAL_CHANNELS * BINAURAL_CHANNELS, exp );
    2205    13560720 :         scale_sig32( MdecIm_fx[0], BINAURAL_CHANNELS * BINAURAL_CHANNELS, exp );
    2206    13560720 :         q_Mdec = add( q_Mdec, exp );
    2207             : 
    2208    13560720 :         q_processMtx_bin = q_processMtx[bin];
    2209    13560720 :         q_processMtxDec_bin = q_processMtxDec[bin];
    2210    13560720 :         move16();
    2211    13560720 :         move16();
    2212             :         /* Store processing matrices */
    2213    40682160 :         FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ )
    2214             :         {
    2215    81364320 :             FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ )
    2216             :             {
    2217    54242880 :                 hDiracDecBin->processMtxRePrev_fx[chA][chB][bin] = hDiracDecBin->processMtxRe_fx[chA][chB][bin]; // q_processMtx_bin
    2218    54242880 :                 move16();
    2219    54242880 :                 hDiracDecBin->processMtxImPrev_fx[chA][chB][bin] = hDiracDecBin->processMtxIm_fx[chA][chB][bin]; // q_processMtx_bin
    2220    54242880 :                 move16();
    2221             : 
    2222    54242880 :                 hDiracDecBin->processMtxDecRePrev_fx[chA][chB][bin] = hDiracDecBin->processMtxDecRe_fx[chA][chB][bin]; // q_processMtxDec_bin
    2223    54242880 :                 move16();
    2224    54242880 :                 hDiracDecBin->processMtxDecImPrev_fx[chA][chB][bin] = hDiracDecBin->processMtxDecIm_fx[chA][chB][bin]; // q_processMtxDec_bin
    2225    54242880 :                 move16();
    2226             : 
    2227    54242880 :                 hDiracDecBin->processMtxRe_fx[chA][chB][bin] = extract_h( Mre_fx[chA][chB] ); // q_M -16
    2228    54242880 :                 move16();
    2229    54242880 :                 hDiracDecBin->processMtxIm_fx[chA][chB][bin] = extract_h( Mim_fx[chA][chB] ); // q_M -16
    2230    54242880 :                 move16();
    2231             : 
    2232    54242880 :                 hDiracDecBin->processMtxDecRe_fx[chA][chB][bin] = extract_h( MdecRe_fx[chA][chB] ); // q_Mdec -16
    2233    54242880 :                 move16();
    2234    54242880 :                 hDiracDecBin->processMtxDecIm_fx[chA][chB][bin] = extract_h( MdecIm_fx[chA][chB] ); // q_Mdec -16
    2235    54242880 :                 move16();
    2236             :             }
    2237             :         }
    2238    13560720 :         q_processMtxPrev[bin] = q_processMtx_bin;
    2239    13560720 :         move16();
    2240    13560720 :         q_processMtxDecPrev[bin] = q_processMtxDec_bin;
    2241    13560720 :         move16();
    2242    13560720 :         q_processMtx[bin] = sub( q_M, 16 );
    2243    13560720 :         move16();
    2244    13560720 :         q_processMtxDec[bin] = sub( q_Mdec, 16 );
    2245    13560720 :         move16();
    2246             : 
    2247    13560720 :         IF( separateCenterChannelRendering )
    2248             :         {
    2249             :             /* The rendering of the separate center channel in masa + mono mode.
    2250             :              * The center channel is processed with a gain factor 0.8414f to match the loudness of different processing paths */
    2251             :             Word32 lRealp_fx, lImagp_fx, rRealp_fx, rImagp_fx;
    2252             :             Word32 gainFactor_fx;
    2253             :             Word16 q_tmp_sq;
    2254      447240 :             Word16 aziDeg = 0;
    2255      447240 :             move16();
    2256      447240 :             Word16 eleDeg = 0;
    2257      447240 :             move16();
    2258      447240 :             UWord8 instantChange = 0;
    2259      447240 :             move16();
    2260             : 
    2261      447240 :             exp = sub( 31, hDiracDecBin->q_earlyPartEneCorrection );
    2262      447240 :             tmp1 = Sqrt32( hDiracDecBin->earlyPartEneCorrection_fx[bin], &exp );
    2263      447240 :             q_tmp_sq = sub( 31, exp );
    2264      447240 :             IF( EQ_16( ivas_format, MASA_ISM_FORMAT ) )
    2265             :             {
    2266      441240 :                 gainFactor_fx = Mpy_32_32( 1705746262, tmp1 ); // 1705746262 = 0.7943f in Q31
    2267             :             }
    2268             :             ELSE
    2269             :             {
    2270        6000 :                 gainFactor_fx = Mpy_32_32( 1806892741, tmp1 ); // 1806892741 = 0.8414f in Q31
    2271             :             }
    2272      447240 :             q_gain = sub( add( q_tmp_sq, 31 ), 31 );
    2273             : 
    2274      447240 :             q_processMtx_bin = q_processMtx_SCCR[bin];
    2275      447240 :             move16();
    2276             : 
    2277     1127920 :             FOR( chB = 0; chB < nchanSeparateChannels; chB++ )
    2278             :             {
    2279      680680 :                 IF( EQ_16( ivas_format, MASA_ISM_FORMAT ) )
    2280             :                 {
    2281      674680 :                     IF( EQ_16( ism_mode, ISM_MASA_MODE_DISC ) )
    2282             :                     {
    2283      372360 :                         aziDeg = hMasaIsmData->azimuth_ism[chB][dirac_read_idx];
    2284      372360 :                         move16();
    2285      372360 :                         eleDeg = hMasaIsmData->elevation_ism[chB][dirac_read_idx];
    2286      372360 :                         move16();
    2287             :                     }
    2288             :                     ELSE
    2289             :                     {
    2290      302320 :                         aziDeg = hMasaIsmData->azimuth_separated_ism[dirac_read_idx];
    2291      302320 :                         move16();
    2292      302320 :                         eleDeg = hMasaIsmData->elevation_separated_ism[dirac_read_idx];
    2293      302320 :                         move16();
    2294      302320 :                         instantChange = 1;
    2295      302320 :                         move16();
    2296             :                     }
    2297             :                 }
    2298             : 
    2299     2042040 :                 FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ )
    2300             :                 {
    2301     1361360 :                     hDiracDecBin->processMtxRePrev_fx[chA][chB + 2][bin] = hDiracDecBin->processMtxRe_fx[chA][chB + 2][bin];
    2302     1361360 :                     move16();
    2303     1361360 :                     hDiracDecBin->processMtxImPrev_fx[chA][chB + 2][bin] = hDiracDecBin->processMtxIm_fx[chA][chB + 2][bin];
    2304     1361360 :                     move16();
    2305             :                 }
    2306      680680 :                 q_processMtxPrev_SCCR[bin] = q_processMtx_bin;
    2307      680680 :                 move16();
    2308             : 
    2309      680680 :                 getDirectPartGains_fx( bin, aziDeg, eleDeg, &lRealp_fx, &lImagp_fx, &rRealp_fx, &rImagp_fx, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[chB], isHeadtracked );
    2310             : 
    2311      680680 :                 hDiracDecBin->processMtxRe_fx[0][chB + 2][bin] = extract_h( Mpy_32_32( lRealp_fx, gainFactor_fx ) );
    2312      680680 :                 move16();
    2313      680680 :                 hDiracDecBin->processMtxIm_fx[0][chB + 2][bin] = extract_h( Mpy_32_32( lImagp_fx, gainFactor_fx ) );
    2314      680680 :                 move16();
    2315      680680 :                 hDiracDecBin->processMtxRe_fx[1][chB + 2][bin] = extract_h( Mpy_32_32( rRealp_fx, gainFactor_fx ) );
    2316      680680 :                 move16();
    2317      680680 :                 hDiracDecBin->processMtxIm_fx[1][chB + 2][bin] = extract_h( Mpy_32_32( rImagp_fx, gainFactor_fx ) );
    2318      680680 :                 move16();
    2319      680680 :                 q_processMtx_SCCR[bin] = sub( sub( add( Q28, q_gain ), 31 ), 16 );
    2320      680680 :                 move16();
    2321             : 
    2322      680680 :                 IF( instantChange )
    2323             :                 {
    2324      906960 :                     FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ )
    2325             :                     {
    2326      604640 :                         hDiracDecBin->processMtxRePrev_fx[chA][chB + 2][bin] = hDiracDecBin->processMtxRe_fx[chA][chB + 2][bin];
    2327      604640 :                         move16();
    2328      604640 :                         hDiracDecBin->processMtxImPrev_fx[chA][chB + 2][bin] = hDiracDecBin->processMtxIm_fx[chA][chB + 2][bin];
    2329      604640 :                         move16();
    2330             :                     }
    2331      302320 :                     q_processMtxPrev_SCCR[bin] = q_processMtx_SCCR[bin];
    2332      302320 :                     move16();
    2333             :                 }
    2334             :             }
    2335             :         }
    2336             :     }
    2337             :     /* Aligning Q-factors of all bins in the processing matrices to a common Q-factor */
    2338      275012 :     minimum_s( q_processMtx, nBins, &hDiracDecBin->q_processMtx );
    2339      275012 :     minimum_s( q_processMtxPrev, nBins, &hDiracDecBin->q_processMtxPrev );
    2340      275012 :     IF( separateCenterChannelRendering )
    2341             :     {
    2342        9653 :         minimum_s( q_processMtx_SCCR, nBins, &hDiracDecBin->q_processMtxSCCR );
    2343        9653 :         minimum_s( q_processMtxPrev_SCCR, nBins, &hDiracDecBin->q_processMtxPrevSCCR );
    2344             :     }
    2345      275012 :     hDiracDecBin->q_processMtx = s_min( hDiracDecBin->q_processMtx, hDiracDecBin->q_processMtxSCCR );
    2346      275012 :     move16();
    2347      275012 :     hDiracDecBin->q_processMtxPrev = s_min( hDiracDecBin->q_processMtxPrev, hDiracDecBin->q_processMtxPrevSCCR );
    2348      275012 :     move16();
    2349      275012 :     hDiracDecBin->q_processMtxSCCR = hDiracDecBin->q_processMtx;
    2350      275012 :     move16();
    2351      275012 :     hDiracDecBin->q_processMtxPrevSCCR = hDiracDecBin->q_processMtxPrev;
    2352      275012 :     move16();
    2353      275012 :     minimum_s( q_processMtxDec, nBins, &hDiracDecBin->q_processMtxDec );
    2354      275012 :     minimum_s( q_processMtxDecPrev, nBins, &hDiracDecBin->q_processMtxDecPrev );
    2355             : 
    2356    13835732 :     FOR( bin = 0; bin < nBins; bin++ )
    2357             :     {
    2358    40682160 :         FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ )
    2359             :         {
    2360    81364320 :             FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ )
    2361             :             {
    2362    54242880 :                 hDiracDecBin->processMtxRe_fx[chA][chB][bin] = shr( hDiracDecBin->processMtxRe_fx[chA][chB][bin], sub( q_processMtx[bin], hDiracDecBin->q_processMtx ) ); // hDiracDecBin->q_processMtx
    2363    54242880 :                 move16();
    2364    54242880 :                 hDiracDecBin->processMtxIm_fx[chA][chB][bin] = shr( hDiracDecBin->processMtxIm_fx[chA][chB][bin], sub( q_processMtx[bin], hDiracDecBin->q_processMtx ) ); // hDiracDecBin->q_processMtx
    2365    54242880 :                 move16();
    2366    54242880 :                 hDiracDecBin->processMtxRePrev_fx[chA][chB][bin] = shr( hDiracDecBin->processMtxRePrev_fx[chA][chB][bin], sub( q_processMtxPrev[bin], hDiracDecBin->q_processMtxPrev ) ); // hDiracDecBin->q_processMtxPrev
    2367    54242880 :                 move16();
    2368    54242880 :                 hDiracDecBin->processMtxImPrev_fx[chA][chB][bin] = shr( hDiracDecBin->processMtxImPrev_fx[chA][chB][bin], sub( q_processMtxPrev[bin], hDiracDecBin->q_processMtxPrev ) ); // hDiracDecBin->q_processMtxPrev
    2369    54242880 :                 move16();
    2370    54242880 :                 hDiracDecBin->processMtxDecRe_fx[chA][chB][bin] = shr( hDiracDecBin->processMtxDecRe_fx[chA][chB][bin], sub( q_processMtxDec[bin], hDiracDecBin->q_processMtxDec ) ); // hDiracDecBin->q_processMtxDec
    2371    54242880 :                 move16();
    2372    54242880 :                 hDiracDecBin->processMtxDecIm_fx[chA][chB][bin] = shr( hDiracDecBin->processMtxDecIm_fx[chA][chB][bin], sub( q_processMtxDec[bin], hDiracDecBin->q_processMtxDec ) ); // hDiracDecBin->q_processMtxDec
    2373    54242880 :                 move16();
    2374    54242880 :                 hDiracDecBin->processMtxDecRePrev_fx[chA][chB][bin] = shr( hDiracDecBin->processMtxDecRePrev_fx[chA][chB][bin], sub( q_processMtxDecPrev[bin], hDiracDecBin->q_processMtxDecPrev ) ); // hDiracDecBin->q_processMtxDecPrev
    2375    54242880 :                 move16();
    2376    54242880 :                 hDiracDecBin->processMtxDecImPrev_fx[chA][chB][bin] = shr( hDiracDecBin->processMtxDecImPrev_fx[chA][chB][bin], sub( q_processMtxDecPrev[bin], hDiracDecBin->q_processMtxDecPrev ) ); // hDiracDecBin->q_processMtxDecPrev
    2377    54242880 :                 move16();
    2378             :             }
    2379    27121440 :             IF( separateCenterChannelRendering )
    2380             :             {
    2381     2255840 :                 FOR( chB = 0; chB < nchanSeparateChannels; chB++ )
    2382             :                 {
    2383     1361360 :                     hDiracDecBin->processMtxRe_fx[chA][chB + 2][bin] = shr( hDiracDecBin->processMtxRe_fx[chA][chB + 2][bin], sub( q_processMtx_SCCR[bin], hDiracDecBin->q_processMtx ) ); // hDiracDecBin->q_processMtx
    2384     1361360 :                     move16();
    2385     1361360 :                     hDiracDecBin->processMtxIm_fx[chA][chB + 2][bin] = shr( hDiracDecBin->processMtxIm_fx[chA][chB + 2][bin], sub( q_processMtx_SCCR[bin], hDiracDecBin->q_processMtx ) ); // hDiracDecBin->q_processMtx
    2386     1361360 :                     move16();
    2387     1361360 :                     hDiracDecBin->processMtxRePrev_fx[chA][chB + 2][bin] = shr( hDiracDecBin->processMtxRePrev_fx[chA][chB + 2][bin], sub( q_processMtxPrev_SCCR[bin], hDiracDecBin->q_processMtxPrev ) ); // hDiracDecBin->q_processMtxPrev
    2388     1361360 :                     move16();
    2389     1361360 :                     hDiracDecBin->processMtxImPrev_fx[chA][chB + 2][bin] = shr( hDiracDecBin->processMtxImPrev_fx[chA][chB + 2][bin], sub( q_processMtxPrev_SCCR[bin], hDiracDecBin->q_processMtxPrev ) ); // hDiracDecBin->q_processMtxPrev
    2390     1361360 :                     move16();
    2391             :                 }
    2392             :             }
    2393             :         }
    2394             :     }
    2395             : 
    2396      275012 :     return;
    2397             : }
    2398             : 
    2399      275012 : static void ivas_dirac_dec_binaural_process_output_fx(
    2400             :     DIRAC_DEC_BIN_HANDLE hDiracDecBin,
    2401             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom,
    2402             :     HANDLE_CLDFB_FILTER_BANK cldfbSynDec[MAX_OUTPUT_CHANNELS],
    2403             :     Word32 *output_fx[], /*q_out*/
    2404             :     Word16 *q_out,
    2405             :     Word32 inRe_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*q_input*/
    2406             :     Word32 inIm_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*q_input*/
    2407             :     const Word16 q_input,
    2408             :     const Word16 max_band_decorr,
    2409             :     const Word16 numInChannels,
    2410             :     const Word16 processReverb,
    2411             :     const Word16 subframe,
    2412             :     const Word16 q_mat )
    2413             : {
    2414             :     Word16 slot, bin, chA, chB;
    2415             :     Word16 nBins;
    2416             :     Word16 offsetSamples;
    2417             :     Word16 nSlots;
    2418             : 
    2419      275012 :     nBins = hSpatParamRendCom->num_freq_bands;
    2420      275012 :     offsetSamples = 0;
    2421      275012 :     nSlots = hSpatParamRendCom->subframe_nbslots[subframe];
    2422      275012 :     move16();
    2423      275012 :     move16();
    2424      275012 :     move16();
    2425             : 
    2426             :     Word32 decSlotRe_fx[BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX], decSlotIm_fx[BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX];
    2427             :     Word32 outSlotRe_fx[CLDFB_NO_CHANNELS_MAX], outSlotIm_fx[CLDFB_NO_CHANNELS_MAX];
    2428             :     Word32 reverbRe_fx[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
    2429             :     Word32 reverbIm_fx[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
    2430             :     Word16 q_inp[6][CLDFB_SLOTS_PER_SUBFRAME];
    2431             :     Word16 interpVal_fx;
    2432             :     Word32 *decSlotRePointer_fx;
    2433             :     Word32 *decSlotImPointer_fx;
    2434      275012 :     Word16 q_inp_mix, q_reverb = 31;
    2435      275012 :     move16();
    2436      275012 :     Word16 ch_len = s_max( 4, numInChannels );
    2437             :     Word16 eff_q;
    2438             : 
    2439             : 
    2440      275012 :     IF( processReverb )
    2441             :     {
    2442             :         /* Process second / room effect part of binaural output when needed */
    2443      112977 :         ivas_binaural_reverb_processSubframe_fx( hDiracDecBin->hReverb, numInChannels, nSlots, inRe_fx, inIm_fx, reverbRe_fx, reverbIm_fx );
    2444             :     }
    2445             : 
    2446             :     // scaling input and reverb to same q//
    2447             :     // input scaling is to maintain precision in ivas_dirac_dec_decorrelate_slot fn//
    2448      275012 :     Word16 shift = s_min( L_norm_arr( cldfbSynDec[0]->cldfb_state_fx, cldfbSynDec[0]->p_filter_length ), L_norm_arr( cldfbSynDec[1]->cldfb_state_fx, cldfbSynDec[1]->p_filter_length ) );
    2449      275012 :     q_inp_mix = 31;
    2450      275012 :     move16();
    2451     1377188 :     FOR( Word16 i = 0; i < ch_len; i++ )
    2452             :     {
    2453     5483140 :         FOR( Word16 j = 0; j < nSlots; j++ )
    2454             :         {
    2455     4380964 :             q_inp[i][j] = s_min( L_norm_arr( inRe_fx[i][j], nBins ), L_norm_arr( inIm_fx[i][j], nBins ) );
    2456     4380964 :             move16();
    2457     4380964 :             test();
    2458     4380964 :             IF( ( processReverb ) && LT_16( i, 2 ) )
    2459             :             {
    2460      899274 :                 q_reverb = s_min( L_norm_arr( reverbRe_fx[i][j], CLDFB_NO_CHANNELS_MAX ), L_norm_arr( reverbIm_fx[i][j], CLDFB_NO_CHANNELS_MAX ) );
    2461      899274 :                 q_inp[i][j] = s_min( q_reverb, q_inp[i][j] );
    2462      899274 :                 move16();
    2463             :             }
    2464     4380964 :             q_inp_mix = s_min( q_inp[i][j], q_inp_mix );
    2465             :         }
    2466             :     }
    2467             : 
    2468      275012 :     q_inp_mix = sub( q_inp_mix, 3 ); // gaurded bits//
    2469             : 
    2470      275012 :     Word16 cldfb_state_shift = sub( add( add( q_inp_mix, q_mat ), sub( q_input, 16 ) ), cldfbSynDec[0]->Q_cldfb_state );
    2471      275012 :     IF( GT_16( cldfb_state_shift, shift ) )
    2472             :     {
    2473           0 :         q_inp_mix = sub( add( q_inp_mix, shift ), cldfb_state_shift );
    2474           0 :         cldfb_state_shift = shift;
    2475           0 :         move16();
    2476             :     }
    2477             : 
    2478             : 
    2479      275012 :     eff_q = sub( add( q_inp_mix, q_mat ), 15 );
    2480             : 
    2481     1377188 :     FOR( Word16 i = 0; i < ch_len; i++ )
    2482             :     {
    2483     5483140 :         FOR( Word16 j = 0; j < nSlots; j++ )
    2484             :         {
    2485             : 
    2486     4380964 :             scale_sig32( inRe_fx[i][j], nBins, q_inp_mix ); /*q_input + q_inp_mix*/
    2487     4380964 :             scale_sig32( inIm_fx[i][j], nBins, q_inp_mix ); /*q_input + q_inp_mix*/
    2488     4380964 :             test();
    2489     4380964 :             IF( processReverb && LT_16( i, 2 ) )
    2490             :             {
    2491      899274 :                 scale_sig32( reverbRe_fx[i][j], CLDFB_NO_CHANNELS_MAX, eff_q ); /*q_inp_mix+q_mat-15*/
    2492      899274 :                 scale_sig32( reverbIm_fx[i][j], CLDFB_NO_CHANNELS_MAX, eff_q ); /*q_inp_mix+q_mat-15*/
    2493             :             }
    2494             :         }
    2495             :     }
    2496             : 
    2497             :     // scaling cldfb states to q_result-1//
    2498      275012 :     scale_sig32( cldfbSynDec[0]->cldfb_state_fx, cldfbSynDec[0]->p_filter_length, cldfb_state_shift );
    2499      275012 :     cldfbSynDec[0]->Q_cldfb_state = add( cldfbSynDec[0]->Q_cldfb_state, cldfb_state_shift );
    2500      275012 :     scale_sig32( cldfbSynDec[1]->cldfb_state_fx, cldfbSynDec[1]->p_filter_length, cldfb_state_shift );
    2501      275012 :     cldfbSynDec[1]->Q_cldfb_state = add( cldfbSynDec[1]->Q_cldfb_state, cldfb_state_shift );
    2502      275012 :     move16();
    2503      275012 :     move16();
    2504             : 
    2505      275012 :     q_inp_mix = add( q_inp_mix, q_input );
    2506             : 
    2507      275012 :     interpVal_fx = 0;
    2508      275012 :     move16();
    2509      275012 :     Word16 q_result = sub( add( q_inp_mix, q_mat ), 15 ); // setting it prior//
    2510      275012 :     cldfbSynDec[0]->Q_cldfb_state = sub( q_result, 1 );
    2511      275012 :     cldfbSynDec[1]->Q_cldfb_state = sub( q_result, 1 );
    2512      275012 :     move16();
    2513      275012 :     move16();
    2514             : 
    2515     1368133 :     FOR( slot = 0; slot < nSlots; slot++ )
    2516             :     {
    2517     1093121 :         IF( NE_16( slot, sub( nSlots, 1 ) ) )
    2518             :         {
    2519      818109 :             interpVal_fx = add( interpVal_fx, slot_fx[nSlots - 1] ); /*Q15*/
    2520             :         }
    2521             :         ELSE
    2522             :         {
    2523      275012 :             interpVal_fx = 32767; /*Q15*/
    2524      275012 :             move16();
    2525             :         }
    2526     1093121 :         test();
    2527     1093121 :         IF( !hDiracDecBin->useTdDecorr && ( max_band_decorr > 0 ) )
    2528             :         {
    2529      556721 :             ivas_dirac_dec_decorrelate_slot_fx( hDiracDecBin, nBins, slot, inRe_fx, inIm_fx, q_inp_mix, decSlotRe_fx, decSlotIm_fx );
    2530             :         }
    2531             : 
    2532     3279363 :         FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ )
    2533             :         {
    2534             :             Word32 *outSlotRePr_fx, *outSlotImPr_fx; /* Pointers needed for function call compatibility */
    2535             : 
    2536     2186242 :             set_zero_fx( outSlotRe_fx, CLDFB_NO_CHANNELS_MAX );
    2537     2186242 :             set_zero_fx( outSlotIm_fx, CLDFB_NO_CHANNELS_MAX );
    2538             : 
    2539             :             /* Processing of the first / HRTF part of the binaural output. */
    2540     6672764 :             FOR( chB = 0; chB < numInChannels; chB++ )
    2541             :             {
    2542     4486522 :                 IF( LT_16( chB, BINAURAL_CHANNELS ) )
    2543             :                 {
    2544             :                     /* Decorrelator signal for TD decorrelation is stored in two input channels above the two normal inputs.
    2545             :                      * It should be noted that TD decorrelation is used only in cases where numInChannels is 2. If this
    2546             :                      * changes, additional adjustments are required. When using CLDFB decorrelator, we simply assign the
    2547             :                      * pointers to buffers. */
    2548     4372484 :                     IF( hDiracDecBin->useTdDecorr )
    2549             :                     {
    2550     1636508 :                         decSlotRePointer_fx = inRe_fx[chB + 2][slot];
    2551     1636508 :                         decSlotImPointer_fx = inIm_fx[chB + 2][slot];
    2552             :                     }
    2553             :                     ELSE
    2554             :                     {
    2555     2735976 :                         decSlotRePointer_fx = decSlotRe_fx[chB];
    2556     2735976 :                         decSlotImPointer_fx = decSlotIm_fx[chB];
    2557             :                     }
    2558             :                 }
    2559             :                 ELSE
    2560             :                 {
    2561      114038 :                     decSlotRePointer_fx = NULL; /* below these pointers are used only for chB < 2 */
    2562      114038 :                     decSlotImPointer_fx = NULL;
    2563             :                 }
    2564             : 
    2565             : 
    2566   225293642 :                 FOR( bin = 0; bin < nBins; bin++ )
    2567             :                 {
    2568             :                     Word16 gain;
    2569             :                     /* Mixing using the formulated processing matrix M */
    2570   220807120 :                     gain = add( mult( sub( 32767, interpVal_fx ), hDiracDecBin->processMtxRePrev_fx[chA][chB][bin] ), mult( interpVal_fx, hDiracDecBin->processMtxRe_fx[chA][chB][bin] ) ); // Q11
    2571             : 
    2572   220807120 :                     outSlotRe_fx[bin] = Madd_32_16( outSlotRe_fx[bin], inRe_fx[chB][slot][bin], gain ); // q_inp_mix-4//q_result
    2573   220807120 :                     outSlotIm_fx[bin] = Madd_32_16( outSlotIm_fx[bin], inIm_fx[chB][slot][bin], gain ); // q_inp_mix-4//q_result
    2574   220807120 :                     move32();
    2575   220807120 :                     move32();
    2576             : 
    2577   220807120 :                     gain = add( mult( sub( 32767, interpVal_fx ), hDiracDecBin->processMtxImPrev_fx[chA][chB][bin] ), mult( interpVal_fx, hDiracDecBin->processMtxIm_fx[chA][chB][bin] ) ); // Q11
    2578             : 
    2579             :                     // interpVal * hDiracDecBin->processMtxIm[chA][chB][bin];
    2580   220807120 :                     outSlotRe_fx[bin] = Msub_32_16( outSlotRe_fx[bin], inIm_fx[chB][slot][bin], gain ); // q_inp_mix-4//q_result
    2581   220807120 :                     outSlotIm_fx[bin] = Madd_32_16( outSlotIm_fx[bin], inRe_fx[chB][slot][bin], gain ); // q_inp_mix-4//q_result
    2582             : 
    2583   220807120 :                     move32();
    2584   220807120 :                     move32();
    2585             : 
    2586             :                     /* Mixing decorrelated signals using the formulated residual processing matrix Mdec */
    2587   220807120 :                     test();
    2588   220807120 :                     IF( LT_16( bin, max_band_decorr ) && LT_16( chB, 2 ) )
    2589             :                     {
    2590   113884780 :                         gain = add( mult( sub( 32767, interpVal_fx ), hDiracDecBin->processMtxDecRePrev_fx[chA][chB][bin] ), mult( interpVal_fx, hDiracDecBin->processMtxDecRe_fx[chA][chB][bin] ) ); // Q11
    2591             :                         // interpVal * hDiracDecBin->processMtxDecRe[chA][chB][bin];
    2592   113884780 :                         outSlotRe_fx[bin] = Madd_32_16( outSlotRe_fx[bin], decSlotRePointer_fx[bin], gain ); // q_inp_mix-4//q_result
    2593   113884780 :                         outSlotIm_fx[bin] = Madd_32_16( outSlotIm_fx[bin], decSlotImPointer_fx[bin], gain ); // q_inp_mix-4//q_result
    2594   113884780 :                         move32();
    2595   113884780 :                         move32();
    2596             : 
    2597             : 
    2598   113884780 :                         gain = add( mult( sub( 32767, interpVal_fx ), hDiracDecBin->processMtxDecImPrev_fx[chA][chB][bin] ), mult( interpVal_fx, hDiracDecBin->processMtxDecIm_fx[chA][chB][bin] ) ); // Q11
    2599   113884780 :                         outSlotRe_fx[bin] = Msub_32_16( outSlotRe_fx[bin], decSlotImPointer_fx[bin], gain );                                                                                          // q_inp_mix-4//q_result
    2600   113884780 :                         outSlotIm_fx[bin] = Madd_32_16( outSlotIm_fx[bin], decSlotRePointer_fx[bin], gain );                                                                                          // q_inp_mix-4//q_result
    2601   113884780 :                         move32();
    2602   113884780 :                         move32();
    2603             :                     }
    2604             :                 }
    2605             :             }
    2606             : 
    2607             : 
    2608     2186242 :             IF( processReverb )
    2609             :             {
    2610             :                 /* Combine second (reverb) part with the first (HRTF) part to obtain binaural output signal with room effect */
    2611      899274 :                 v_add_fx( outSlotRe_fx, reverbRe_fx[chA][slot], outSlotRe_fx, CLDFB_NO_CHANNELS_MAX );
    2612      899274 :                 v_add_fx( outSlotIm_fx, reverbIm_fx[chA][slot], outSlotIm_fx, CLDFB_NO_CHANNELS_MAX );
    2613             :             }
    2614             : 
    2615             : 
    2616     2186242 :             outSlotRePr_fx = &( outSlotRe_fx[0] );
    2617     2186242 :             outSlotImPr_fx = &( outSlotIm_fx[0] );
    2618             : 
    2619     2186242 :             cldfbSynthesis_ivas_fx( &outSlotRePr_fx, &outSlotImPr_fx, &( output_fx[chA][nBins * slot + offsetSamples] ), nBins, 0, 0, cldfbSynDec[chA] );
    2620     2186242 :             cldfbSynDec[chA]->Q_cldfb_state = sub( q_result, 1 );
    2621     2186242 :             move16();
    2622             :         }
    2623             :     }
    2624      275012 :     *q_out = sub( q_result, 1 );
    2625      275012 :     move16();
    2626      275012 :     return;
    2627             : }
    2628             : 
    2629             : 
    2630       74400 : static void adaptTransportSignalsHeadtracked_fx(
    2631             :     COMBINED_ORIENTATION_HANDLE hHeadTrackData,
    2632             :     Word32 inRe_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*q_inp*/
    2633             :     Word32 inIm_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*q_inp*/
    2634             :     Word16 q_inp,
    2635             :     const Word16 nBins,
    2636             :     const Word16 nSlots,
    2637             :     Word32 Rmat[3][3] /*Q30*/ )
    2638             : {
    2639             :     Word16 slot, ch, bin, louderCh;
    2640             :     Word32 mono_factor_ILD, mono_factor;
    2641             :     Word32 y_val, mono_factor_rotation, ene_proc, ene_target, ILD;
    2642             :     Word16 ene_proc_e, ene_target_e;
    2643             :     Word16 max_band;
    2644             :     Word32 eqVal;
    2645       74400 :     Word16 band_idx, bin_lo, bin_hi, norm, shift = 31;
    2646             :     Word32 temp_div;
    2647             :     Word16 e_div, is_zero, i;
    2648       74400 :     move16();
    2649             : 
    2650      223200 :     FOR( i = 0; i < 2; i++ )
    2651             :     {
    2652      744000 :         FOR( Word16 j = 0; j < nSlots; j++ )
    2653             :         {
    2654      595200 :             norm = s_min( L_norm_arr( inRe_fx[i][j], nBins ), L_norm_arr( inIm_fx[i][j], nBins ) );
    2655      595200 :             shift = s_min( norm, shift );
    2656             :         }
    2657             :     }
    2658             : 
    2659             :     /* Determine head-orientation-based mono factor.
    2660             :     Rmat[1][1] entry informs how close the ears are aligned according to transport signals. */
    2661             : 
    2662       74400 :     y_val = L_sub( ONE_IN_Q30, L_abs( Rmat[1][1] ) );                                                        // Q30
    2663       74400 :     mono_factor_rotation = Mpy_32_16_1( L_sub( y_val, ADAPT_HTPROTO_ROT_LIM_0_FX ), TWO_POINT_FIVE_IN_Q13 ); // Q28
    2664       74400 :     mono_factor_rotation = L_max( 0, L_min( ONE_IN_Q28, mono_factor_rotation ) );
    2665             : 
    2666       74400 :     IF( EQ_32( mono_factor_rotation, ONE_IN_Q28 ) )
    2667             :     {
    2668       19453 :         mono_factor_rotation = ONE_IN_Q31;
    2669             :     }
    2670             :     ELSE
    2671             :     {
    2672       54947 :         mono_factor_rotation = L_shl( mono_factor_rotation, 3 ); // Q31
    2673             :     }
    2674       74400 :     move32();
    2675             : 
    2676             :     /* Adapt transport signals in frequency bands */
    2677             :     /* optimization grouping CLDFB bins into MASA bands (they are readily available in ROM and suitable for the task) AND group CLDFB slots into sub-frames */
    2678             : 
    2679       74400 :     max_band = 0;
    2680       74400 :     move16();
    2681     1806000 :     WHILE( max_band < MASA_FREQUENCY_BANDS && MASA_band_grouping_24[max_band] < nBins )
    2682             :     {
    2683     1731600 :         max_band = add( max_band, 1 );
    2684             :     }
    2685             : 
    2686       74400 :     shift = sub( shift, 5 );
    2687             :     // 5 is gaurded bits needed//
    2688             :     Word32 re, img, temp;
    2689             :     Word16 s, q_band_nrg, q_temp[2];
    2690     1806000 :     FOR( band_idx = 0; band_idx < max_band; band_idx++ )
    2691             :     {
    2692             :         Word32 ch_nrg[2];   /* storage for input signal channel energies */
    2693             :         Word64 W_ch_nrg[2]; /* storage for input signal channel energies */
    2694     1731600 :         bin_lo = MASA_band_grouping_24[band_idx];
    2695     1731600 :         bin_hi = s_min( MASA_band_grouping_24[band_idx + 1], (Word16) nBins );
    2696             : 
    2697     5194800 :         FOR( ch = 0; ch < 2; ch++ )
    2698             :         {
    2699     3463200 :             W_ch_nrg[ch] = 0;
    2700     3463200 :             move32();
    2701    17316000 :             FOR( slot = 0; slot < nSlots; slot++ )
    2702             :             {
    2703    40924800 :                 FOR( bin = bin_lo; bin < bin_hi; bin++ )
    2704             :                 {
    2705    27072000 :                     re = L_shl( inRe_fx[ch][slot][bin], shift );
    2706    27072000 :                     img = L_shl( inIm_fx[ch][slot][bin], shift );
    2707             : 
    2708    27072000 :                     W_ch_nrg[ch] = W_add( W_ch_nrg[ch], ( W_add( W_mult0_32_32( re, re ), W_mult0_32_32( img, img ) ) ) ); // 2(q_inp +shift)
    2709    27072000 :                     move64();
    2710             :                 }
    2711             :             }
    2712     3463200 :             s = W_norm( W_ch_nrg[ch] );
    2713     3463200 :             ch_nrg[ch] = W_extract_h( W_shl( W_ch_nrg[ch], s ) ); // Q: 2*(q_inp+shift) + s - 32
    2714     3463200 :             q_temp[ch] = sub( add( shl( add( q_inp, shift ), 1 ), s ), 32 );
    2715     3463200 :             move32();
    2716     3463200 :             move16();
    2717             : 
    2718     3463200 :             hHeadTrackData->chEneIIR_fx[ch][band_idx] = Mpy_32_16_1( hHeadTrackData->chEneIIR_fx[ch][band_idx], ADAPT_HTPROTO_IIR_FAC_FX ); // q_chEneIIR
    2719     3463200 :             move32();
    2720     3463200 :             temp = Mpy_32_16_1( ch_nrg[ch], sub( 32767, ADAPT_HTPROTO_IIR_FAC_FX ) ); // q_temp[ch]
    2721     3463200 :             IF( LT_16( hHeadTrackData->q_chEneIIR[ch][band_idx], q_temp[ch] ) )
    2722             :             {
    2723     3405347 :                 hHeadTrackData->chEneIIR_fx[ch][band_idx] = L_add( L_shr( temp, sub( q_temp[ch], hHeadTrackData->q_chEneIIR[ch][band_idx] ) ), hHeadTrackData->chEneIIR_fx[ch][band_idx] ); // hHeadTrackData->q_chEneIIR[ch][band_idx]
    2724             :             }
    2725             :             ELSE
    2726             :             {
    2727       57853 :                 hHeadTrackData->chEneIIR_fx[ch][band_idx] = L_add( L_shr( hHeadTrackData->chEneIIR_fx[ch][band_idx], sub( hHeadTrackData->q_chEneIIR[ch][band_idx], q_temp[ch] ) ), temp ); // q_temp[ch]
    2728             :             }
    2729     3463200 :             move32();
    2730     3463200 :             hHeadTrackData->q_chEneIIR[ch][band_idx] = s_min( hHeadTrackData->q_chEneIIR[ch][band_idx], q_temp[ch] );
    2731     3463200 :             move16();
    2732             :         }
    2733             :         /* Determine ILD */
    2734             : 
    2735     1731600 :         IF( EQ_32( L_max( 1, hHeadTrackData->chEneIIR_fx[0][band_idx] ), L_max( 1, hHeadTrackData->chEneIIR_fx[1][band_idx] ) ) )
    2736             :         {
    2737        1943 :             ILD = 0;
    2738        1943 :             move32();
    2739             :         }
    2740             :         ELSE
    2741             :         {
    2742     1729657 :             temp_div = L_deposit_h( BASOP_Util_Divide3232_Scale( L_max( 1, hHeadTrackData->chEneIIR_fx[0][band_idx] ), L_max( 1, hHeadTrackData->chEneIIR_fx[1][band_idx] ), &e_div ) );
    2743     1729657 :             e_div = add( e_div, sub( hHeadTrackData->q_chEneIIR[1][band_idx], hHeadTrackData->q_chEneIIR[0][band_idx] ) );
    2744     1729657 :             temp = BASOP_Util_Log2( temp_div ); // Q25
    2745     1729657 :             IF( e_div > 0 )
    2746             :             {
    2747      846913 :                 temp = L_add( temp, L_shl( e_div, 25 ) ); // Q25
    2748             :             }
    2749             :             ELSE
    2750             :             {
    2751      882744 :                 temp = L_sub( temp, L_shl( L_abs( e_div ), 25 ) ); // Q25
    2752             :             }
    2753             : 
    2754     1729657 :             temp = Mpy_32_32( temp, 646462464 );       // logx base 10 = 0.30103* logx base 2//
    2755     1729657 :             ILD = L_abs( Mpy_32_16_1( temp, 20480 ) ); // Q21
    2756             :         }
    2757     1731600 :         IF( BASOP_Util_Cmp_Mant32Exp( hHeadTrackData->chEneIIR_fx[1][band_idx], sub( 31, hHeadTrackData->q_chEneIIR[1][band_idx] ), hHeadTrackData->chEneIIR_fx[0][band_idx], sub( 31, hHeadTrackData->q_chEneIIR[0][band_idx] ) ) > 0 )
    2758             :         {
    2759     1169699 :             louderCh = 1;
    2760             :         }
    2761             :         ELSE
    2762             :         {
    2763      561901 :             louderCh = 0;
    2764             :         }
    2765     1731600 :         move16();
    2766             : 
    2767             :         /* Determine ILD-based mono factor */
    2768     1731600 :         mono_factor_ILD = Mpy_32_16_1( L_sub( ILD, ONE_IN_Q21 ), 10911 ); // Q21
    2769             : 
    2770     1731600 :         mono_factor_ILD = L_max( 0, L_min( ONE_IN_Q21, mono_factor_ILD ) ); // Q21
    2771             : 
    2772     1731600 :         IF( EQ_32( mono_factor_ILD, ONE_IN_Q21 ) )
    2773             :         {
    2774      706563 :             mono_factor_ILD = ONE_IN_Q31;
    2775      706563 :             move32();
    2776             :         }
    2777             :         ELSE
    2778             :         {
    2779     1025037 :             mono_factor_ILD = L_shl( mono_factor_ILD, 10 ); // Q31
    2780             :         }
    2781             : 
    2782             :         /* Combine mono factors */
    2783     1731600 :         mono_factor = Mpy_32_32( mono_factor_ILD, mono_factor_rotation ); // Q31
    2784             : 
    2785             :         /* Mix original audio and sum signal according to determined mono factor */
    2786     5194800 :         FOR( ch = 0; ch < 2; ch++ )
    2787             :         {
    2788     3463200 :             IF( NE_16( ch, louderCh ) )
    2789             :             {
    2790             :                 Word32 band_nrg;
    2791     1731600 :                 Word64 W_band_nrg = 0;
    2792     1731600 :                 move64();
    2793             : 
    2794     8658000 :                 FOR( slot = 0; slot < nSlots; slot++ )
    2795             :                 {
    2796    20462400 :                     FOR( bin = bin_lo; bin < bin_hi; bin++ )
    2797             :                     {
    2798             :                         /* mono sum signal with the computed weight + rest from the original channel */
    2799    13536000 :                         inRe_fx[ch][slot][bin] = L_add( ( Mpy_32_32( mono_factor, L_add( inRe_fx[0][slot][bin], inRe_fx[1][slot][bin] ) ) ), ( Mpy_32_32( L_sub( ONE_IN_Q31, mono_factor ), inRe_fx[ch][slot][bin] ) ) );
    2800    13536000 :                         inIm_fx[ch][slot][bin] = L_add( ( Mpy_32_32( mono_factor, L_add( inIm_fx[0][slot][bin], inIm_fx[1][slot][bin] ) ) ), ( Mpy_32_32( L_sub( ONE_IN_Q31, mono_factor ), inIm_fx[ch][slot][bin] ) ) );
    2801    13536000 :                         move32();
    2802    13536000 :                         move32();
    2803    13536000 :                         re = L_shl( inRe_fx[ch][slot][bin], shift );  // q_inp +shift
    2804    13536000 :                         img = L_shl( inIm_fx[ch][slot][bin], shift ); // q_inp +shift
    2805             : 
    2806    13536000 :                         W_band_nrg = W_add( W_band_nrg, ( W_add( W_mult0_32_32( re, re ), W_mult0_32_32( img, img ) ) ) ); // 2(q_inp + shift)
    2807             :                     }
    2808             :                 }
    2809     1731600 :                 s = W_norm( W_band_nrg );
    2810     1731600 :                 band_nrg = W_extract_h( W_shl( W_band_nrg, s ) ); // Q: 2*(q_inp+shift) + s - 32
    2811     1731600 :                 q_band_nrg = sub( add( shl( add( q_inp, shift ), 1 ), s ), 32 );
    2812             : 
    2813     1731600 :                 hHeadTrackData->procChEneIIR_fx[ch][band_idx] = Mpy_32_16_1( hHeadTrackData->procChEneIIR_fx[ch][band_idx], ADAPT_HTPROTO_IIR_FAC_FX ); // hHeadTrackData->q_procChEneIIR[ch][band_idx]
    2814     1731600 :                 move32();
    2815             : 
    2816     1731600 :                 temp = Mpy_32_16_1( band_nrg, sub( 32767, ADAPT_HTPROTO_IIR_FAC_FX ) ); // q_band_nrg
    2817     1731600 :                 IF( LT_16( hHeadTrackData->q_procChEneIIR[ch][band_idx], q_band_nrg ) )
    2818             :                 {
    2819     1704621 :                     hHeadTrackData->procChEneIIR_fx[ch][band_idx] = L_add( L_shr( temp, sub( q_band_nrg, hHeadTrackData->q_procChEneIIR[ch][band_idx] ) ), hHeadTrackData->procChEneIIR_fx[ch][band_idx] ); // hHeadTrackData->q_procChEneIIR[ch][band_idx]
    2820             :                 }
    2821             :                 ELSE
    2822             :                 {
    2823       26979 :                     hHeadTrackData->procChEneIIR_fx[ch][band_idx] = L_add( L_shr( hHeadTrackData->procChEneIIR_fx[ch][band_idx], sub( hHeadTrackData->q_procChEneIIR[ch][band_idx], q_band_nrg ) ), temp ); // q_band_nrg
    2824             :                 }
    2825     1731600 :                 move32();
    2826     1731600 :                 hHeadTrackData->q_procChEneIIR[ch][band_idx] = s_min( hHeadTrackData->q_procChEneIIR[ch][band_idx], q_band_nrg );
    2827     1731600 :                 move16();
    2828             :             }
    2829             :             ELSE
    2830             :             {
    2831             :                 /* processed signal is input. use the original channel, so no need to compute new signals or signal energy */
    2832     1731600 :                 hHeadTrackData->procChEneIIR_fx[ch][band_idx] = Mpy_32_16_1( hHeadTrackData->procChEneIIR_fx[ch][band_idx], ADAPT_HTPROTO_IIR_FAC_FX ); // q_procChEneIIR
    2833     1731600 :                 move32();
    2834             : 
    2835     1731600 :                 temp = Mpy_32_16_1( ch_nrg[ch], sub( 32767, ADAPT_HTPROTO_IIR_FAC_FX ) );
    2836     1731600 :                 IF( LT_16( hHeadTrackData->q_procChEneIIR[ch][band_idx], q_temp[ch] ) )
    2837             :                 {
    2838     1699203 :                     hHeadTrackData->procChEneIIR_fx[ch][band_idx] = L_add( L_shr( temp, sub( q_temp[ch], hHeadTrackData->q_procChEneIIR[ch][band_idx] ) ), hHeadTrackData->procChEneIIR_fx[ch][band_idx] ); // hHeadTrackData->q_procChEneIIR[ch][band_idx]
    2839             :                 }
    2840             :                 ELSE
    2841             :                 {
    2842       32397 :                     hHeadTrackData->procChEneIIR_fx[ch][band_idx] = L_add( L_shr( hHeadTrackData->procChEneIIR_fx[ch][band_idx], sub( hHeadTrackData->q_procChEneIIR[ch][band_idx], q_temp[ch] ) ), temp ); // q_temp[ch]
    2843             :                 }
    2844     1731600 :                 move32();
    2845     1731600 :                 hHeadTrackData->q_procChEneIIR[ch][band_idx] = s_min( hHeadTrackData->q_procChEneIIR[ch][band_idx], q_temp[ch] );
    2846     1731600 :                 move16();
    2847             :             }
    2848             :         }
    2849             : 
    2850             :         /* Equalize */
    2851     1731600 :         ene_target = BASOP_Util_Add_Mant32Exp( hHeadTrackData->chEneIIR_fx[0][band_idx], sub( 31, hHeadTrackData->q_chEneIIR[0][band_idx] ), hHeadTrackData->chEneIIR_fx[1][band_idx], sub( 31, hHeadTrackData->q_chEneIIR[1][band_idx] ), &ene_target_e );
    2852             : 
    2853     1731600 :         ene_proc = BASOP_Util_Add_Mant32Exp( hHeadTrackData->procChEneIIR_fx[0][band_idx], sub( 31, hHeadTrackData->q_procChEneIIR[0][band_idx] ), hHeadTrackData->procChEneIIR_fx[1][band_idx], sub( 31, hHeadTrackData->q_procChEneIIR[1][band_idx] ), &ene_proc_e );
    2854             : 
    2855     1731600 :         temp_div = L_deposit_h( BASOP_Util_Divide3232_Scale( ene_target, L_max( 1, ene_proc ), &e_div ) );
    2856     1731600 :         e_div = add( e_div, sub( ene_target_e, ene_proc_e ) );
    2857             : 
    2858     1731600 :         eqVal = Sqrt32( temp_div, &e_div );
    2859             : 
    2860     1731600 :         Word16 comp_flag = BASOP_Util_Cmp_Mant32Exp( 1073741824, 3, eqVal, e_div );
    2861     1731600 :         IF( EQ_16( comp_flag, -1 ) )
    2862             :         {
    2863          35 :             eqVal = 1073741824; // 4inQ28
    2864          35 :             move32();
    2865             :         }
    2866             :         ELSE
    2867             :         {
    2868     1731565 :             eqVal = L_shl( eqVal, sub( e_div, 3 ) ); // Q28
    2869             :         }
    2870             : 
    2871     8658000 :         FOR( slot = 0; slot < nSlots; slot++ )
    2872             :         {
    2873    20779200 :             FOR( ch = 0; ch < 2; ch++ )
    2874             :             {
    2875    40924800 :                 FOR( bin = bin_lo; bin < bin_hi; bin++ )
    2876             :                 {
    2877    27072000 :                     Word16 temp_shift = s_min( norm_l( inRe_fx[ch][slot][bin] ), norm_l( inIm_fx[ch][slot][bin] ) );
    2878    27072000 :                     re = L_shl( inRe_fx[ch][slot][bin], temp_shift );
    2879    27072000 :                     img = L_shl( inIm_fx[ch][slot][bin], temp_shift );
    2880             : 
    2881    27072000 :                     re = L_shr( Mpy_32_32( re, eqVal ), sub( temp_shift, 3 ) );
    2882    27072000 :                     img = L_shr( Mpy_32_32( img, eqVal ), sub( temp_shift, 3 ) );
    2883    27072000 :                     inRe_fx[ch][slot][bin] = re;  // q_inp
    2884    27072000 :                     inIm_fx[ch][slot][bin] = img; // q_inp
    2885    27072000 :                     move32();
    2886    27072000 :                     move32();
    2887             :                 }
    2888             :             }
    2889             :         }
    2890             :     }
    2891             : 
    2892       74400 :     is_zero = 1;
    2893       74400 :     move16();
    2894       75600 :     FOR( i = 0; i < MASA_FREQUENCY_BANDS; i++ )
    2895             :     {
    2896       75550 :         test();
    2897       75550 :         if ( ( hHeadTrackData->chEneIIR_fx[0][i] != 0 ) || ( hHeadTrackData->chEneIIR_fx[1][i] != 0 ) )
    2898             :         {
    2899       74350 :             is_zero = 0;
    2900       74350 :             move16();
    2901       74350 :             BREAK;
    2902             :         }
    2903             :     }
    2904       74400 :     IF( is_zero )
    2905             :     {
    2906          50 :         set16_fx( hHeadTrackData->q_chEneIIR[0], 31, MASA_FREQUENCY_BANDS );
    2907          50 :         set16_fx( hHeadTrackData->q_chEneIIR[1], 31, MASA_FREQUENCY_BANDS );
    2908             :     }
    2909             : 
    2910       74400 :     is_zero = 1;
    2911       74400 :     move16();
    2912       75602 :     FOR( i = 0; i < MASA_FREQUENCY_BANDS; i++ )
    2913             :     {
    2914       75552 :         test();
    2915       75552 :         if ( ( hHeadTrackData->procChEneIIR_fx[0][i] != 0 ) || ( hHeadTrackData->procChEneIIR_fx[1][i] != 0 ) )
    2916             :         {
    2917       74350 :             is_zero = 0;
    2918       74350 :             move16();
    2919       74350 :             BREAK;
    2920             :         }
    2921             :     }
    2922       74400 :     IF( is_zero )
    2923             :     {
    2924          50 :         set16_fx( hHeadTrackData->q_procChEneIIR[0], 31, MASA_FREQUENCY_BANDS );
    2925          50 :         set16_fx( hHeadTrackData->q_procChEneIIR[1], 31, MASA_FREQUENCY_BANDS );
    2926             :     }
    2927             : 
    2928       74400 :     return;
    2929             : }
    2930             : 
    2931             : 
    2932       74400 : static void ivas_dirac_dec_binaural_check_and_switch_transports_headtracked_fx(
    2933             :     COMBINED_ORIENTATION_HANDLE hHeadTrackData,
    2934             :     Word32 inRe_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX],
    2935             :     Word32 inIm_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX],
    2936             :     const Word16 nBins,
    2937             :     const Word16 nSlots,
    2938             :     Word32 Rmat_fx[3][3] /*Q30*/ )
    2939             : {
    2940             :     Word16 slot, bin, ch;
    2941             :     Word32 tmpVal;
    2942       74400 :     Word16 norm, e_div, shift = 31;
    2943       74400 :     move16();
    2944             :     Word32 Re, Im, temp_div;
    2945             : 
    2946             :     /* When not currently in prototype signal left-right switching procedure, check if such switching is needed */
    2947       74400 :     IF( EQ_16( hHeadTrackData->lrSwitchedNext, hHeadTrackData->lrSwitchedCurrent ) )
    2948             :     {
    2949       67508 :         Word32 thresholdDotProduct = 182536112; // 0.17 in Q30//       /* Corresponds to 10-degree switching threshold */
    2950       67508 :         move32();
    2951       67508 :         test();
    2952       67508 :         if ( hHeadTrackData->lrSwitchedCurrent == 0 && ( LT_32( Rmat_fx[1][1], L_negate( thresholdDotProduct ) ) ) )
    2953             :         {
    2954          38 :             hHeadTrackData->lrSwitchedNext = 1;
    2955          38 :             move16();
    2956             :         }
    2957       67508 :         test();
    2958       67508 :         if ( EQ_16( hHeadTrackData->lrSwitchedCurrent, 1 ) && ( GT_32( Rmat_fx[1][1], thresholdDotProduct ) ) )
    2959             :         {
    2960          32 :             hHeadTrackData->lrSwitchedNext = 0;
    2961          32 :             move16();
    2962             :         }
    2963             :     }
    2964             : 
    2965      223200 :     FOR( Word16 i = 0; i < 2; i++ )
    2966             :     {
    2967      744000 :         FOR( Word16 j = 0; j < nSlots; j++ )
    2968             :         {
    2969      595200 :             norm = s_min( L_norm_arr( inRe_fx[i][j], nBins ), L_norm_arr( inIm_fx[i][j], nBins ) );
    2970      595200 :             shift = s_min( norm, shift );
    2971             :         }
    2972             :     }
    2973             : 
    2974       74400 :     shift = sub( shift, 3 ); // guard bits//
    2975             :                              /* When currently in interpolation */
    2976       74400 :     IF( NE_16( hHeadTrackData->lrSwitchedNext, hHeadTrackData->lrSwitchedCurrent ) )
    2977             :     {
    2978       34810 :         FOR( slot = 0; slot < nSlots; slot++ )
    2979             :         {
    2980             :             Word32 switchOrderFactor, origOrderFactor;
    2981             :             Word16 e_switchOrderFactor, e_origOrderFactor;
    2982             : 
    2983       27848 :             hHeadTrackData->lrSwitchInterpVal_fx = L_add( hHeadTrackData->lrSwitchInterpVal_fx, 2684354 /* 0.0025f in Q30 */ ); /* Corresponds to 0.5 seconds interpolation time */ /* Q30 */
    2984       27848 :             move32();
    2985             : 
    2986       27848 :             IF( GT_32( hHeadTrackData->lrSwitchInterpVal_fx, 1072668096 /* 0.999f in Q30 */ ) )
    2987             :             {
    2988             :                 /* Stop interpolation, reset values */
    2989          68 :                 hHeadTrackData->lrSwitchInterpVal_fx = 0;
    2990          68 :                 hHeadTrackData->lrSwitchedCurrent = hHeadTrackData->lrSwitchedNext;
    2991          68 :                 move32();
    2992          68 :                 move16();
    2993             :             }
    2994             : 
    2995             :             /* Gains for determining portion of switched channel order and original channel order */
    2996       27848 :             tmpVal = Mpy_32_16_1( hHeadTrackData->lrSwitchInterpVal_fx, (Word16) hHeadTrackData->lrSwitchedNext );                                          /* Q15 */
    2997       27848 :             tmpVal = L_add( tmpVal, Mpy_32_16_1( L_sub( ONE_IN_Q30, hHeadTrackData->lrSwitchInterpVal_fx ), (Word16) hHeadTrackData->lrSwitchedCurrent ) ); /* Q15 */
    2998             : 
    2999       27848 :             e_switchOrderFactor = 0;
    3000       27848 :             e_origOrderFactor = 0;
    3001       27848 :             move16();
    3002       27848 :             move16();
    3003       27848 :             IF( EQ_32( tmpVal, 32768 ) )
    3004             :             {
    3005          38 :                 tmpVal = ONE_IN_Q31;
    3006          38 :                 move32();
    3007             :             }
    3008             :             ELSE
    3009       27810 :                 tmpVal = L_shl( tmpVal, 16 ); // Q31
    3010       27848 :             switchOrderFactor = Sqrt32( tmpVal, &e_switchOrderFactor );
    3011       27848 :             switchOrderFactor = L_shl( switchOrderFactor, e_switchOrderFactor );         // Q31
    3012       27848 :             origOrderFactor = Sqrt32( L_sub( ONE_IN_Q31, tmpVal ), &e_origOrderFactor ); // Q31
    3013       27848 :             origOrderFactor = L_shl( origOrderFactor, e_origOrderFactor );
    3014     1298728 :             FOR( bin = 0; bin < nBins; bin++ )
    3015             :             {
    3016             :                 /* determine original order (1) signals and switched order (2) signals */
    3017             :                 Word32 re1[BINAURAL_CHANNELS], re2[BINAURAL_CHANNELS], im1[BINAURAL_CHANNELS], im2[BINAURAL_CHANNELS];
    3018             : 
    3019     3812640 :                 FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
    3020             :                 {
    3021     2541760 :                     re1[ch] = Mpy_32_32( inRe_fx[ch][slot][bin], origOrderFactor );       // q_inp
    3022     2541760 :                     re2[ch] = Mpy_32_32( inRe_fx[1 - ch][slot][bin], switchOrderFactor ); // q_inp
    3023     2541760 :                     im1[ch] = Mpy_32_32( inIm_fx[ch][slot][bin], origOrderFactor );       // q_inp
    3024     2541760 :                     im2[ch] = Mpy_32_32( inIm_fx[1 - ch][slot][bin], switchOrderFactor ); // q_inp
    3025     2541760 :                     move32();
    3026     2541760 :                     move32();
    3027     2541760 :                     move32();
    3028     2541760 :                     move32();
    3029             :                 }
    3030             : 
    3031     3812640 :                 FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
    3032             :                 {
    3033             :                     Word32 eneRef, ene, eq;
    3034             : 
    3035     2541760 :                     re1[ch] = L_shl( re1[ch], shift ); // q_inp+shift//
    3036     2541760 :                     re2[ch] = L_shl( re2[ch], shift ); // q_inp+shift//
    3037     2541760 :                     im1[ch] = L_shl( im1[ch], shift ); // q_inp+shift//
    3038     2541760 :                     im2[ch] = L_shl( im2[ch], shift ); // q_inp+shift//
    3039     2541760 :                     move32();
    3040     2541760 :                     move32();
    3041     2541760 :                     move32();
    3042     2541760 :                     move32();
    3043             : 
    3044             :                     /* Interpolate / mix original and switched order signals */
    3045     2541760 :                     Re = L_add( re1[ch], re2[ch] ); // q_inp+shift//
    3046     2541760 :                     Im = L_add( im1[ch], im2[ch] ); // q_inp+shift//
    3047             : 
    3048             :                     /* Equalize interpolated signals to preserve energy per bin */
    3049             : 
    3050     2541760 :                     eneRef = L_add( ( L_add( Mpy_32_32( re1[ch], re1[ch] ), Mpy_32_32( re2[ch], re2[ch] ) ) ), ( L_add( Mpy_32_32( im1[ch], im1[ch] ), Mpy_32_32( im2[ch], im2[ch] ) ) ) ); // 2*(q_inp+shift) -31//
    3051     2541760 :                     ene = L_add( Mpy_32_32( Re, Re ), Mpy_32_32( Im, Im ) );                                                                                                                // 2*(q_inp+shift) -31//
    3052             : 
    3053     2541760 :                     temp_div = L_deposit_h( BASOP_Util_Divide3232_Scale( eneRef, L_max( 1, ene ), &e_div ) );
    3054             : 
    3055     2541760 :                     eq = Sqrt32( temp_div, &e_div );
    3056             : 
    3057     2541760 :                     Word16 comp_flag = BASOP_Util_Cmp_Mant32Exp( 1073741824, 3, eq, e_div );
    3058     2541760 :                     IF( EQ_16( comp_flag, -1 ) )
    3059             :                     {
    3060       16444 :                         eq = 1073741824; // 4inQ28
    3061       16444 :                         move32();
    3062             :                     }
    3063             :                     ELSE
    3064             :                     {
    3065     2525316 :                         eq = L_shl( eq, sub( e_div, 3 ) ); // Q28
    3066             :                     }
    3067             : 
    3068     2541760 :                     Re = L_shr( Mpy_32_32( Re, eq ), sub( shift, 3 ) ); // q_inp
    3069     2541760 :                     Im = L_shr( Mpy_32_32( Im, eq ), sub( shift, 3 ) ); // q_inp
    3070             : 
    3071     2541760 :                     inRe_fx[ch][slot][bin] = Re;
    3072     2541760 :                     inIm_fx[ch][slot][bin] = Im;
    3073     2541760 :                     move32();
    3074     2541760 :                     move32();
    3075             :                 }
    3076             :             }
    3077             :         }
    3078             :     }
    3079             :     ELSE
    3080             :     {
    3081             :         /* If not in interpolation, but in switched prototype situation, then switch left and right channels */
    3082       67438 :         IF( EQ_16( hHeadTrackData->lrSwitchedCurrent, 1 ) )
    3083             :         {
    3084       37425 :             FOR( slot = 0; slot < nSlots; slot++ )
    3085             :             {
    3086     1333140 :                 FOR( bin = 0; bin < nBins; bin++ )
    3087             :                 {
    3088     1303200 :                     tmpVal = inRe_fx[0][slot][bin];
    3089     1303200 :                     inRe_fx[0][slot][bin] = inRe_fx[1][slot][bin];
    3090     1303200 :                     inRe_fx[1][slot][bin] = tmpVal;
    3091     1303200 :                     tmpVal = inIm_fx[0][slot][bin];
    3092     1303200 :                     inIm_fx[0][slot][bin] = inIm_fx[1][slot][bin];
    3093     1303200 :                     inIm_fx[1][slot][bin] = tmpVal;
    3094     1303200 :                     move32();
    3095     1303200 :                     move32();
    3096     1303200 :                     move32();
    3097     1303200 :                     move32();
    3098             :                 }
    3099             :             }
    3100             :         }
    3101             :     }
    3102             : 
    3103       74400 :     return;
    3104             : }
    3105             : 
    3106             : 
    3107    41517570 : static void eig2x2_fx(
    3108             :     const Word32 E1_fx, /*q_E*/
    3109             :     const Word32 E2_fx, /*q_E*/
    3110             :     Word16 q_E,
    3111             :     const Word32 Cre_fx, /*q_C*/
    3112             :     const Word32 Cim_fx, /*q_C*/
    3113             :     Word16 q_C,
    3114             :     Word32 Ure_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_U*/
    3115             :     Word32 Uim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_U*/
    3116             :     Word16 *q_U,
    3117             :     Word32 D_fx[BINAURAL_CHANNELS], /*q_D*/
    3118             :     Word16 *q_D )
    3119             : {
    3120             :     Word16 chA, chB, ch;
    3121             :     Word32 s_fx, normVal_fx, crossSquare_fx, a_fx, pm_fx, add_fx;
    3122             :     Word32 tmp1, tmp2, tmp3, e1, e2, c_re, c_im;
    3123             :     Word16 q_crossSquare, q_tmp1, q_tmp2, exp_tmp3, exp, q_e, q_c, q_U_1, q_U_2;
    3124    41517570 :     Word32 epsilon_mant = 1180591621;
    3125    41517570 :     Word16 epsilon_exp = -39;
    3126    41517570 :     move32();
    3127    41517570 :     move16();
    3128             : 
    3129    41517570 :     pm_fx = 0;
    3130    41517570 :     move32();
    3131    41517570 :     add_fx = 0;
    3132    41517570 :     move32();
    3133    41517570 :     q_tmp2 = 0;
    3134    41517570 :     move16();
    3135             : 
    3136   124552710 :     FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ )
    3137             :     {
    3138   249105420 :         FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ )
    3139             :         {
    3140   166070280 :             Ure_fx[chA][chB] = 0;
    3141   166070280 :             move32();
    3142   166070280 :             Uim_fx[chA][chB] = 0;
    3143   166070280 :             move32();
    3144             :         }
    3145             :     }
    3146             : 
    3147    41517570 :     exp = sub( get_min_scalefactor( Cre_fx, Cim_fx ), 2 );
    3148    41517570 :     c_re = L_shl( Cre_fx, exp );
    3149    41517570 :     c_im = L_shl( Cim_fx, exp );
    3150    41517570 :     q_c = add( q_C, exp );
    3151             : 
    3152    41517570 :     exp = sub( get_min_scalefactor( E1_fx, E2_fx ), 2 );
    3153    41517570 :     e1 = L_shl( E1_fx, exp );
    3154    41517570 :     e2 = L_shl( E2_fx, exp );
    3155    41517570 :     q_e = add( q_E, exp );
    3156             : 
    3157             :     /*crossSquare_fx = (c_re * c_re) + (c_im * c_im)
    3158             :     a_fx = (e1 + e2) * (e1 + e2) - 4.0f * ((e1 * e2) - crossSquare_fx) = (e1 - e2)^2 + 4 * crossSquare_fx
    3159             :     pm_fx = 0.5f * sqrtf(max(0.0f, a_fx))
    3160             :     add_fx = 0.5f * (e1 + e2)*/
    3161             : 
    3162    41517570 :     IF( L_and( c_re == 0, c_im == 0 ) )
    3163             :     {
    3164             :         /* if c_re = 0 and c_im = 0, then crossSquare_fx = (c_re * c_re) + (c_im * c_im) = 0
    3165             :         a_fx = (E1 - E2)^2
    3166             :         pm_fx = 0.5 * sqrt(max(0, a_fx)) = 0.5 * max(0, (e1 - e2)) */
    3167    11426432 :         crossSquare_fx = 0;
    3168    11426432 :         move32();
    3169    11426432 :         q_crossSquare = Q31;
    3170    11426432 :         move16();
    3171    11426432 :         pm_fx = L_shr( L_max( 0, L_abs( L_sub( e1, e2 ) ) ), 1 );
    3172    11426432 :         q_tmp2 = q_e;
    3173    11426432 :         move16();
    3174             :     }
    3175             :     ELSE
    3176             :     {
    3177    30091138 :         crossSquare_fx = Madd_32_32( Mpy_32_32( c_re, c_re ), c_im, c_im );
    3178    30091138 :         q_crossSquare = sub( add( q_c, q_c ), 31 );
    3179    30091138 :         IF( EQ_32( e1, e2 ) )
    3180             :         {
    3181             :             /* if e1 - e2 = 0, then a_fx = 4 * crossSquare_fx
    3182             :             pm_fx = 0.5 * sqrt(max(0, 4 * crossSquare_fx)) =  sqrt(0, crossSquare_fx)*/
    3183     4183256 :             test();
    3184     4183256 :             test();
    3185     4183256 :             IF( EQ_32( c_re, 0 ) || LT_32( L_abs( c_re ), ONE_IN_Q15 ) )
    3186             :             {
    3187             :                 /* if c_re = 0, then crossSquare_fx = c_im^2 => pm_fx = max(0, c_im) */
    3188       11846 :                 pm_fx = L_max( 0, L_abs( c_im ) );
    3189       11846 :                 q_tmp2 = q_c;
    3190       11846 :                 move16();
    3191             :             }
    3192     4171410 :             ELSE IF( c_im == 0 || LT_32( L_abs( c_im ), ONE_IN_Q15 ) )
    3193             :             {
    3194             :                 /* if c_im = 0, then crossSquare_fx = c_re^2 => pm_fx = max(0, c_re) */
    3195     4130193 :                 pm_fx = L_max( 0, L_abs( c_re ) );
    3196     4130193 :                 q_tmp2 = q_c;
    3197     4130193 :                 move16();
    3198             :             }
    3199             :             ELSE
    3200             :             {
    3201       41217 :                 exp = sub( 31, q_crossSquare );
    3202       41217 :                 pm_fx = Sqrt32( L_max( 0, crossSquare_fx ), &exp );
    3203       41217 :                 q_tmp2 = sub( 31, exp );
    3204             :             }
    3205             :         }
    3206             :         ELSE
    3207             :         {
    3208             :             /* if e1, e2 >> c_re, c_im then (e1 - e2)^2 ~ (e1 - e2)^2 + 4 * crossSquare_fx
    3209             :                a_fx = (E1 - E2)^2
    3210             :                pm_fx = 0.5 * sqrt(max(0, a_fx)) = 0.5 * max(0, (e1 - e2)) */
    3211             : 
    3212    25907882 :             IF( GT_16( sub( q_c, q_e ), Q15 ) )
    3213             :             {
    3214       22147 :                 pm_fx = L_shr( L_max( 0, L_abs( L_sub( e1, e2 ) ) ), 1 );
    3215       22147 :                 q_tmp2 = q_e;
    3216       22147 :                 move16();
    3217             :             }
    3218             :             ELSE
    3219             :             {
    3220    25885735 :                 tmp2 = crossSquare_fx;
    3221    25885735 :                 move32();
    3222    25885735 :                 q_tmp2 = sub( q_crossSquare, 2 ); // crossSquare_fx = 4 * crossSquare_fx;
    3223             : 
    3224    25885735 :                 tmp1 = Mpy_32_32( L_sub( e1, e2 ), L_sub( e1, e2 ) );
    3225    25885735 :                 q_tmp1 = sub( add( q_e, q_e ), 31 );
    3226             : 
    3227    25885735 :                 a_fx = BASOP_Util_Add_Mant32Exp( tmp1, sub( 31, q_tmp1 ), tmp2, sub( 31, q_tmp2 ), &q_tmp2 ); // (E1 - E2)^2 + 4 * crossSquare_fx
    3228    25885735 :                 q_tmp2 = sub( 31, q_tmp2 );
    3229             : 
    3230    25885735 :                 exp = sub( 31, q_tmp2 );
    3231    25885735 :                 pm_fx = Sqrt32( L_max( 0, L_sub( a_fx, 1 ) ), &exp );
    3232    25885735 :                 pm_fx = L_shr( pm_fx, 1 );
    3233    25885735 :                 q_tmp2 = sub( 31, exp );
    3234             :             }
    3235             :         }
    3236             :     }
    3237             :     // add_fx = 0.5 * (e1 + e2)
    3238    41517570 :     add_fx = L_shr( L_add( e1, e2 ), 1 );
    3239    41517570 :     q_tmp1 = q_e;
    3240    41517570 :     move16();
    3241             : 
    3242    41517570 :     IF( LT_16( q_tmp1, q_tmp2 ) )
    3243             :     {
    3244    25994300 :         D_fx[0] = L_add( L_shr( add_fx, 1 ), L_shr( pm_fx, add( sub( q_tmp2, q_tmp1 ), 1 ) ) );
    3245    25994300 :         move32();
    3246    25994300 :         D_fx[1] = L_max( 0, L_sub( L_shr( add_fx, 1 ), L_shr( pm_fx, add( sub( q_tmp2, q_tmp1 ), 1 ) ) ) );
    3247    25994300 :         move32();
    3248    25994300 :         *q_D = sub( q_tmp1, 1 );
    3249    25994300 :         move16();
    3250             :     }
    3251             :     ELSE
    3252             :     {
    3253    15523270 :         D_fx[0] = L_add( L_shr( add_fx, add( sub( q_tmp1, q_tmp2 ), 1 ) ), L_shr( pm_fx, 1 ) );
    3254    15523270 :         move32();
    3255    15523270 :         D_fx[1] = L_max( 0, L_sub( L_shr( add_fx, add( sub( q_tmp1, q_tmp2 ), 1 ) ), L_shr( pm_fx, 1 ) ) );
    3256    15523270 :         move32();
    3257    15523270 :         *q_D = sub( q_tmp2, 1 );
    3258    15523270 :         move16();
    3259             :     }
    3260             : 
    3261             :     /* Numeric case, when input is practically zeros */
    3262             :     // IF( D_fx[0] < EPSILON_FX )
    3263             : 
    3264    41517570 :     IF( LT_32( L_shl_sat( D_fx[0], sub( sub( 31, *q_D ), EPSILON_EXP ) ), EPSILON_MANT ) )
    3265             :     {
    3266      228647 :         Ure_fx[0][0] = ONE_IN_Q31;
    3267      228647 :         move32();
    3268      228647 :         Ure_fx[1][1] = ONE_IN_Q31;
    3269      228647 :         move32();
    3270      228647 :         *q_U = Q31;
    3271      228647 :         move16();
    3272             : 
    3273      228647 :         return;
    3274             :     }
    3275             : 
    3276             :     /* Numeric case, when input is near an identity matrix with a gain */
    3277    41288923 :     tmp1 = Mpy_32_32( 2147484, add_fx ); // 2147484 = 1e-3f in Q31
    3278             : 
    3279    41288923 :     IF( LT_16( q_tmp1, q_tmp2 ) )
    3280             :     {
    3281    25909086 :         IF( LT_32( L_shr( pm_fx, sub( q_tmp2, q_tmp1 ) ), tmp1 ) )
    3282             :         {
    3283           3 :             Ure_fx[0][0] = ONE_IN_Q30;
    3284           3 :             move32();
    3285           3 :             Ure_fx[1][1] = ONE_IN_Q30;
    3286           3 :             move32();
    3287           3 :             *q_U = Q30;
    3288           3 :             move16();
    3289             : 
    3290           3 :             return;
    3291             :         }
    3292             :     }
    3293             :     ELSE
    3294             :     {
    3295    15379837 :         IF( LT_32( pm_fx, L_shr( tmp1, sub( q_tmp1, q_tmp2 ) ) ) )
    3296             :         {
    3297     3936793 :             Ure_fx[0][0] = ONE_IN_Q30;
    3298     3936793 :             move32();
    3299     3936793 :             Ure_fx[1][1] = ONE_IN_Q30;
    3300     3936793 :             move32();
    3301     3936793 :             *q_U = Q30;
    3302     3936793 :             move16();
    3303             : 
    3304     3936793 :             return;
    3305             :         }
    3306             :     }
    3307             : 
    3308    37352127 :     q_U_1 = 0;
    3309    37352127 :     q_U_2 = 0;
    3310    37352127 :     move16();
    3311    37352127 :     move16();
    3312             : 
    3313             : #ifdef OPT_SBA_REND_V1_BE
    3314             :     /* Eigenvectors */
    3315   112056381 :     FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
    3316             :     {
    3317    74704254 :         Word16 q_diff = sub( q_e, *q_D );
    3318    74704254 :         IF( q_diff > 0 )
    3319             :         {
    3320    74704254 :             tmp1 = L_sub( D_fx[ch], L_shr( e1, q_diff ) );
    3321    74704254 :             tmp2 = L_sub( D_fx[ch], L_shr( e2, q_diff ) );
    3322    74704254 :             q_tmp1 = *q_D;
    3323    74704254 :             move16();
    3324             :         }
    3325             :         ELSE
    3326             :         {
    3327           0 :             tmp1 = L_sub( L_shl( D_fx[ch], q_diff ), e1 );
    3328           0 :             tmp2 = L_sub( L_shl( D_fx[ch], q_diff ), e2 );
    3329           0 :             q_tmp1 = q_e;
    3330           0 :             move16();
    3331             :         }
    3332             : 
    3333    74704254 :         IF( GT_32( L_abs( tmp2 ), L_abs( tmp1 ) ) )
    3334             :         {
    3335    33251789 :             s_fx = tmp2;
    3336    33251789 :             move32();
    3337    33251789 :             exp = sub( norm_l( s_fx ), 1 );
    3338    33251789 :             tmp2 = Mpy_32_32( s_fx, s_fx );
    3339    33251789 :             q_tmp2 = sub( add( q_tmp1, q_tmp1 ), 31 );
    3340             : 
    3341    33251789 :             tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &q_tmp2 );
    3342    33251789 :             q_tmp2 = sub( 31, q_tmp2 );
    3343             : 
    3344    33251789 :             tmp3 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), epsilon_mant, epsilon_exp, &exp_tmp3 );
    3345             : 
    3346    33251789 :             tmp2 = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q30, tmp3, &exp );
    3347    33251789 :             exp = sub( exp, sub( Q30, sub( 31, exp_tmp3 ) ) );
    3348    33251789 :             normVal_fx = Sqrt32( tmp2, &exp ); // q_tmp2
    3349    33251789 :             q_tmp2 = sub( 31, exp );
    3350             : 
    3351    33251789 :             q_diff = sub( q_c, q_tmp1 );
    3352    33251789 :             IF( q_diff > 0 )
    3353             :             {
    3354    15816184 :                 c_re = L_shr( c_re, q_diff );
    3355    15816184 :                 c_im = L_shr( c_im, q_diff );
    3356    15816184 :                 q_c = q_tmp1;
    3357    15816184 :                 move16();
    3358             :             }
    3359             :             ELSE
    3360             :             {
    3361    17435605 :                 s_fx = L_shl( s_fx, q_diff );
    3362    17435605 :                 q_tmp1 = q_c;
    3363    17435605 :                 move16();
    3364             :             }
    3365             : 
    3366    33251789 :             Ure_fx[0][ch] = Mpy_32_32( s_fx, normVal_fx );
    3367    33251789 :             move32();
    3368    33251789 :             Ure_fx[1][ch] = Mpy_32_32( c_re, normVal_fx );
    3369    33251789 :             move32();
    3370    33251789 :             Uim_fx[1][ch] = Mpy_32_32( c_im, normVal_fx );
    3371    33251789 :             move32();
    3372    33251789 :             q_U_1 = sub( add( q_tmp1, q_tmp2 ), 31 );
    3373             : 
    3374    33251789 :             IF( q_U_2 != 0 )
    3375             :             {
    3376    13354278 :                 q_diff = sub( q_U_2, q_U_1 );
    3377    13354278 :                 IF( q_diff > 0 )
    3378             :                 {
    3379          24 :                     Ure_fx[1][ch - 1] = L_shr( Ure_fx[1][ch - 1], q_diff );
    3380          24 :                     Ure_fx[0][ch - 1] = L_shr( Ure_fx[0][ch - 1], q_diff );
    3381          24 :                     Uim_fx[0][ch - 1] = L_shr( Uim_fx[0][ch - 1], q_diff );
    3382          24 :                     q_U_2 = q_U_1;
    3383          24 :                     move32();
    3384          24 :                     move32();
    3385          24 :                     move32();
    3386          24 :                     move16();
    3387             :                 }
    3388    13354254 :                 ELSE IF( GT_16( q_U_1, q_U_2 ) )
    3389             :                 {
    3390           0 :                     Ure_fx[1][ch] = L_shl( Ure_fx[1][ch], q_diff );
    3391           0 :                     Ure_fx[0][ch] = L_shl( Ure_fx[0][ch], q_diff );
    3392           0 :                     Uim_fx[1][ch] = L_shl( Uim_fx[1][ch], q_diff );
    3393           0 :                     q_U_1 = q_U_2;
    3394           0 :                     move32();
    3395           0 :                     move32();
    3396           0 :                     move32();
    3397           0 :                     move16();
    3398             :                 }
    3399             :             }
    3400    33251789 :             q_U_2 = q_U_1;
    3401    33251789 :             move16();
    3402             :         }
    3403             :         ELSE
    3404             :         {
    3405    41452465 :             s_fx = tmp1;
    3406    41452465 :             move32();
    3407             : 
    3408    41452465 :             exp = sub( norm_l( s_fx ), 1 );
    3409    41452465 :             tmp2 = Mpy_32_32( s_fx, s_fx );
    3410    41452465 :             q_tmp2 = sub( add( q_tmp1, q_tmp1 ), 31 );
    3411             : 
    3412    41452465 :             tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &q_tmp2 );
    3413    41452465 :             q_tmp2 = sub( 31, q_tmp2 );
    3414             : 
    3415    41452465 :             tmp3 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), epsilon_mant, epsilon_exp, &exp_tmp3 );
    3416             : 
    3417    41452465 :             tmp2 = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q30, tmp3, &exp );
    3418    41452465 :             exp = sub( exp, sub( Q30, sub( 31, exp_tmp3 ) ) );
    3419    41452465 :             normVal_fx = Sqrt32( tmp2, &exp ); // q_tmp2
    3420    41452465 :             q_tmp2 = sub( 31, exp );
    3421             : 
    3422    41452465 :             q_diff = sub( q_c, q_tmp1 );
    3423    41452465 :             IF( q_diff > 0 )
    3424             :             {
    3425    17450461 :                 c_re = L_shr( c_re, q_diff );
    3426    17450461 :                 c_im = L_shr( c_im, q_diff );
    3427    17450461 :                 q_c = q_tmp1;
    3428    17450461 :                 move16();
    3429             :             }
    3430             :             ELSE
    3431             :             {
    3432    24002004 :                 s_fx = L_shl( s_fx, q_diff );
    3433    24002004 :                 q_tmp1 = q_c;
    3434    24002004 :                 move16();
    3435             :             }
    3436             : 
    3437    41452465 :             Ure_fx[1][ch] = Mpy_32_32( s_fx, normVal_fx );
    3438    41452465 :             move32();
    3439    41452465 :             Ure_fx[0][ch] = Mpy_32_32( c_re, normVal_fx );
    3440    41452465 :             move32();
    3441    41452465 :             Uim_fx[0][ch] = Mpy_32_32( L_negate( c_im ), normVal_fx );
    3442    41452465 :             move32();
    3443    41452465 :             q_U_2 = sub( add( q_tmp1, q_tmp2 ), 31 );
    3444             : 
    3445    41452465 :             IF( q_U_1 != 0 )
    3446             :             {
    3447    23997849 :                 q_diff = sub( q_U_2, q_U_1 );
    3448    23997849 :                 IF( q_diff > 0 )
    3449             :                 {
    3450           0 :                     Ure_fx[1][ch] = L_shr( Ure_fx[1][ch], q_diff );
    3451           0 :                     Ure_fx[0][ch] = L_shr( Ure_fx[0][ch], q_diff );
    3452           0 :                     Uim_fx[0][ch] = L_shr( Uim_fx[0][ch], q_diff );
    3453           0 :                     q_U_2 = q_U_1;
    3454           0 :                     move32();
    3455           0 :                     move32();
    3456           0 :                     move32();
    3457           0 :                     move16();
    3458             :                 }
    3459    23997849 :                 ELSE IF( GT_16( q_U_1, q_U_2 ) )
    3460             :                 {
    3461         162 :                     Ure_fx[1][ch - 1] = L_shl( Ure_fx[1][ch - 1], q_diff );
    3462         162 :                     Ure_fx[0][ch - 1] = L_shl( Ure_fx[0][ch - 1], q_diff );
    3463         162 :                     Uim_fx[1][ch - 1] = L_shl( Uim_fx[1][ch - 1], q_diff );
    3464         162 :                     q_U_1 = q_U_2;
    3465         162 :                     move32();
    3466         162 :                     move32();
    3467         162 :                     move32();
    3468         162 :                     move16();
    3469             :                 }
    3470             :             }
    3471    41452465 :             q_U_1 = q_U_2;
    3472    41452465 :             move16();
    3473             :         }
    3474             :     }
    3475             : #else  /* OPT_SBA_REND_V1_BE */
    3476             :     /* Eigenvectors */
    3477             :     FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
    3478             :     {
    3479             :         IF( LT_16( *q_D, q_e ) )
    3480             :         {
    3481             :             tmp1 = L_sub( D_fx[ch], L_shr( e1, sub( q_e, *q_D ) ) );
    3482             :             tmp2 = L_sub( D_fx[ch], L_shr( e2, sub( q_e, *q_D ) ) );
    3483             :             q_tmp1 = *q_D;
    3484             :             move16();
    3485             :         }
    3486             :         ELSE
    3487             :         {
    3488             :             tmp1 = L_sub( L_shr( D_fx[ch], sub( *q_D, q_e ) ), e1 );
    3489             :             tmp2 = L_sub( L_shr( D_fx[ch], sub( *q_D, q_e ) ), e2 );
    3490             :             q_tmp1 = q_e;
    3491             :             move16();
    3492             :         }
    3493             : 
    3494             :         IF( GT_32( L_abs( tmp2 ), L_abs( tmp1 ) ) )
    3495             :         {
    3496             :             s_fx = tmp2;
    3497             :             move32();
    3498             :             exp = sub( norm_l( s_fx ), 1 );
    3499             :             tmp2 = Mpy_32_32( s_fx, s_fx );
    3500             :             q_tmp2 = sub( add( q_tmp1, q_tmp1 ), 31 );
    3501             : 
    3502             :             tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &q_tmp2 );
    3503             :             q_tmp2 = sub( 31, q_tmp2 );
    3504             : 
    3505             :             tmp3 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), epsilon_mant, epsilon_exp, &exp_tmp3 );
    3506             : 
    3507             :             tmp2 = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q30, tmp3, &exp );
    3508             :             exp = sub( exp, sub( Q30, sub( 31, exp_tmp3 ) ) );
    3509             :             normVal_fx = Sqrt32( tmp2, &exp ); // q_tmp2
    3510             :             q_tmp2 = sub( 31, exp );
    3511             : 
    3512             :             IF( LT_16( q_tmp1, q_c ) )
    3513             :             {
    3514             :                 c_re = L_shr( c_re, sub( q_c, q_tmp1 ) );
    3515             :                 c_im = L_shr( c_im, sub( q_c, q_tmp1 ) );
    3516             :                 q_c = q_tmp1;
    3517             :                 move16();
    3518             :             }
    3519             :             ELSE
    3520             :             {
    3521             :                 s_fx = L_shr( s_fx, sub( q_tmp1, q_c ) );
    3522             :                 q_tmp1 = q_c;
    3523             :                 move16();
    3524             :             }
    3525             : 
    3526             :             Ure_fx[0][ch] = Mpy_32_32( s_fx, normVal_fx );
    3527             :             move32();
    3528             :             Ure_fx[1][ch] = Mpy_32_32( c_re, normVal_fx );
    3529             :             move32();
    3530             :             Uim_fx[1][ch] = Mpy_32_32( c_im, normVal_fx );
    3531             :             move32();
    3532             :             q_U_1 = sub( add( q_tmp1, q_tmp2 ), 31 );
    3533             : 
    3534             :             IF( q_U_2 != 0 )
    3535             :             {
    3536             :                 IF( LT_16( q_U_1, q_U_2 ) )
    3537             :                 {
    3538             :                     Ure_fx[1][ch - 1] = L_shr( Ure_fx[1][ch - 1], sub( q_U_2, q_U_1 ) );
    3539             :                     Ure_fx[0][ch - 1] = L_shr( Ure_fx[0][ch - 1], sub( q_U_2, q_U_1 ) );
    3540             :                     Uim_fx[0][ch - 1] = L_shr( Uim_fx[0][ch - 1], sub( q_U_2, q_U_1 ) );
    3541             :                     q_U_2 = q_U_1;
    3542             :                     move32();
    3543             :                     move32();
    3544             :                     move32();
    3545             :                     move16();
    3546             :                 }
    3547             :                 ELSE IF( GT_16( q_U_1, q_U_2 ) )
    3548             :                 {
    3549             :                     Ure_fx[1][ch] = L_shr( Ure_fx[1][ch], sub( q_U_1, q_U_2 ) );
    3550             :                     Ure_fx[0][ch] = L_shr( Ure_fx[0][ch], sub( q_U_1, q_U_2 ) );
    3551             :                     Uim_fx[1][ch] = L_shr( Uim_fx[1][ch], sub( q_U_1, q_U_2 ) );
    3552             :                     q_U_1 = q_U_2;
    3553             :                     move32();
    3554             :                     move32();
    3555             :                     move32();
    3556             :                     move16();
    3557             :                 }
    3558             :             }
    3559             :             q_U_2 = q_U_1;
    3560             :             move16();
    3561             :         }
    3562             :         ELSE
    3563             :         {
    3564             :             s_fx = tmp1;
    3565             :             move32();
    3566             : 
    3567             :             exp = sub( norm_l( s_fx ), 1 );
    3568             :             tmp2 = Mpy_32_32( s_fx, s_fx );
    3569             :             q_tmp2 = sub( add( q_tmp1, q_tmp1 ), 31 );
    3570             : 
    3571             :             tmp2 = BASOP_Util_Add_Mant32Exp( crossSquare_fx, sub( 31, q_crossSquare ), tmp2, sub( 31, q_tmp2 ), &q_tmp2 );
    3572             :             q_tmp2 = sub( 31, q_tmp2 );
    3573             : 
    3574             :             tmp3 = BASOP_Util_Add_Mant32Exp( tmp2, sub( 31, q_tmp2 ), epsilon_mant, epsilon_exp, &exp_tmp3 );
    3575             : 
    3576             :             tmp2 = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q30, tmp3, &exp );
    3577             :             exp = sub( exp, sub( Q30, sub( 31, exp_tmp3 ) ) );
    3578             :             normVal_fx = Sqrt32( tmp2, &exp ); // q_tmp2
    3579             :             q_tmp2 = sub( 31, exp );
    3580             : 
    3581             :             IF( LT_16( q_tmp1, q_c ) )
    3582             :             {
    3583             :                 c_re = L_shr( c_re, sub( q_c, q_tmp1 ) );
    3584             :                 c_im = L_shr( c_im, sub( q_c, q_tmp1 ) );
    3585             :                 q_c = q_tmp1;
    3586             :                 move16();
    3587             :             }
    3588             :             ELSE
    3589             :             {
    3590             :                 s_fx = L_shr( s_fx, sub( q_tmp1, q_c ) );
    3591             :                 q_tmp1 = q_c;
    3592             :                 move16();
    3593             :             }
    3594             : 
    3595             :             Ure_fx[1][ch] = Mpy_32_32( s_fx, normVal_fx );
    3596             :             move32();
    3597             :             Ure_fx[0][ch] = Mpy_32_32( c_re, normVal_fx );
    3598             :             move32();
    3599             :             Uim_fx[0][ch] = Mpy_32_32( -c_im, normVal_fx );
    3600             :             move32();
    3601             :             q_U_2 = sub( add( q_tmp1, q_tmp2 ), 31 );
    3602             : 
    3603             :             IF( q_U_1 != 0 )
    3604             :             {
    3605             :                 IF( LT_16( q_U_1, q_U_2 ) )
    3606             :                 {
    3607             :                     Ure_fx[1][ch] = L_shr( Ure_fx[1][ch], sub( q_U_2, q_U_1 ) );
    3608             :                     Ure_fx[0][ch] = L_shr( Ure_fx[0][ch], sub( q_U_2, q_U_1 ) );
    3609             :                     Uim_fx[0][ch] = L_shr( Uim_fx[0][ch], sub( q_U_2, q_U_1 ) );
    3610             :                     q_U_2 = q_U_1;
    3611             :                     move32();
    3612             :                     move32();
    3613             :                     move32();
    3614             :                     move16();
    3615             :                 }
    3616             :                 ELSE IF( GT_16( q_U_1, q_U_2 ) )
    3617             :                 {
    3618             :                     Ure_fx[1][ch - 1] = L_shr( Ure_fx[1][ch - 1], sub( q_U_1, q_U_2 ) );
    3619             :                     Ure_fx[0][ch - 1] = L_shr( Ure_fx[0][ch - 1], sub( q_U_1, q_U_2 ) );
    3620             :                     Uim_fx[1][ch - 1] = L_shr( Uim_fx[1][ch - 1], sub( q_U_1, q_U_2 ) );
    3621             :                     q_U_1 = q_U_2;
    3622             :                     move32();
    3623             :                     move32();
    3624             :                     move32();
    3625             :                     move16();
    3626             :                 }
    3627             :             }
    3628             :             q_U_1 = q_U_2;
    3629             :             move16();
    3630             :         }
    3631             :     }
    3632             : #endif /* OPT_SBA_REND_V1_BE */
    3633             : 
    3634    37352127 :     if ( q_U_1 != 0 )
    3635             :     {
    3636    37352127 :         *q_U = q_U_1;
    3637    37352127 :         move16();
    3638             :     }
    3639             : 
    3640    37352127 :     if ( q_U_1 == 0 )
    3641             :     {
    3642           0 :         *q_U = q_U_2;
    3643           0 :         move16();
    3644             :     }
    3645             : 
    3646    37352127 :     return;
    3647             : }
    3648             : 
    3649    20758785 : static void matrixDiagMul_fx(
    3650             :     Word32 reIn_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_In*/
    3651             :     Word32 imIn_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_In*/
    3652             :     Word16 q_In,
    3653             :     const Word32 D_fx[BINAURAL_CHANNELS], /*q_D*/
    3654             :     Word16 q_D,
    3655             :     Word32 reOut_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_Out*/
    3656             :     Word32 imOut_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_Out*/
    3657             :     Word16 *q_Out )
    3658             : {
    3659             :     Word16 chA, chB;
    3660    20758785 :     Word16 size = i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS );
    3661             : 
    3662    62276355 :     FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ )
    3663             :     {
    3664   124552710 :         FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ )
    3665             :         {
    3666    83035140 :             reOut_fx[chA][chB] = Mpy_32_32( reIn_fx[chA][chB], D_fx[chB] );
    3667    83035140 :             imOut_fx[chA][chB] = Mpy_32_32( imIn_fx[chA][chB], D_fx[chB] );
    3668    83035140 :             move32();
    3669    83035140 :             move32();
    3670             :         }
    3671             :     }
    3672             : 
    3673    20758785 :     *q_Out = sub( add( q_In, q_D ), 31 );
    3674    20758785 :     move16();
    3675             : 
    3676    20758785 :     if ( L_and( is_zero_arr( reOut_fx[0], size ), is_zero_arr( imOut_fx[0], size ) ) )
    3677             :     {
    3678       49339 :         *q_Out = Q31;
    3679       49339 :         move16();
    3680             :     }
    3681             : 
    3682    20758785 :     return;
    3683             : }
    3684             : 
    3685    75837075 : static void matrixMul_fx(
    3686             :     Word32 Are_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/
    3687             :     Word32 Aim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/
    3688             :     Word16 *q_A,
    3689             :     Word32 Bre_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_B*/
    3690             :     Word32 Bim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_B*/
    3691             :     Word16 *q_B,
    3692             :     Word32 outRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/
    3693             :     Word32 outIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/
    3694             :     Word16 *q_out )
    3695             : {
    3696             :     Word16 chA, chB;
    3697             :     Word16 min_q_shift1, min_q_shift2;
    3698    75837075 :     Word16 size = i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS );
    3699             : 
    3700    75837075 :     min_q_shift1 = sub( s_min( L_norm_arr( Are_fx[0], size ), L_norm_arr( Aim_fx[0], size ) ), 1 );
    3701    75837075 :     min_q_shift2 = sub( s_min( L_norm_arr( Bre_fx[0], size ), L_norm_arr( Bim_fx[0], size ) ), 1 );
    3702             : 
    3703    75837075 :     scale_sig32( Are_fx[0], size, min_q_shift1 );
    3704    75837075 :     scale_sig32( Aim_fx[0], size, min_q_shift1 );
    3705    75837075 :     scale_sig32( Bre_fx[0], size, min_q_shift2 );
    3706    75837075 :     scale_sig32( Bim_fx[0], size, min_q_shift2 );
    3707             : 
    3708    75837075 :     *q_A = add( *q_A, min_q_shift1 );
    3709    75837075 :     *q_B = add( *q_B, min_q_shift2 );
    3710    75837075 :     move16();
    3711    75837075 :     move16();
    3712             : 
    3713   227511225 :     FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ )
    3714             :     {
    3715   455022450 :         FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ )
    3716             :         {
    3717             : #ifdef IVAS_ENH64_CADENCE_CHANGES
    3718             :             outRe_fx[chA][chB] = W_extract_h( W_mac_32_32( W_mult_32_32( Are_fx[chA][0], Bre_fx[0][chB] ), Are_fx[chA][1], Bre_fx[1][chB] ) );
    3719             :             move32();
    3720             :             outRe_fx[chA][chB] = L_sub( outRe_fx[chA][chB], W_extract_h( W_mac_32_32( W_mult_32_32( Aim_fx[chA][0], Bim_fx[0][chB] ), Aim_fx[chA][1], Bim_fx[1][chB] ) ) );
    3721             :             move32();
    3722             :             outIm_fx[chA][chB] = W_extract_h( W_mac_32_32( W_mult_32_32( Aim_fx[chA][0], Bre_fx[0][chB] ), Aim_fx[chA][1], Bre_fx[1][chB] ) );
    3723             :             move32();
    3724             :             outIm_fx[chA][chB] = L_add( outIm_fx[chA][chB], W_extract_h( W_mac_32_32( W_mult_32_32( Are_fx[chA][0], Bim_fx[0][chB] ), Are_fx[chA][1], Bim_fx[1][chB] ) ) );
    3725             :             move32();
    3726             : #else
    3727   303348300 :             outRe_fx[chA][chB] = Msub_32_32( Msub_32_32( Madd_32_32( Mpy_32_32( Are_fx[chA][0], Bre_fx[0][chB] ),
    3728   303348300 :                                                                      Are_fx[chA][1], Bre_fx[1][chB] ),
    3729   303348300 :                                                          Aim_fx[chA][0], Bim_fx[0][chB] ),
    3730   303348300 :                                              Aim_fx[chA][1], Bim_fx[1][chB] );
    3731   303348300 :             move32();
    3732   303348300 :             outIm_fx[chA][chB] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Aim_fx[chA][0], Bre_fx[0][chB] ),
    3733   303348300 :                                                                      Aim_fx[chA][1], Bre_fx[1][chB] ),
    3734   303348300 :                                                          Are_fx[chA][0], Bim_fx[0][chB] ),
    3735   303348300 :                                              Are_fx[chA][1], Bim_fx[1][chB] );
    3736   303348300 :             move32();
    3737             : #endif /* #ifdef IVAS_ENH64_CADENCE_CHANGES */
    3738             :         }
    3739             :     }
    3740    75837075 :     *q_out = sub( add( *q_A, *q_B ), 31 );
    3741             : 
    3742    75837075 :     move16();
    3743    75837075 :     if ( L_and( is_zero_arr( outRe_fx[0], size ), is_zero_arr( outIm_fx[0], size ) ) )
    3744             :     {
    3745      289296 :         *q_out = Q31;
    3746      289296 :         move16();
    3747             :     }
    3748             : 
    3749    75837075 :     return;
    3750             : }
    3751             : 
    3752    20758785 : static void matrixTransp1Mul_fx(
    3753             :     Word32 Are_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/
    3754             :     Word32 Aim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/
    3755             :     Word16 q_A,
    3756             :     Word32 Bre_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_B*/
    3757             :     Word32 Bim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_B*/
    3758             :     Word16 q_B,
    3759             :     Word32 outRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/
    3760             :     Word32 outIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/
    3761             :     Word16 *q_out )
    3762             : {
    3763             :     Word16 chA, chB;
    3764    20758785 :     Word16 size = i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS );
    3765             : 
    3766             :     Word64 tmp_outRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
    3767             :     Word64 tmp_outIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
    3768             :     Word16 q_tmp_outRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
    3769             :     Word16 q_tmp_outIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
    3770             :     Word64 tmp64_1, tmp64_2;
    3771    20758785 :     Word16 tmp16, q_common = 63;
    3772    20758785 :     move16();
    3773             : 
    3774    62276355 :     FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ )
    3775             :     {
    3776   124552710 :         FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ )
    3777             :         {
    3778    83035140 :             tmp64_1 = W_mac_32_32( W_mult_32_32( Are_fx[0][chA], Bre_fx[0][chB] ), Are_fx[1][chA], Bre_fx[1][chB] ); // Q: add( add( q_A, q_B ), 1 )
    3779    83035140 :             tmp64_2 = W_mac_32_32( W_mult_32_32( Aim_fx[0][chA], Bim_fx[0][chB] ), Aim_fx[1][chA], Bim_fx[1][chB] ); // Q: add( add( q_A, q_B ), 1 )
    3780    83035140 :             tmp_outRe_fx[chA][chB] = W_add( tmp64_1, tmp64_2 );                                                      // Q: add( add( q_A, q_B ), 1 )
    3781    83035140 :             move64();
    3782    83035140 :             tmp16 = W_norm( tmp_outRe_fx[chA][chB] );
    3783    83035140 :             tmp_outRe_fx[chA][chB] = W_shl( tmp_outRe_fx[chA][chB], tmp16 ); // Q:add( tmp16, add( add( q_A, q_B ), 1 ) )
    3784    83035140 :             move64();
    3785    83035140 :             q_tmp_outRe_fx[chA][chB] = add( tmp16, add( add( q_A, q_B ), 1 ) );
    3786    83035140 :             move16();
    3787    83035140 :             q_common = s_min( q_tmp_outRe_fx[chA][chB], q_common );
    3788             : 
    3789             : 
    3790    83035140 :             tmp64_1 = W_mac_32_32( W_mult_32_32( Are_fx[0][chA], Bim_fx[0][chB] ), Are_fx[1][chA], Bim_fx[1][chB] ); // Q: add( add( q_A, q_B ), 1 )
    3791    83035140 :             tmp64_2 = W_mac_32_32( W_mult_32_32( Aim_fx[0][chA], Bre_fx[0][chB] ), Aim_fx[1][chA], Bre_fx[1][chB] ); // Q: add( add( q_A, q_B ), 1 )
    3792    83035140 :             tmp_outIm_fx[chA][chB] = W_sub( tmp64_1, tmp64_2 );                                                      // Q: add( add( q_A, q_B ), 1 )
    3793    83035140 :             move64();
    3794    83035140 :             tmp16 = W_norm( tmp_outIm_fx[chA][chB] );
    3795    83035140 :             tmp_outIm_fx[chA][chB] = W_shl( tmp_outIm_fx[chA][chB], tmp16 ); // Q:add( tmp16, add( add( q_A, q_B ), 1 ) )
    3796    83035140 :             move64();
    3797    83035140 :             q_tmp_outIm_fx[chA][chB] = add( tmp16, add( add( q_A, q_B ), 1 ) );
    3798    83035140 :             move16();
    3799    83035140 :             q_common = s_min( q_tmp_outIm_fx[chA][chB], q_common );
    3800             :         }
    3801             :     }
    3802    62276355 :     FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ )
    3803             :     {
    3804   124552710 :         FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ )
    3805             :         {
    3806    83035140 :             outRe_fx[chA][chB] = W_extract_h( W_shl( tmp_outRe_fx[chA][chB], sub( q_common, q_tmp_outRe_fx[chA][chB] ) ) );
    3807    83035140 :             move32();
    3808    83035140 :             outIm_fx[chA][chB] = W_extract_h( W_shl( tmp_outIm_fx[chA][chB], sub( q_common, q_tmp_outIm_fx[chA][chB] ) ) );
    3809    83035140 :             move32();
    3810             :         }
    3811             :     }
    3812    20758785 :     *q_out = sub( q_common, 32 );
    3813    20758785 :     move16();
    3814    20758785 :     if ( L_and( is_zero_arr( outRe_fx[0], size ), is_zero_arr( outIm_fx[0], size ) ) )
    3815             :     {
    3816       83909 :         *q_out = Q31;
    3817       83909 :         move16();
    3818             :     }
    3819             : 
    3820    20758785 :     return;
    3821             : }
    3822             : 
    3823    55078290 : static void matrixTransp2Mul_fx(
    3824             :     Word32 Are_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/
    3825             :     Word32 Aim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/
    3826             :     Word16 *q_A,
    3827             :     Word32 Bre_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_B*/
    3828             :     Word32 Bim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_B*/
    3829             :     Word16 *q_B,
    3830             :     Word32 Ascale,
    3831             :     Word32 Bscale,
    3832             :     Word32 outRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/
    3833             :     Word32 outIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/
    3834             :     Word16 *q_out )
    3835             : {
    3836             :     Word16 chA, chB;
    3837             :     Word16 min_q_shift;
    3838    55078290 :     Word16 size = BINAURAL_CHANNELS * BINAURAL_CHANNELS;
    3839             : 
    3840    55078290 :     IF( Ascale == 1 )
    3841             :     {
    3842    34319505 :         min_q_shift = sub( s_min( L_norm_arr( Are_fx[0], size ), L_norm_arr( Aim_fx[0], size ) ), 1 );
    3843    34319505 :         scale_sig32( Are_fx[0], size, min_q_shift );
    3844    34319505 :         scale_sig32( Aim_fx[0], size, min_q_shift );
    3845    34319505 :         *q_A = add( *q_A, min_q_shift );
    3846    34319505 :         move16();
    3847             :     }
    3848             : 
    3849    55078290 :     IF( Bscale == 1 )
    3850             :     {
    3851           0 :         min_q_shift = sub( s_min( L_norm_arr( Bre_fx[0], size ), L_norm_arr( Bim_fx[0], size ) ), 1 );
    3852           0 :         scale_sig32( Bre_fx[0], size, min_q_shift );
    3853           0 :         scale_sig32( Bim_fx[0], size, min_q_shift );
    3854           0 :         *q_B = add( *q_B, min_q_shift );
    3855           0 :         move16();
    3856             :     }
    3857             : 
    3858   165234870 :     FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ )
    3859             :     {
    3860   330469740 :         FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ )
    3861             :         {
    3862             : #ifdef IVAS_ENH64_CADENCE_CHANGES
    3863             :             outRe_fx[chA][chB] = W_extract_h( W_mac_32_32( W_mult_32_32( Are_fx[chA][0], Bre_fx[chB][0] ), Are_fx[chA][1], Bre_fx[chB][1] ) );
    3864             :             move32();
    3865             :             outRe_fx[chA][chB] = L_sub( outRe_fx[chA][chB], W_extract_h( W_mac_32_32( W_mult_32_32( Aim_fx[chA][0], L_negate( Bim_fx[chB][0] ) ), Aim_fx[chA][1], L_negate( Bim_fx[chB][1] ) ) ) );
    3866             :             move32();
    3867             :             outIm_fx[chA][chB] = W_extract_h( W_mac_32_32( W_mult_32_32( Aim_fx[chA][0], Bre_fx[chB][0] ), Aim_fx[chA][1], Bre_fx[chB][1] ) );
    3868             :             move32();
    3869             :             outIm_fx[chA][chB] = L_add( outIm_fx[chA][chB], W_extract_h( W_mac_32_32( W_mult_32_32( Are_fx[chA][0], L_negate( Bim_fx[chB][0] ) ), Are_fx[chA][1], L_negate( Bim_fx[chB][1] ) ) ) );
    3870             :             move32();
    3871             : #else
    3872   220313160 :             outRe_fx[chA][chB] = Madd_32_32( Madd_32_32( Madd_32_32( Mpy_32_32( Are_fx[chA][0], Bre_fx[chB][0] ),
    3873   220313160 :                                                                      Are_fx[chA][1], Bre_fx[chB][1] ),
    3874   220313160 :                                                          Aim_fx[chA][0], Bim_fx[chB][0] ),
    3875   220313160 :                                              Aim_fx[chA][1], Bim_fx[chB][1] );
    3876   220313160 :             move32();
    3877   220313160 :             outIm_fx[chA][chB] = Msub_32_32( Msub_32_32( Madd_32_32( Mpy_32_32( Aim_fx[chA][0], Bre_fx[chB][0] ),
    3878   220313160 :                                                                      Aim_fx[chA][1], Bre_fx[chB][1] ),
    3879   220313160 :                                                          Are_fx[chA][0], Bim_fx[chB][0] ),
    3880   220313160 :                                              Are_fx[chA][1], Bim_fx[chB][1] );
    3881   220313160 :             move32();
    3882             : #endif /* #ifdef IVAS_ENH64_CADENCE_CHANGES */
    3883             :         }
    3884             :     }
    3885    55078290 :     *q_out = sub( add( *q_A, *q_B ), 31 );
    3886    55078290 :     move16();
    3887             : 
    3888    55078290 :     if ( L_and( is_zero_arr( outRe_fx[0], size ), is_zero_arr( outIm_fx[0], size ) ) )
    3889             :     {
    3890      209223 :         *q_out = Q31;
    3891      209223 :         move16();
    3892             :     }
    3893    55078290 :     return;
    3894             : }
    3895             : 
    3896             : 
    3897    20758785 : static void chol2x2_fx(
    3898             :     const Word32 E1, /*q_E*/
    3899             :     const Word32 E2, /*q_E*/
    3900             :     Word16 q_E,
    3901             :     const Word32 Cre, /*q_C*/
    3902             :     const Word32 Cim, /*q_C*/
    3903             :     Word16 q_C,
    3904             :     Word32 outRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/
    3905             :     Word32 outIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/
    3906             :     Word16 *q_out )
    3907             : {
    3908             :     Word16 chA, chB;
    3909             :     Word32 sqrtVal_fx, temp;
    3910             :     Word16 exp, q_re1, q_re2, q_re3, q_im, q_tmp;
    3911             :     Word32 e1, e2, c_re, c_im;
    3912             :     Word16 q_e, q_c;
    3913             : 
    3914    20758785 :     exp = sub( get_min_scalefactor( E1, E2 ), 1 );
    3915    20758785 :     e1 = L_shl( E1, exp );
    3916    20758785 :     e2 = L_shl( E2, exp );
    3917    20758785 :     q_e = add( q_E, exp );
    3918             : 
    3919    20758785 :     exp = sub( get_min_scalefactor( Cre, Cim ), 1 );
    3920    20758785 :     c_re = L_shl( Cre, exp );
    3921    20758785 :     c_im = L_shl( Cim, exp );
    3922    20758785 :     q_c = add( q_C, exp );
    3923             : 
    3924             : 
    3925    62276355 :     FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ )
    3926             :     {
    3927   124552710 :         FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ )
    3928             :         {
    3929    83035140 :             outRe[chA][chB] = 0;
    3930    83035140 :             move32();
    3931    83035140 :             outIm[chA][chB] = 0;
    3932    83035140 :             move32();
    3933             :         }
    3934             :     }
    3935             : 
    3936    20758785 :     IF( GT_32( e1, e2 ) ) /* Perform Cholesky decomposition according to louder channel first */
    3937             :     {
    3938    10435736 :         exp = sub( 31, q_e );
    3939    10435736 :         outRe[0][0] = Sqrt32( e1, &exp );
    3940    10435736 :         move32();
    3941    10435736 :         q_re1 = sub( 31, exp );
    3942             : 
    3943             :         // 4611686 = 1e-12 in Q62
    3944    10435736 :         IF( outRe[0][0] == 0 )
    3945             :         {
    3946           0 :             outRe[1][0] = BASOP_Util_Divide3232_Scale_newton( c_re, 4611686, &exp );
    3947           0 :             move32();
    3948           0 :             q_re2 = add( sub( 31, exp ), sub( q_c, 62 ) );
    3949             : 
    3950           0 :             outIm[1][0] = BASOP_Util_Divide3232_Scale_newton( c_im, 4611686, &exp );
    3951           0 :             move32();
    3952           0 :             q_im = add( sub( 31, exp ), sub( q_c, 62 ) );
    3953             :         }
    3954             :         ELSE
    3955             :         {
    3956             :             Word32 denom;
    3957             :             Word16 den_exp;
    3958             :             Word32 my_outRe, my_outIm;
    3959             : 
    3960             :             /* Compute denom = 1.0 / outRe[0][0] */
    3961    10435736 :             denom = ISqrt32( outRe[0][0], &exp );
    3962    10435736 :             denom = Mpy_32_32( denom, denom );
    3963    10435736 :             den_exp = shl( exp, 1 );
    3964             : 
    3965             :             /* Normalise c_re, c_im */
    3966    10435736 :             exp = norm_l( c_re );
    3967    10435736 :             my_outRe = L_shl( c_re, exp );
    3968    10435736 :             q_re2 = add( q_c, exp );
    3969    10435736 :             exp = norm_l( c_im );
    3970    10435736 :             my_outIm = L_shl( c_im, exp );
    3971    10435736 :             q_im = add( q_c, exp );
    3972             : 
    3973             :             /* Multiply and store c_re*denom and c_im*denom */
    3974    10435736 :             outRe[1][0] = Mpy_32_32( denom, my_outRe );
    3975    10435736 :             move32();
    3976    10435736 :             q_re2 = sub( q_re2, den_exp );
    3977             : 
    3978    10435736 :             outIm[1][0] = Mpy_32_32( denom, my_outIm );
    3979    10435736 :             move32();
    3980    10435736 :             q_im = sub( q_im, den_exp );
    3981             :         }
    3982    10435736 :         if ( outRe[1][0] == 0 )
    3983             :         {
    3984         700 :             q_re2 = Q31;
    3985         700 :             move16();
    3986             :         }
    3987    10435736 :         if ( outIm[1][0] == 0 )
    3988             :         {
    3989     7167781 :             q_im = Q31;
    3990     7167781 :             move16();
    3991             :         }
    3992             : 
    3993    10435736 :         temp = Madd_32_32( Mpy_32_32( c_re, c_re ), c_im, c_im );
    3994    10435736 :         q_tmp = sub( add( q_c, q_c ), 31 );
    3995             : 
    3996             :         // 4611686 = Q62
    3997    10435736 :         IF( e1 == 0 )
    3998             :         {
    3999           0 :             Word16 norm = norm_l( temp );
    4000           0 :             temp = L_shl( temp, norm );
    4001           0 :             q_tmp = add( q_tmp, norm );
    4002           0 :             temp = Mpy_32_32( temp, ONE_DIV_EPSILON_MANT );
    4003           0 :             q_tmp = sub( q_tmp, ONE_DIV_EPSILON_EXP );
    4004             :         }
    4005             :         ELSE
    4006             :         {
    4007    10435736 :             temp = BASOP_Util_Divide3232_Scale_newton( temp, e1, &exp );
    4008    10435736 :             q_tmp = add( sub( 31, exp ), sub( q_tmp, q_e ) );
    4009             :         }
    4010    10435736 :         if ( temp == 0 )
    4011             :         {
    4012         680 :             q_tmp = Q31;
    4013         680 :             move16();
    4014             :         }
    4015             : 
    4016    10435736 :         IF( LT_16( q_e, q_tmp ) )
    4017             :         {
    4018     9339673 :             sqrtVal_fx = L_sub( e2, L_shr( temp, sub( q_tmp, q_e ) ) ); ////q_tmp
    4019     9339673 :             q_tmp = q_e;
    4020     9339673 :             move16();
    4021             :         }
    4022             :         ELSE
    4023             :         {
    4024     1096063 :             sqrtVal_fx = L_sub( L_shr( e2, sub( q_e, q_tmp ) ), temp ); // q_tmp
    4025             :         }
    4026             : 
    4027    10435736 :         exp = sub( 31, q_tmp );
    4028    10435736 :         outRe[1][1] = Sqrt32( L_max( 0, sqrtVal_fx ), &exp );
    4029    10435736 :         move32();
    4030    10435736 :         q_re3 = sub( 31, exp );
    4031             : 
    4032    10435736 :         *q_out = s_min( s_min( q_re1, q_re2 ), s_min( q_re3, q_im ) );
    4033    10435736 :         outRe[0][0] = L_shr( outRe[0][0], sub( q_re1, *q_out ) );
    4034    10435736 :         move32();
    4035    10435736 :         outRe[1][0] = L_shr( outRe[1][0], sub( q_re2, *q_out ) );
    4036    10435736 :         move32();
    4037    10435736 :         outIm[1][0] = L_shr( outIm[1][0], sub( q_im, *q_out ) );
    4038    10435736 :         move32();
    4039    10435736 :         outRe[1][1] = L_shr( outRe[1][1], sub( q_re3, *q_out ) );
    4040    10435736 :         move32();
    4041             :     }
    4042             :     ELSE
    4043             :     {
    4044    10323049 :         exp = sub( 31, q_e );
    4045    10323049 :         outRe[1][1] = Sqrt32( e2, &exp );
    4046    10323049 :         move32();
    4047    10323049 :         q_re1 = sub( 31, exp );
    4048             : 
    4049             :         // 4611686 = Q62
    4050    10323049 :         IF( outRe[1][1] == 0 )
    4051             :         {
    4052             :             // outRe[0][1] = BASOP_Util_Divide3232_Scale_newton( c_re, 4611686, &exp );
    4053       80073 :             Word32 tmp1 = 1953125005; /* 1/4611686 Q62 */
    4054       80073 :             exp = 9;
    4055             : 
    4056       80073 :             outRe[0][1] = Mpy_32_32( tmp1, c_re );
    4057       80073 :             move32();
    4058       80073 :             q_re2 = add( sub( 31, exp ), sub( q_c, 62 ) );
    4059             : 
    4060             :             // outIm[0][1] = BASOP_Util_Divide3232_Scale_newton( -c_im, 4611686, &exp );
    4061       80073 :             outIm[0][1] = Mpy_32_32( tmp1, -c_im );
    4062       80073 :             move32();
    4063       80073 :             q_im = add( sub( 31, exp ), sub( q_c, 62 ) );
    4064             :         }
    4065             :         ELSE
    4066             :         {
    4067             :             {
    4068             :                 // outRe[0][1] = BASOP_Util_Divide3232_Scale_newton( c_re, outRe[1][1], &exp );
    4069    10242976 :                 Word32 tmp1 = BASOP_Util_Divide3232_Scale_newton( 0x7FFFFFFF, outRe[1][1], &exp );
    4070    10242976 :                 outRe[0][1] = Mpy_32_32( tmp1, c_re );
    4071    10242976 :                 move32();
    4072    10242976 :                 q_re2 = add( sub( 31, exp ), sub( q_c, q_re1 ) );
    4073             : 
    4074             :                 // outIm[0][1] = BASOP_Util_Divide3232_Scale_newton( -c_im, outRe[1][1], &exp );
    4075    10242976 :                 outIm[0][1] = Mpy_32_32( tmp1, -c_im );
    4076    10242976 :                 move32();
    4077    10242976 :                 q_im = add( sub( 31, exp ), sub( q_c, q_re1 ) );
    4078             :             }
    4079             :         }
    4080    10323049 :         if ( outRe[0][1] == 0 )
    4081             :         {
    4082       87869 :             q_re2 = Q31;
    4083       87869 :             move16();
    4084             :         }
    4085    10323049 :         if ( outIm[0][1] == 0 )
    4086             :         {
    4087     8452667 :             q_im = Q31;
    4088     8452667 :             move16();
    4089             :         }
    4090             : 
    4091    10323049 :         temp = Madd_32_32( Mpy_32_32( c_re, c_re ), c_im, c_im );
    4092    10323049 :         q_tmp = sub( add( q_c, q_c ), 31 );
    4093             : 
    4094             :         // 4611686 = 1e-12 in Q62
    4095    10323049 :         IF( e2 == 0 )
    4096             :         {
    4097       80073 :             temp = BASOP_Util_Divide3232_Scale_newton( temp, 4611686, &exp );
    4098       80073 :             q_tmp = add( sub( 31, exp ), sub( q_tmp, 62 ) );
    4099             :         }
    4100             :         ELSE
    4101             :         {
    4102    10242976 :             temp = BASOP_Util_Divide3232_Scale_newton( temp, e2, &exp );
    4103    10242976 :             q_tmp = add( sub( 31, exp ), sub( q_tmp, q_e ) );
    4104             :         }
    4105    10323049 :         if ( temp == 0 )
    4106             :         {
    4107       87850 :             q_tmp = Q31;
    4108       87850 :             move16();
    4109             :         }
    4110             : 
    4111    10323049 :         IF( LT_16( q_e, q_tmp ) )
    4112             :         {
    4113     9414853 :             sqrtVal_fx = L_sub( e1, L_shr( temp, sub( q_tmp, q_e ) ) ); ////q_tmp
    4114     9414853 :             q_tmp = q_e;
    4115     9414853 :             move16();
    4116             :         }
    4117             :         ELSE
    4118             :         {
    4119      908196 :             sqrtVal_fx = L_sub( L_shr( e1, sub( q_e, q_tmp ) ), temp ); ////q_tmp
    4120             :         }
    4121             : 
    4122    10323049 :         exp = sub( 31, q_tmp );
    4123    10323049 :         outRe[0][0] = Sqrt32( L_max( 0, sqrtVal_fx ), &exp );
    4124    10323049 :         move32();
    4125    10323049 :         q_re3 = sub( 31, exp );
    4126             : 
    4127    10323049 :         *q_out = s_min( s_min( q_re1, q_re2 ), s_min( q_re3, q_im ) );
    4128    10323049 :         move16();
    4129    10323049 :         outRe[1][1] = L_shr( outRe[1][1], sub( q_re1, *q_out ) );
    4130    10323049 :         move32();
    4131    10323049 :         outRe[0][1] = L_shr( outRe[0][1], sub( q_re2, *q_out ) );
    4132    10323049 :         move32();
    4133    10323049 :         outIm[0][1] = L_shr( outIm[0][1], sub( q_im, *q_out ) );
    4134    10323049 :         move32();
    4135    10323049 :         outRe[0][0] = L_shr( outRe[0][0], sub( q_re3, *q_out ) );
    4136    10323049 :         move32();
    4137             :     }
    4138             : 
    4139    20758785 :     return;
    4140             : }
    4141    20758785 : static void formulate2x2MixingMatrix_fx(
    4142             :     Word32 Ein1_fx, /*q_Ein*/
    4143             :     Word32 Ein2_fx, /*q_Ein*/
    4144             :     Word16 q_Ein,
    4145             :     Word32 CinRe_fx, /*q_Cin*/
    4146             :     Word32 CinIm_fx, /*q_Cin*/
    4147             :     Word16 q_Cin,
    4148             :     Word32 Eout1_fx, /*q_Eout*/
    4149             :     Word32 Eout2_fx, /*q_Eout*/
    4150             :     Word16 q_Eout,
    4151             :     Word32 CoutRe_fx, /*q_Cout*/
    4152             :     Word32 CoutIm_fx, /*q_Cout*/
    4153             :     Word16 q_Cout,
    4154             :     Word32 Q_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS],   // Q31
    4155             :     Word32 Mre_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_M*/
    4156             :     Word32 Mim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_M*/
    4157             :     Word16 *q_M,
    4158             :     const Word16 regularizationFactor_fx /*Q14*/ )
    4159             : {
    4160             :     /*
    4161             :      This function implements a 2x2 solution for an optimized spatial audio rendering algorithm
    4162             :      Vilkamo, J., Bäckström, T. and Kuntz, A., 2013.
    4163             :      "Optimized covariance domain framework for time–frequency processing of spatial audio."
    4164             :      Journal of the Audio Engineering Society, 61(6), pp.403-411.
    4165             : 
    4166             :      The result of the formulas below are the same as those in the publication, however, some
    4167             :      derivation details differ for as simple as possible 2x2 formulattion
    4168             :      */
    4169             :     Word16 chA, chB;
    4170             :     Word32 maxEne_fx, tmp, maxEneDiv_fx;
    4171             :     Word16 q_maxEne, q_maxEneDiv, exp, exp1;
    4172             :     Word32 KyRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], KyIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
    4173             :     Word32 Uxre_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], Uxim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
    4174             :     Word32 Sx_fx[BINAURAL_CHANNELS], Kxre_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], Kxim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
    4175             :     Word32 tmpRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], tmpIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
    4176             :     Word32 Are_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], Aim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
    4177             :     Word32 Ure_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], Uim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
    4178             :     Word32 D_fx[BINAURAL_CHANNELS];
    4179             :     Word32 div_fx[BINAURAL_CHANNELS];
    4180             :     Word32 Ghat_fx[BINAURAL_CHANNELS];
    4181             :     Word32 GhatQ_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
    4182             :     Word32 Pre_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], Pim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
    4183             :     Word16 q_ky, q_Sx, q_Ux, q_Kx, q_A, q_U, q_D, q_P;
    4184             :     Word32 E_in1, E_in2, E_out1, E_out2, Cout_re, Cout_im, Cin_re, Cin_im;
    4185             :     Word16 q_ein, q_eout, q_cin, q_cout, q_Ghat, q_GhatQ, q_temp, q_div, exp_temp;
    4186             :     Word32 temp;
    4187             :     Word16 q_Pre[BINAURAL_CHANNELS][BINAURAL_CHANNELS], q_Pim[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
    4188             :     Word16 hdrm_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], hdrm_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS];
    4189    20758785 :     set16_fx( hdrm_re[0], 63, i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ) );
    4190    20758785 :     set16_fx( hdrm_im[0], 63, i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ) );
    4191    20758785 :     set16_fx( q_Pre[0], Q31, i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ) );
    4192    20758785 :     set16_fx( q_Pim[0], Q31, i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ) );
    4193             : 
    4194    20758785 :     q_ky = 0;
    4195    20758785 :     move16();
    4196    20758785 :     q_Sx = 0;
    4197    20758785 :     move16();
    4198    20758785 :     q_Ux = 0;
    4199    20758785 :     move16();
    4200    20758785 :     q_Kx = 0;
    4201    20758785 :     move16();
    4202             : 
    4203    20758785 :     exp = sub( get_min_scalefactor( Ein1_fx, Ein2_fx ), 1 );
    4204    20758785 :     E_in1 = L_shl( Ein1_fx, exp );
    4205    20758785 :     E_in2 = L_shl( Ein2_fx, exp );
    4206    20758785 :     q_ein = add( q_Ein, exp );
    4207             : 
    4208    20758785 :     exp = sub( get_min_scalefactor( Eout1_fx, Eout2_fx ), 1 );
    4209    20758785 :     E_out1 = L_shl( Eout1_fx, exp );
    4210    20758785 :     E_out2 = L_shl( Eout2_fx, exp );
    4211    20758785 :     q_eout = add( q_Eout, exp );
    4212             : 
    4213    20758785 :     exp = sub( get_min_scalefactor( CinRe_fx, CinIm_fx ), 1 );
    4214    20758785 :     Cin_re = L_shl( CinRe_fx, exp );
    4215    20758785 :     Cin_im = L_shl( CinIm_fx, exp );
    4216    20758785 :     q_cin = add( q_Cin, exp );
    4217             : 
    4218    20758785 :     exp = sub( get_min_scalefactor( CoutRe_fx, CoutIm_fx ), 1 );
    4219    20758785 :     Cout_re = L_shl( CoutRe_fx, exp );
    4220    20758785 :     Cout_im = L_shl( CoutIm_fx, exp );
    4221    20758785 :     q_cout = add( q_Cout, exp );
    4222             : 
    4223             :     /* Normalize energy values */
    4224    20758785 :     maxEne_fx = L_max( E_in1, E_in2 );
    4225    20758785 :     q_maxEne = q_ein;
    4226    20758785 :     move16();
    4227             : 
    4228    20758785 :     tmp = L_max( E_out1, E_out2 );
    4229    20758785 :     IF( LT_16( q_maxEne, q_eout ) )
    4230             :     {
    4231    11646785 :         maxEne_fx = L_max( maxEne_fx, L_shr( tmp, sub( q_eout, q_maxEne ) ) ); // q_maxEne
    4232             :     }
    4233             :     ELSE
    4234             :     {
    4235     9112000 :         maxEne_fx = L_max( L_shr( maxEne_fx, sub( q_maxEne, q_eout ) ), tmp ); // q_maxEne
    4236     9112000 :         q_maxEne = q_eout;
    4237     9112000 :         move16();
    4238             :     }
    4239             : 
    4240             :     // 4611686 = Q62
    4241    20758785 :     IF( maxEne_fx == 0 )
    4242             :     {
    4243       49339 :         maxEneDiv_fx = ONE_DIV_EPSILON_MANT;
    4244       49339 :         move32();
    4245       49339 :         q_maxEneDiv = 31 - ONE_DIV_EPSILON_EXP;
    4246       49339 :         move16();
    4247             :     }
    4248             :     ELSE
    4249             :     {
    4250    20709446 :         maxEneDiv_fx = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q30, maxEne_fx, &exp );
    4251    20709446 :         q_maxEneDiv = add( sub( 31, exp ), sub( Q30, q_maxEne ) );
    4252             :     }
    4253    20758785 :     exp = norm_l( maxEneDiv_fx );
    4254    20758785 :     maxEneDiv_fx = L_shl( maxEneDiv_fx, exp );
    4255    20758785 :     q_maxEneDiv = add( q_maxEneDiv, exp );
    4256             : 
    4257    20758785 :     E_in1 = Mpy_32_32( E_in1, maxEneDiv_fx );
    4258    20758785 :     E_in2 = Mpy_32_32( E_in2, maxEneDiv_fx );
    4259    20758785 :     q_ein = sub( add( q_ein, q_maxEneDiv ), 31 );
    4260             : 
    4261    20758785 :     Cin_re = Mpy_32_32( Cin_re, maxEneDiv_fx );
    4262    20758785 :     Cin_im = Mpy_32_32( Cin_im, maxEneDiv_fx );
    4263    20758785 :     q_cin = sub( add( q_cin, q_maxEneDiv ), 31 );
    4264             : 
    4265    20758785 :     E_out1 = Mpy_32_32( E_out1, maxEneDiv_fx );
    4266    20758785 :     E_out2 = Mpy_32_32( E_out2, maxEneDiv_fx );
    4267    20758785 :     q_eout = sub( add( q_eout, q_maxEneDiv ), 31 );
    4268             : 
    4269    20758785 :     Cout_re = Mpy_32_32( Cout_re, maxEneDiv_fx );
    4270    20758785 :     Cout_im = Mpy_32_32( Cout_im, maxEneDiv_fx );
    4271    20758785 :     q_cout = sub( add( q_cout, q_maxEneDiv ), 31 );
    4272             : 
    4273             :     /* Cholesky decomposition of target / output covariance matrix */
    4274    20758785 :     chol2x2_fx( E_out1, E_out2, q_eout, Cout_re, Cout_im, q_cout, KyRe_fx, KyIm_fx, &q_ky );
    4275             : 
    4276             :     /* Eigendecomposition of input covariance matrix */
    4277    20758785 :     eig2x2_fx( E_in1, E_in2, q_ein, Cin_re, Cin_im, q_cin, Uxre_fx, Uxim_fx, &q_Ux, Sx_fx, &q_Sx );
    4278             : 
    4279             :     /* Eigendecomposition to Kx -- Ux Sx Ux' -> Kx Kx'*/
    4280    20758785 :     exp = sub( 31, q_Sx );
    4281    20758785 :     exp1 = sub( 31, q_Sx );
    4282    20758785 :     Sx_fx[0] = Sqrt32( Sx_fx[0], &exp );
    4283    20758785 :     move32();
    4284    20758785 :     Sx_fx[1] = Sqrt32( Sx_fx[1], &exp1 );
    4285    20758785 :     move32();
    4286    20758785 :     q_Sx = sub( 31, s_max( exp, exp1 ) );
    4287    20758785 :     Word16 q_diff = sub( 31, q_Sx );
    4288    20758785 :     Sx_fx[0] = L_shr( Sx_fx[0], sub( q_diff, exp ) ); // q_Sx
    4289    20758785 :     move32();
    4290    20758785 :     Sx_fx[1] = L_shr( Sx_fx[1], sub( q_diff, exp1 ) ); // q_Sx
    4291    20758785 :     move32();
    4292             : 
    4293    20758785 :     matrixDiagMul_fx( Uxre_fx, Uxim_fx, q_Ux, Sx_fx, q_Sx, Kxre_fx, Kxim_fx, &q_Kx );
    4294             : 
    4295             :     /* Regularize the diagonal Sx for matrix inversion */
    4296    20758785 :     Sx_fx[0] = L_max( L_shr( Sx_fx[0], 1 ), Mpy_32_16_1( Sx_fx[1], regularizationFactor_fx ) );
    4297    20758785 :     Sx_fx[1] = L_max( L_shr( Sx_fx[1], 1 ), L_shl( Mpy_32_16_1( Sx_fx[0], regularizationFactor_fx ), 1 ) );
    4298    20758785 :     move32();
    4299    20758785 :     move32();
    4300    20758785 :     q_Sx = sub( add( q_Sx, Q14 ), 15 );
    4301             : 
    4302    20758785 :     temp = Mpy_32_32( E_in2, 2147484 ); // 2147484 = 0.001f in Q31
    4303    20758785 :     temp = L_max( temp, E_in1 );
    4304             : 
    4305    20758785 :     IF( temp == 0 )
    4306             :     {
    4307       49339 :         IF( E_out1 == 0 )
    4308             :         {
    4309       49339 :             Ghat_fx[0] = 0;
    4310       49339 :             exp = -19;
    4311       49339 :             move32();
    4312       49339 :             move16();
    4313             :         }
    4314             :         ELSE
    4315             :         {
    4316           0 :             temp = BASOP_Util_Divide3232_Scale_newton( E_out1, 4611686, &exp ); // 4611686 = Q62
    4317           0 :             exp = sub( exp, sub( q_eout, 62 ) );
    4318           0 :             Ghat_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp
    4319             :         }
    4320             :     }
    4321             :     ELSE
    4322             :     {
    4323    20709446 :         temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp );
    4324             : 
    4325    20709446 :         temp = BASOP_Util_Divide3232_Scale_newton( E_out1, temp, &exp );
    4326    20709446 :         exp = sub( exp, sub( q_eout, sub( 31, exp_temp ) ) );
    4327    20709446 :         Ghat_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp
    4328             :     }
    4329    20758785 :     move32();
    4330             : 
    4331    20758785 :     temp = Mpy_32_32( E_in1, 2147484 ); // 2147484 = 0.001f in Q31
    4332    20758785 :     temp = L_max( temp, E_in2 );        // q_ein
    4333    20758785 :     IF( temp == 0 )
    4334             :     {
    4335       49339 :         IF( E_out2 == 0 )
    4336             :         { /* We can set hard-coded results */
    4337       49339 :             Ghat_fx[1] = 0;
    4338       49339 :             exp1 = -19;
    4339       49339 :             move16();
    4340             :         }
    4341             :         ELSE
    4342             :         {
    4343           0 :             temp = BASOP_Util_Divide3232_Scale_newton( E_out2, 4611686, &exp1 ); // 4611686 = Q62
    4344           0 :             exp1 = sub( exp1, sub( q_eout, 62 ) );
    4345           0 :             Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1
    4346             :         }
    4347             :     }
    4348             :     ELSE
    4349             :     {
    4350    20709446 :         temp = BASOP_Util_Add_Mant32Exp( temp, sub( 31, q_ein ), EPSILON_MANT, EPSILON_EXP, &exp_temp );
    4351             : 
    4352    20709446 :         temp = BASOP_Util_Divide3232_Scale_newton( E_out2, temp, &exp1 );
    4353    20709446 :         exp1 = sub( exp1, sub( q_eout, sub( 31, exp_temp ) ) );
    4354    20709446 :         Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1
    4355             :     }
    4356    20758785 :     move32();
    4357             : 
    4358    20758785 :     q_Ghat = sub( 31, s_max( exp, exp1 ) );
    4359    20758785 :     q_diff = sub( 31, q_Ghat );
    4360    20758785 :     Ghat_fx[0] = L_shr( Ghat_fx[0], sub( q_diff, exp ) ); // q_Ghat
    4361    20758785 :     move32();
    4362    20758785 :     Ghat_fx[1] = L_shr( Ghat_fx[1], sub( q_diff, exp1 ) ); // q_Ghat
    4363    20758785 :     move32();
    4364             : 
    4365             :     /* Matrix multiplication, tmp = Ky' * G_hat * Q */
    4366    62276355 :     FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ )
    4367             :     {
    4368    41517570 :         GhatQ_fx[chA][0] = Mpy_32_32( Q_fx[chA][0], Ghat_fx[chA] );
    4369    41517570 :         GhatQ_fx[chA][1] = Mpy_32_32( Q_fx[chA][1], Ghat_fx[chA] );
    4370    41517570 :         move32();
    4371    41517570 :         move32();
    4372             :     }
    4373    20758785 :     q_GhatQ = sub( add( Q31, q_Ghat ), 31 );
    4374             : 
    4375    20758785 :     exp = sub( s_min( L_norm_arr( KyRe_fx[0], i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ) ), L_norm_arr( KyIm_fx[0], i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ) ) ), 1 );
    4376    20758785 :     scale_sig32( KyRe_fx[0], BINAURAL_CHANNELS * BINAURAL_CHANNELS, exp );
    4377    20758785 :     scale_sig32( KyIm_fx[0], BINAURAL_CHANNELS * BINAURAL_CHANNELS, exp );
    4378    20758785 :     q_ky = add( q_ky, exp );
    4379             : 
    4380    62276355 :     FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ )
    4381             :     {
    4382   124552710 :         FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ )
    4383             :         {
    4384    83035140 :             tmpRe_fx[chA][chB] = Madd_32_32( Mpy_32_32( KyRe_fx[0][chA], GhatQ_fx[0][chB] ), KyRe_fx[1][chA], GhatQ_fx[1][chB] );
    4385    83035140 :             tmpIm_fx[chA][chB] = Msub_32_32( Mpy_32_32( L_negate( KyIm_fx[0][chA] ), GhatQ_fx[0][chB] ), KyIm_fx[1][chA], GhatQ_fx[1][chB] );
    4386    83035140 :             move32();
    4387    83035140 :             move32();
    4388             :         }
    4389             :     }
    4390             : 
    4391    20758785 :     q_temp = sub( add( q_ky, q_GhatQ ), 31 );
    4392             : 
    4393             :     /* A = Ky' * G_hat * Q * Kx (see publication) */
    4394    20758785 :     matrixMul_fx( tmpRe_fx, tmpIm_fx, &q_temp, Kxre_fx, Kxim_fx, &q_Kx, Are_fx, Aim_fx, &q_A );
    4395             : 
    4396             :     /* Find nearest orthonormal matrix P to A = Ky' * G_hat * Q * Kx
    4397             :        For matrix A that is P = A(A'A)^0.5 */
    4398    20758785 :     matrixTransp1Mul_fx( Are_fx, Aim_fx, q_A, Are_fx, Aim_fx, q_A, tmpRe_fx, tmpIm_fx, &q_temp );
    4399             : 
    4400    20758785 :     eig2x2_fx( tmpRe_fx[0][0], tmpRe_fx[1][1], q_temp, tmpRe_fx[1][0], tmpIm_fx[1][0], q_temp, Ure_fx, Uim_fx, &q_U, D_fx, &q_D );
    4401             : 
    4402    20758785 :     IF( D_fx[0] == 0 )
    4403             :     {
    4404      179308 :         temp = ONE_DIV_EPSILON_MANT; /* Result of 1.0/eps with full precision */
    4405      179308 :         move32();
    4406      179308 :         exp = ONE_DIV_EPSILON_EXP;
    4407      179308 :         move16();
    4408             :     }
    4409             :     ELSE
    4410             :     {
    4411    20579477 :         temp = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q30, D_fx[0], &exp );
    4412    20579477 :         exp = sub( exp, sub( Q30, q_D ) );
    4413             :     }
    4414    20758785 :     div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp
    4415    20758785 :     move32();
    4416             : 
    4417             :     // Sqrt(1)
    4418    20758785 :     div_fx[1] = L_add( 0, 2047986068 ); // Q = 31 - exp1
    4419    20758785 :     exp1 = add( 0, 20 );
    4420             : 
    4421    20758785 :     IF( D_fx[1] != 0 ) // This is the new code: replace div sqrt by isqrt
    4422             :     {
    4423    16201772 :         exp1 = sub( 31, q_D );
    4424    16201772 :         div_fx[1] = ISqrt32( D_fx[1], &exp1 );
    4425    16201772 :         move32();
    4426             :     }
    4427    20758785 :     q_div = sub( 31, s_max( exp, exp1 ) );
    4428             : 
    4429    20758785 :     div_fx[0] = L_shr( div_fx[0], sub( sub( 31, exp ), q_div ) ); // q_div
    4430    20758785 :     move32();
    4431    20758785 :     div_fx[1] = L_shr( div_fx[1], sub( sub( 31, exp1 ), q_div ) ); // q_div
    4432    20758785 :     move32();
    4433             : 
    4434             :     // 1310720000 = 10,000.0f in Q17
    4435    20758785 :     Word32 thresh = L_shl_sat( 1310720000, sub( q_div, Q17 ) ); // q_div
    4436    20758785 :     div_fx[0] = L_min( div_fx[0], thresh );                     // q_div
    4437    20758785 :     div_fx[1] = L_min( div_fx[1], thresh );                     // q_div
    4438             : 
    4439    20758785 :     matrixMul_fx( Are_fx, Aim_fx, &q_A, Ure_fx, Uim_fx, &q_U, tmpRe_fx, tmpIm_fx, &q_temp );
    4440             : 
    4441    20758785 :     exp = L_norm_arr( div_fx, BINAURAL_CHANNELS );
    4442    20758785 :     scale_sig32( div_fx, BINAURAL_CHANNELS, exp );
    4443    20758785 :     q_div = add( q_div, exp );
    4444             : 
    4445    62276355 :     FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ )
    4446             :     {
    4447   124552710 :         FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ )
    4448             :         {
    4449             :             Word64 W_tmp;
    4450             : 
    4451    83035140 :             W_tmp = W_mult0_32_32( tmpRe_fx[chA][chB], div_fx[chB] );
    4452    83035140 :             IF( W_tmp != 0 )
    4453             :             {
    4454    73017276 :                 Word16 hdrm = sub( W_norm( W_tmp ), 32 );
    4455    73017276 :                 tmpRe_fx[chA][chB] = W_shl_sat_l( W_tmp, hdrm );
    4456    73017276 :                 move32();
    4457    73017276 :                 hdrm_re[chA][chB] = add( add( q_temp, q_div ), hdrm );
    4458    73017276 :                 move16();
    4459             :             }
    4460             :             ELSE
    4461             :             {
    4462    10017864 :                 tmpRe_fx[chA][chB] = 0;
    4463    10017864 :                 move32();
    4464             :             }
    4465             : 
    4466    83035140 :             W_tmp = W_mult0_32_32( tmpIm_fx[chA][chB], div_fx[chB] );
    4467    83035140 :             IF( W_tmp != 0 )
    4468             :             {
    4469    51928110 :                 Word16 hdrm = sub( W_norm( W_tmp ), 32 );
    4470    51928110 :                 move16();
    4471    51928110 :                 tmpIm_fx[chA][chB] = W_shl_sat_l( W_tmp, hdrm );
    4472    51928110 :                 move32();
    4473    51928110 :                 hdrm_im[chA][chB] = add( add( q_temp, q_div ), hdrm );
    4474    51928110 :                 move16();
    4475             :             }
    4476             :             ELSE
    4477             :             {
    4478    31107030 :                 tmpIm_fx[chA][chB] = 0;
    4479    31107030 :                 move32();
    4480             :             }
    4481             :         }
    4482             :     }
    4483             : 
    4484    20758785 :     minimum_s( hdrm_re[0], i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ), &exp );
    4485    20758785 :     q_temp = exp;
    4486    20758785 :     move16();
    4487    20758785 :     minimum_s( hdrm_im[0], BINAURAL_CHANNELS * BINAURAL_CHANNELS, &exp );
    4488    20758785 :     q_temp = s_min( q_temp, exp );
    4489    20758785 :     q_temp = sub( q_temp, 1 );
    4490             : 
    4491    62276355 :     FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ )
    4492             :     {
    4493   124552710 :         FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ )
    4494             :         {
    4495    83035140 :             tmpRe_fx[chA][chB] = L_shr( tmpRe_fx[chA][chB], sub( hdrm_re[chA][chB], q_temp ) );
    4496    83035140 :             tmpIm_fx[chA][chB] = L_shr( tmpIm_fx[chA][chB], sub( hdrm_im[chA][chB], q_temp ) );
    4497    83035140 :             move32();
    4498    83035140 :             move32();
    4499             :         }
    4500             :     }
    4501             : 
    4502    20758785 :     matrixTransp2Mul_fx( tmpRe_fx, tmpIm_fx, &q_temp, Ure_fx, Uim_fx, &q_U,
    4503             :                          0 /*int Ascale*/,
    4504             :                          0 /*int Bscale*/,
    4505             :                          Pre_fx, Pim_fx, &q_P ); /* Nearest orthonormal matrix P to matrix A formulated */
    4506             : 
    4507             :     /* These are the final formulas of the JAES publication M = Ky P Kx^(-1) */
    4508             : #if ( BINAURAL_CHANNELS != 2 )
    4509             :     FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ )
    4510             :     {
    4511             :         FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ )
    4512             :         {
    4513             :             IF( Sx_fx[chB] == 0 )
    4514             :             {
    4515             :                 Pre_fx[chA][chB] = Mpy_32_32( Pre_fx[chA][chB], ONE_DIV_EPSILON_MANT );
    4516             :                 // q_Pre[chA][chB]  = add(sub(31, q_P), 31 - ONE_DIV_EPSILON_EXP);
    4517             :                 q_Pre[chA][chB] = sub( 62 - ONE_DIV_EPSILON_EXP, q_P );
    4518             : 
    4519             : 
    4520             :                 Pim_fx[chA][chB] = Mpy_32_32( Pim_fx[chA][chB], ONE_DIV_EPSILON_MANT );
    4521             :                 // q_Pim[chA][chB]  = add(sub(31, q_P), 31 - ONE_DIV_EPSILON_EXP);
    4522             :                 q_Pim[chA][chB] = sub( 62 - ONE_DIV_EPSILON_EXP, q_P );
    4523             :             }
    4524             :             ELSE
    4525             :             {
    4526             :                 Word16 Pre_shift, Pim_shift;
    4527             :                 temp = BASOP_Util_Add_Mant32Exp( Sx_fx[chB], sub( 31, q_Sx ), EPSILON_MANT, EPSILON_EXP, &exp_temp );
    4528             : 
    4529             :                 temp = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q30, temp, &exp );
    4530             :                 Pre_shift = norm_l( Pre_fx[chA][chB] );
    4531             :                 Pim_shift = norm_l( Pim_fx[chA][chB] );
    4532             :                 Pre_fx[chA][chB] = Mpy_32_32( L_shl( Pre_fx[chA][chB], Pre_shift ), temp );
    4533             :                 Pim_fx[chA][chB] = Mpy_32_32( L_shl( Pim_fx[chA][chB], Pim_shift ), temp );
    4534             :                 q_temp = add( sub( sub( q_P, exp ), sub( 31, Q30 ) ), exp_temp );
    4535             :                 q_Pre[chA][chB] = add( q_temp, Pre_shift );
    4536             :                 q_Pim[chA][chB] = add( q_temp, Pim_shift );
    4537             :             }
    4538             :             if ( Pre_fx[chA][chB] == 0 )
    4539             :             {
    4540             :                 q_Pre[chA][chB] = 31;
    4541             :                 move16();
    4542             :             }
    4543             :             if ( Pim_fx[chA][chB] == 0 )
    4544             :             {
    4545             :                 q_Pim[chA][chB] = 31;
    4546             :                 move16();
    4547             :             }
    4548             :             move32();
    4549             :             move32();
    4550             :             move16();
    4551             :             move16();
    4552             :         }
    4553             :     }
    4554             : #else
    4555             :     /* BINAURAL_CHANNEL == 2 */
    4556    62276355 :     FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ )
    4557             :     {
    4558    41517570 :         IF( Sx_fx[chB] == 0 )
    4559             :         {
    4560       98678 :             Pre_fx[0][chB] = Mpy_32_32( Pre_fx[0][chB], ONE_DIV_EPSILON_MANT );
    4561       98678 :             q_Pre[0][chB] = sub( 62 - ONE_DIV_EPSILON_EXP, q_P );
    4562       98678 :             Pim_fx[0][chB] = Mpy_32_32( Pim_fx[0][chB], ONE_DIV_EPSILON_MANT );
    4563       98678 :             q_Pim[0][chB] = sub( 62 - ONE_DIV_EPSILON_EXP, q_P );
    4564       98678 :             Pre_fx[1][chB] = Mpy_32_32( Pre_fx[1][chB], ONE_DIV_EPSILON_MANT );
    4565       98678 :             q_Pre[1][chB] = sub( 62 - ONE_DIV_EPSILON_EXP, q_P );
    4566       98678 :             Pim_fx[1][chB] = Mpy_32_32( Pim_fx[1][chB], ONE_DIV_EPSILON_MANT );
    4567       98678 :             q_Pim[1][chB] = sub( 62 - ONE_DIV_EPSILON_EXP, q_P );
    4568             :         }
    4569             :         ELSE
    4570             :         {
    4571             :             Word16 Pre_shift, Pim_shift;
    4572    41418892 :             temp = BASOP_Util_Add_Mant32Exp( Sx_fx[chB], sub( 31, q_Sx ), EPSILON_MANT, EPSILON_EXP, &exp_temp );
    4573    41418892 :             temp = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q30, temp, &exp );
    4574    41418892 :             q_temp = add( sub( sub( q_P, exp ), sub( 31, Q30 ) ), exp_temp );
    4575             : 
    4576    41418892 :             Pre_shift = norm_l( Pre_fx[0][chB] );
    4577    41418892 :             Pim_shift = norm_l( Pim_fx[0][chB] );
    4578    41418892 :             Pre_fx[0][chB] = Mpy_32_32( L_shl( Pre_fx[0][chB], Pre_shift ), temp );
    4579    41418892 :             Pim_fx[0][chB] = Mpy_32_32( L_shl( Pim_fx[0][chB], Pim_shift ), temp );
    4580    41418892 :             q_Pre[0][chB] = add( q_temp, Pre_shift );
    4581    41418892 :             q_Pim[0][chB] = add( q_temp, Pim_shift );
    4582             : 
    4583    41418892 :             Pre_shift = norm_l( Pre_fx[1][chB] );
    4584    41418892 :             Pim_shift = norm_l( Pim_fx[1][chB] );
    4585    41418892 :             Pre_fx[1][chB] = Mpy_32_32( L_shl( Pre_fx[1][chB], Pre_shift ), temp );
    4586    41418892 :             Pim_fx[1][chB] = Mpy_32_32( L_shl( Pim_fx[1][chB], Pim_shift ), temp );
    4587    41418892 :             q_Pre[1][chB] = add( q_temp, Pre_shift );
    4588    41418892 :             q_Pim[1][chB] = add( q_temp, Pim_shift );
    4589             :         }
    4590    41517570 :         if ( Pre_fx[0][chB] == 0 )
    4591             :         {
    4592     4615000 :             q_Pre[0][chB] = 31;
    4593     4615000 :             move16();
    4594             :         }
    4595    41517570 :         if ( Pim_fx[0][chB] == 0 )
    4596             :         {
    4597    15184481 :             q_Pim[0][chB] = 31;
    4598    15184481 :             move16();
    4599             :         }
    4600    41517570 :         if ( Pre_fx[1][chB] == 0 )
    4601             :         {
    4602     5396315 :             q_Pre[1][chB] = 31;
    4603     5396315 :             move16();
    4604             :         }
    4605    41517570 :         if ( Pim_fx[1][chB] == 0 )
    4606             :         {
    4607    15842885 :             q_Pim[1][chB] = 31;
    4608    15842885 :             move16();
    4609             :         }
    4610    41517570 :         move32();
    4611    41517570 :         move32();
    4612    41517570 :         move16();
    4613    41517570 :         move16();
    4614    41517570 :         move32();
    4615    41517570 :         move32();
    4616    41517570 :         move16();
    4617    41517570 :         move16();
    4618             :     }
    4619             : #endif
    4620    20758785 :     minimum_s( q_Pre[0], BINAURAL_CHANNELS * BINAURAL_CHANNELS, &exp );
    4621    20758785 :     q_P = s_min( q_P, exp );
    4622    20758785 :     minimum_s( q_Pim[0], BINAURAL_CHANNELS * BINAURAL_CHANNELS, &exp );
    4623    20758785 :     q_P = s_min( q_P, exp );
    4624             : 
    4625    62276355 :     FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ )
    4626             :     {
    4627   124552710 :         FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ )
    4628             :         {
    4629    83035140 :             Pre_fx[chA][chB] = L_shr( Pre_fx[chA][chB], sub( q_Pre[chA][chB], q_P ) ); // q_P
    4630    83035140 :             Pim_fx[chA][chB] = L_shr( Pim_fx[chA][chB], sub( q_Pim[chA][chB], q_P ) ); // q_P
    4631    83035140 :             move32();
    4632    83035140 :             move32();
    4633             :         }
    4634             :     }
    4635             : 
    4636    20758785 :     matrixMul_fx( KyRe_fx, KyIm_fx, &q_ky, Pre_fx, Pim_fx, &q_P, tmpRe_fx, tmpIm_fx, &q_temp );
    4637             : 
    4638    20758785 :     matrixTransp2Mul_fx( tmpRe_fx, tmpIm_fx, &q_temp, Uxre_fx, Uxim_fx, &q_Ux,
    4639             :                          1 /*int Ascale*/,
    4640             :                          0 /*int Bscale*/,
    4641             :                          Mre_fx, Mim_fx, q_M );
    4642    20758785 :     return;
    4643             : }
    4644             : 
    4645             : 
    4646    19796437 : static void getDirectPartGains_fx(
    4647             :     const Word16 bin,
    4648             :     Word16 aziDeg,
    4649             :     Word16 eleDeg,
    4650             :     Word32 *lRealp,
    4651             :     Word32 *lImagp,
    4652             :     Word32 *rRealp,
    4653             :     Word32 *rImagp,
    4654             :     const UWord8 renderStereoOutputInsteadOfBinaural,
    4655             :     Word32 Rmat[3][3], /*Q30*/
    4656             :     PARAMBIN_HRTF_GAIN_CACHE *gainCache,
    4657             :     const Word16 isHeadtracked )
    4658             : {
    4659             :     // float aziRad, eleRad;
    4660             :     Word32 y, mappedX;
    4661             :     Word16 aziRadMapped, A, A2, A3;
    4662    19796437 :     const Word16 LsAngleRad = 17157; // Q15
    4663    19796437 :     move16();
    4664             :     Word32 *ptr_sin, *ptr_cos;
    4665             :     Word32 sin_val, cos_val;
    4666             :     Word16 e_mappedX;
    4667             : 
    4668    19796437 :     ptr_sin = &sine_table_Q31[180]; // sin[x] = sine_table_Q31[180 + x]
    4669    19796437 :     ptr_cos = cosine_table_Q31;
    4670             : 
    4671    19796437 :     IF( renderStereoOutputInsteadOfBinaural ) /* In stereo (i.e. non-binaural) rendering mode */
    4672             :     {
    4673             :         /* Convert azi and ele to an azi value of the cone of confusion */
    4674             : 
    4675             :         // y = ( sinf( aziRad ) * cosf( eleRad ) );
    4676             : 
    4677     1569126 :         IF( GT_16( abs_s( eleDeg ), 180 ) )
    4678             :         {
    4679             :             // cos(180 + x) = -cos(x)
    4680           0 :             cos_val = -ptr_cos[sub( abs_s( eleDeg ), 180 )]; // Q31
    4681             :         }
    4682             :         ELSE
    4683             :         {
    4684     1569126 :             cos_val = ptr_cos[abs_s( eleDeg )]; // Q31
    4685             :         }
    4686     1569126 :         move32();
    4687             : 
    4688     1569126 :         IF( GT_16( aziDeg, 180 ) )
    4689             :         {
    4690             :             // sin(180 + x) = -sin(x)
    4691           0 :             sin_val = -ptr_sin[sub( aziDeg, 180 )]; // Q31
    4692             :         }
    4693     1569126 :         ELSE IF( LT_16( aziDeg, -180 ) )
    4694             :         {
    4695             :             // sin(-(180 + x)) = sin(180 + x) = sinx
    4696           0 :             sin_val = ptr_sin[sub( abs_s( aziDeg ), 180 )]; // Q31
    4697             :         }
    4698             :         ELSE
    4699             :         {
    4700     1569126 :             sin_val = ptr_sin[aziDeg]; // Q31
    4701             :         }
    4702     1569126 :         move32();
    4703             : 
    4704     1569126 :         y = Mpy_32_32( sin_val, cos_val ); // Q31
    4705     1569126 :         e_mappedX = 0;
    4706     1569126 :         move16();
    4707     1569126 :         mappedX = Sqrt32( L_max( 0, L_sub( ONE_IN_Q31, Mpy_32_32( y, y ) ) ), &e_mappedX );
    4708             : 
    4709     1569126 :         aziRadMapped = BASOP_util_atan2( y, mappedX, negate( e_mappedX ) ); // Q13
    4710             : 
    4711             :         /* Determine the real valued amplitude panning gains */
    4712     1569126 :         *lImagp = 0;
    4713     1569126 :         *rImagp = 0;
    4714     1569126 :         move32();
    4715     1569126 :         move32();
    4716     1569126 :         IF( GE_16( aziRadMapped, shr( LsAngleRad, 2 ) ) )
    4717             :         { /* Left side */
    4718      355280 :             *lRealp = ONE_IN_Q31;
    4719      355280 :             *rRealp = 0;
    4720      355280 :             move32();
    4721      355280 :             move32();
    4722             :         }
    4723     1213846 :         ELSE IF( LE_16( aziRadMapped, negate( shr( LsAngleRad, 2 ) ) ) )
    4724             :         { /* Right side */
    4725      565479 :             *lRealp = 0;
    4726      565479 :             *rRealp = ONE_IN_Q31;
    4727      565479 :             move32();
    4728      565479 :             move32();
    4729             :         }
    4730             :         ELSE /* Tangent panning law */
    4731             :         {
    4732             :             Word16 e_div, div, e_a, e_a3, temp_16_1, temp_16_2, e_num, e_den;
    4733      648367 :             div = BASOP_Util_Divide3232_Scale( y, mappedX, &e_div );
    4734      648367 :             e_div = sub( e_div, e_mappedX );
    4735             : 
    4736      648367 :             A = mult( div, INV_TAN30_FX );
    4737      648367 :             e_a = add( e_div, 1 );
    4738             : 
    4739      648367 :             e_num = BASOP_Util_Add_MantExp( A, e_a, -32767, 0, &temp_16_1 );
    4740      648367 :             e_den = BASOP_Util_Add_MantExp( A, e_a, 32767, 0, &temp_16_2 );
    4741      648367 :             IF( temp_16_2 <= 0 )
    4742             :             {
    4743           0 :                 temp_16_2 = 32;
    4744           0 :                 e_den = 0;
    4745           0 :                 move16();
    4746           0 :                 move16();
    4747             :             }
    4748      648367 :             A2 = BASOP_Util_Divide1616_Scale( temp_16_1, temp_16_2, &e_div );
    4749      648367 :             e_div = add( e_div, sub( e_num, e_den ) );
    4750             : 
    4751      648367 :             e_den = BASOP_Util_Add_MantExp( mult( A2, A2 ), add( e_div, e_div ), 32767, 0, &temp_16_2 );
    4752      648367 :             A3 = BASOP_Util_Divide1616_Scale( 32767, temp_16_2, &e_a3 );
    4753      648367 :             e_a3 = sub( e_a3, e_den );
    4754             :             // A3 = 1.0f / ( A2 * A2 + 1.0f );   // Q15
    4755      648367 :             Word32 temp_32 = L_shr( L_deposit_h( A3 ), sub( 0, e_a3 ) );
    4756      648367 :             Word16 temp_e = 0;
    4757      648367 :             e_a3 = 0;
    4758      648367 :             move16();
    4759      648367 :             move16();
    4760      648367 :             *lRealp = Sqrt32( temp_32, &e_a3 );
    4761      648367 :             *rRealp = Sqrt32( L_sub( ONE_IN_Q31, temp_32 ), &temp_e );
    4762      648367 :             *lRealp = L_shr( *lRealp, sub( 0, e_a3 ) );   // Q31
    4763      648367 :             *rRealp = L_shr( *rRealp, sub( 0, temp_e ) ); // Q31
    4764      648367 :             move32();
    4765      648367 :             move32();
    4766      648367 :             move32();
    4767      648367 :             move32();
    4768             :         }
    4769             : 
    4770             :         /* Scaling to have the same expected gain as for the HRTF rendering */
    4771     1569126 :         *lRealp = Mpy_32_32( *lRealp, SQRT2_FIXED ); // Q30
    4772     1569126 :         *rRealp = Mpy_32_32( *rRealp, SQRT2_FIXED ); // Q30
    4773             : 
    4774     1569126 :         *lRealp = L_shr( *lRealp, 2 ); // Q28
    4775     1569126 :         *rRealp = L_shr( *rRealp, 2 ); // Q28
    4776     1569126 :         move32();
    4777     1569126 :         move32();
    4778     1569126 :         move32();
    4779     1569126 :         move32();
    4780             :     }
    4781             :     ELSE /* In regular binaural rendering mode */
    4782             :     {
    4783    18227311 :         test();
    4784    18227311 :         IF( EQ_16( aziDeg, gainCache->azi ) && EQ_16( eleDeg, gainCache->ele ) )
    4785             :         {
    4786    10947758 :             hrtfShGetHrtf_fx( bin, aziDeg, eleDeg, lRealp, lImagp, rRealp, rImagp, gainCache, TRUE );
    4787             :         }
    4788             :         ELSE
    4789             :         {
    4790     7279553 :             gainCache->azi = aziDeg;
    4791     7279553 :             gainCache->ele = eleDeg;
    4792     7279553 :             move16();
    4793     7279553 :             move16();
    4794     7279553 :             IF( isHeadtracked )
    4795             :             {
    4796             :                 // Word32 aziDeg_32, eleDeg_32;
    4797     3269585 :                 rotateAziEle_fx( aziDeg, eleDeg, &aziDeg, &eleDeg, Rmat, 0 ); // need to be chnaged
    4798             :                                                                               // eleDeg = L_shr(eleDeg_32, 22);
    4799             :                                                                               // aziDeg = L_shr(aziDeg_32, 22);
    4800             :             }
    4801     7279553 :             hrtfShGetHrtf_fx( bin, aziDeg, eleDeg, lRealp, lImagp, rRealp, rImagp, gainCache, FALSE );
    4802             :         }
    4803             :     }
    4804             : 
    4805    19796437 :     return;
    4806             : }
    4807             : 
    4808    18227311 : static void hrtfShGetHrtf_fx(
    4809             :     const Word16 bin,
    4810             :     const Word16 aziDeg,
    4811             :     const Word16 eleDeg,
    4812             :     Word32 *lRealp,
    4813             :     Word32 *lImagp,
    4814             :     Word32 *rRealp,
    4815             :     Word32 *rImagp,
    4816             :     PARAMBIN_HRTF_GAIN_CACHE *gainCache,
    4817             :     const Word16 useCachedValue )
    4818             : {
    4819             :     Word16 k;
    4820             : 
    4821    18227311 :     *lRealp = 0;
    4822    18227311 :     *lImagp = 0;
    4823    18227311 :     *rRealp = 0;
    4824    18227311 :     *rImagp = 0;
    4825    18227311 :     move32();
    4826    18227311 :     move32();
    4827    18227311 :     move32();
    4828    18227311 :     move32();
    4829             : 
    4830    18227311 :     IF( useCachedValue )
    4831             :     {
    4832             :         Word32 *shVec;
    4833    10947758 :         shVec = gainCache->shVec_fx;
    4834             : 
    4835   186111886 :         FOR( k = 0; k < HRTF_SH_CHANNELS; k++ )
    4836             :         {
    4837   175164128 :             *lRealp = Madd_32_16( *lRealp, shVec[k], hrtfShCoeffsRe_fx[0][k][bin] ); // Q28
    4838   175164128 :             *lImagp = Madd_32_16( *lImagp, shVec[k], hrtfShCoeffsIm_fx[0][k][bin] ); // Q28
    4839   175164128 :             *rRealp = Madd_32_16( *rRealp, shVec[k], hrtfShCoeffsRe_fx[1][k][bin] ); // Q28
    4840   175164128 :             *rImagp = Madd_32_16( *rImagp, shVec[k], hrtfShCoeffsIm_fx[1][k][bin] ); // Q28
    4841   175164128 :             move32();
    4842   175164128 :             move32();
    4843   175164128 :             move32();
    4844   175164128 :             move32();
    4845             :         }
    4846             :     }
    4847             :     ELSE
    4848             :     {
    4849             :         Word32 shVec[HRTF_SH_CHANNELS];
    4850             : 
    4851     7279553 :         ivas_dirac_dec_get_response_fx( aziDeg,
    4852             :                                         eleDeg,
    4853             :                                         shVec,
    4854             :                                         HRTF_SH_ORDER,
    4855             :                                         Q29 );
    4856             : 
    4857   123752401 :         FOR( k = 0; k < HRTF_SH_CHANNELS; k++ )
    4858             :         {
    4859   116472848 :             *lRealp = Madd_32_16( *lRealp, shVec[k], hrtfShCoeffsRe_fx[0][k][bin] ); // Q28
    4860   116472848 :             *lImagp = Madd_32_16( *lImagp, shVec[k], hrtfShCoeffsIm_fx[0][k][bin] ); // Q28
    4861   116472848 :             *rRealp = Madd_32_16( *rRealp, shVec[k], hrtfShCoeffsRe_fx[1][k][bin] ); // Q28
    4862   116472848 :             *rImagp = Madd_32_16( *rImagp, shVec[k], hrtfShCoeffsIm_fx[1][k][bin] ); // Q28
    4863   116472848 :             gainCache->shVec_fx[k] = shVec[k];                                       // Q29
    4864   116472848 :             move32();
    4865   116472848 :             move32();
    4866   116472848 :             move32();
    4867   116472848 :             move32();
    4868   116472848 :             move32();
    4869             :         }
    4870             :     }
    4871             : 
    4872    18227311 :     return;
    4873             : }
    4874             : 
    4875             : /*-------------------------------------------------------------------------
    4876             :  * configure_reqularization_factor()
    4877             :  *
    4878             :  * Configure regularization factor for the mixing matrix generation of the
    4879             :  * parametric binauralizer using IVAS codec format and current bitrate.
    4880             :  *------------------------------------------------------------------------*/
    4881             : 
    4882             : /*! r: Configured reqularization factor value */
    4883             : 
    4884        3442 : Word16 configure_reqularization_factor_fx(
    4885             :     const IVAS_FORMAT ivas_format, /* i  : IVAS format          */
    4886             :     const Word32 ivas_total_brate  /* i  : IVAS total bitrate  */
    4887             : )
    4888             : {
    4889             :     Word16 reqularizationFactor;
    4890        3442 :     reqularizationFactor = 16384; /* Default value */ /*Q14*/
    4891        3442 :     move16();
    4892             : 
    4893        3442 :     IF( EQ_32( ivas_format, MASA_FORMAT ) )
    4894             :     {
    4895        1706 :         IF( GE_32( ivas_total_brate, IVAS_160k ) )
    4896             :         {
    4897         142 :             reqularizationFactor = 6553; /*Q14*/
    4898         142 :             move16();
    4899             :         }
    4900        1564 :         ELSE IF( EQ_32( ivas_total_brate, IVAS_128k ) )
    4901             :         {
    4902          88 :             reqularizationFactor = 8192; /*Q14*/
    4903          88 :             move16();
    4904             :         }
    4905        1476 :         ELSE IF( EQ_32( ivas_total_brate, IVAS_96k ) )
    4906             :         {
    4907          96 :             reqularizationFactor = 9830; /*Q14*/
    4908          96 :             move16();
    4909             :         }
    4910        1380 :         ELSE IF( GE_32( ivas_total_brate, IVAS_64k ) )
    4911             :         {
    4912         202 :             reqularizationFactor = 13107; /*Q14*/
    4913         202 :             move16();
    4914             :         }
    4915             :         ELSE
    4916             :         {
    4917        1178 :             reqularizationFactor = 16384; /*Q14*/
    4918        1178 :             move16();
    4919             :         }
    4920             :     }
    4921             : 
    4922        3442 :     IF( EQ_32( ivas_format, MC_FORMAT ) ) /* This is always McMASA for parametric binauralizer. */
    4923             :     {
    4924         221 :         IF( GE_32( ivas_total_brate, IVAS_96k ) )
    4925             :         {
    4926           0 :             reqularizationFactor = 6553; /*Q14*/
    4927           0 :             move16();
    4928             :         }
    4929         221 :         ELSE IF( GE_32( ivas_total_brate, IVAS_80k ) )
    4930             :         {
    4931           2 :             reqularizationFactor = 8192; /*Q14*/
    4932           2 :             move16();
    4933             :         }
    4934         219 :         ELSE IF( GE_32( ivas_total_brate, IVAS_64k ) )
    4935             :         {
    4936           8 :             reqularizationFactor = 11468; /*Q14*/
    4937           8 :             move16();
    4938             :         }
    4939         211 :         ELSE IF( GE_32( ivas_total_brate, IVAS_48k ) )
    4940             :         {
    4941          13 :             reqularizationFactor = 13107; /*Q14*/
    4942          13 :             move16();
    4943             :         }
    4944             :         ELSE
    4945             :         {
    4946         198 :             reqularizationFactor = 16384; /*Q14*/
    4947         198 :             move16();
    4948             :         }
    4949             :     }
    4950             : 
    4951             :     /* For SBA and parametric ISM, currently in default value of 1.0f. */
    4952             : 
    4953        3442 :     return reqularizationFactor;
    4954             : }
    4955             : 
    4956             : /*-------------------------------------------------------------------*
    4957             :  * ivas_omasa_preProcessStereoTransportsForMovedObjects_fx()
    4958             :  *
    4959             :  *
    4960             :  *-------------------------------------------------------------------*/
    4961             : 
    4962        5029 : void ivas_omasa_preProcessStereoTransportsForMovedObjects_fx(
    4963             :     Decoder_Struct *st_ivas,
    4964             :     Word32 inRe_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*cldfb_buf_q*/
    4965             :     Word32 inIm_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*cldfb_buf_q*/
    4966             :     Word16 *cldfb_buf_q,
    4967             :     const Word16 nBins,
    4968             :     const Word16 subframe )
    4969             : {
    4970             :     Word16 bin, ch, inCh, outCh, ismDirIndex, slot;
    4971             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
    4972             :     MASA_ISM_DATA_HANDLE hMasaIsmData;
    4973             :     UWord8 enableCentering;
    4974             :     Word16 dirac_read_idx;
    4975             :     Word16 nSlots;
    4976             : 
    4977        5029 :     hSpatParamRendCom = st_ivas->hSpatParamRendCom;
    4978        5029 :     hMasaIsmData = st_ivas->hMasaIsmData;
    4979             : 
    4980        5029 :     test();
    4981        5029 :     test();
    4982        5029 :     IF( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_FOA ) || EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_HOA2 ) || EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_HOA3 ) )
    4983             :     {
    4984        1216 :         enableCentering = 0;
    4985        1216 :         move16();
    4986             :     }
    4987             :     ELSE
    4988             :     {
    4989        3813 :         enableCentering = 1;
    4990        3813 :         move16();
    4991             :     }
    4992             : 
    4993             :     /* Bypass processing until first object is moved */
    4994        5029 :     IF( hMasaIsmData->objectsMoved == 0 )
    4995             :     {
    4996       21118 :         FOR( ismDirIndex = 0; ismDirIndex < hSpatParamRendCom->numIsmDirections; ismDirIndex++ )
    4997             :         {
    4998       16089 :             if ( hMasaIsmData->ism_is_edited[ismDirIndex] )
    4999             :             {
    5000           0 :                 hMasaIsmData->objectsMoved = 1;
    5001           0 :                 move16();
    5002             :             }
    5003             :         }
    5004        5029 :         IF( hMasaIsmData->objectsMoved == 0 )
    5005             :         {
    5006             :             /* No objects have moved so far */
    5007        5029 :             return;
    5008             :         }
    5009             :     }
    5010             : 
    5011             :     /* Perform object-movement based processing */
    5012           0 :     nSlots = hSpatParamRendCom->subframe_nbslots[subframe];
    5013           0 :     move16();
    5014           0 :     dirac_read_idx = hSpatParamRendCom->render_to_md_map[subframe];
    5015           0 :     move16();
    5016             : 
    5017           0 :     FOR( bin = 0; bin < nBins; bin++ )
    5018             :     {
    5019             :         Word16 ismPreprocMtxNew_fx[2][2];
    5020             :         Word16 ismPreprocMtxIncrement_fx[2][2];
    5021             :         Word16 eneMove_fx[2];
    5022             :         Word16 enePreserve_fx[2];
    5023             :         Word16 ismRatioAcc_fx;
    5024             :         Word32 subframeEne_fx;
    5025             :         Word32 Enes_fx[2];
    5026             :         Word16 normEnes_fx[2];
    5027             :         Word16 remainderNormEne_fx;
    5028           0 :         Word16 normEnes_q_fx[2], temp_q = 0;
    5029             :         Word16 eneMove_q_fx[2], enePreserve_q_fx[2], temp1;
    5030             :         Word32 temp;
    5031             : 
    5032           0 :         set16_fx( ismPreprocMtxNew_fx[0], 0, 2 );
    5033           0 :         set16_fx( ismPreprocMtxNew_fx[1], 0, 2 );
    5034           0 :         set16_fx( ismPreprocMtxIncrement_fx[0], 0, 2 );
    5035           0 :         set16_fx( ismPreprocMtxIncrement_fx[1], 0, 2 );
    5036           0 :         set16_fx( eneMove_fx, 0, 2 );
    5037           0 :         set16_fx( enePreserve_fx, 0, 2 );
    5038           0 :         ismRatioAcc_fx = 0;
    5039           0 :         move16();
    5040           0 :         subframeEne_fx = 0;
    5041           0 :         move32();
    5042           0 :         set16_fx( normEnes_fx, 0, 2 );
    5043           0 :         set32_fx( Enes_fx, 0, 2 );
    5044           0 :         set16_fx( normEnes_q_fx, Q31, 2 );
    5045           0 :         set16_fx( eneMove_q_fx, Q31, 2 );
    5046           0 :         set16_fx( enePreserve_q_fx, Q31, 2 );
    5047             : 
    5048             :         /* Determine transport normalized energies and subframe energy */
    5049           0 :         FOR( slot = 0; slot < nSlots; slot++ )
    5050             :         {
    5051           0 :             FOR( ch = 0; ch < 2; ch++ )
    5052             :             {
    5053           0 :                 Enes_fx[ch] = L_add( Enes_fx[ch], Mpy_32_32( inRe_fx[ch][slot][bin], inRe_fx[ch][slot][bin] ) ); // Q = *cldfb_buf_q + *cldfb_buf_q - 31 = Q-19
    5054           0 :                 move32();
    5055           0 :                 Enes_fx[ch] = L_add( Enes_fx[ch], Mpy_32_32( inIm_fx[ch][slot][bin], inIm_fx[ch][slot][bin] ) ); // Q = *cldfb_buf_q + *cldfb_buf_q - 31 = Q-19
    5056           0 :                 move32();
    5057             :             }
    5058             : 
    5059           0 :             subframeEne_fx = L_add( Enes_fx[0], Enes_fx[1] ); // Q = *cldfb_buf_q + *cldfb_buf_q - 31 = Q-19
    5060             : 
    5061           0 :             IF( subframeEne_fx != 0 )
    5062             :             {
    5063           0 :                 normEnes_fx[0] = BASOP_Util_Divide3232_Scale( Enes_fx[0], subframeEne_fx, &temp_q );
    5064           0 :                 move32();
    5065           0 :                 normEnes_fx[0] = shr( normEnes_fx[0], sub( sub( 15, temp_q ), Q12 ) ); // Q12
    5066           0 :                 move32();
    5067           0 :                 normEnes_fx[1] = BASOP_Util_Divide3232_Scale( Enes_fx[1], subframeEne_fx, &temp_q );
    5068           0 :                 move32();
    5069           0 :                 normEnes_fx[1] = shr( normEnes_fx[1], sub( sub( 15, temp_q ), Q12 ) ); // Q12
    5070           0 :                 move32();
    5071             :             }
    5072             :             ELSE
    5073             :             {
    5074           0 :                 normEnes_fx[0] = BASOP_Util_Divide3232_Scale( Enes_fx[0], EPSILON_FX, &temp_q );
    5075           0 :                 move32();
    5076           0 :                 normEnes_fx[0] = shr( normEnes_fx[0], sub( sub( 15, temp_q ), Q12 ) ); // Q12
    5077           0 :                 move32();
    5078           0 :                 normEnes_fx[1] = BASOP_Util_Divide3232_Scale( Enes_fx[1], EPSILON_FX, &temp_q );
    5079           0 :                 move32();
    5080           0 :                 normEnes_fx[1] = shr( normEnes_fx[1], sub( sub( 15, temp_q ), Q12 ) ); // Q12
    5081           0 :                 move32();
    5082             :             }
    5083             : 
    5084             : 
    5085             :             /* For each ismDir, formulate a mix-matrix that moves object audio signals between
    5086             :              * left and right channels when needed. Make a combined matrix by a ratio-weighted sum */
    5087           0 :             FOR( ismDirIndex = 0; ismDirIndex < hSpatParamRendCom->numIsmDirections; ismDirIndex++ )
    5088             :             {
    5089             :                 Word16 panGainsOut_fx[2];
    5090             :                 Word16 panGainsIn_fx[2];
    5091             :                 Word16 ratio;
    5092             :                 Word16 panEnesOut_fx[2];
    5093             :                 Word16 panEnesIn_fx[2];
    5094             :                 Word16 centeringFactor_fx;
    5095             : 
    5096           0 :                 ratio = extract_l( hMasaIsmData->energy_ratio_ism_fx[ismDirIndex][dirac_read_idx][bin] ); // Q14
    5097           0 :                 ismRatioAcc_fx = add( ismRatioAcc_fx, ratio );
    5098             : 
    5099             :                 /* Get input and output panning gains */
    5100           0 :                 ivas_get_stereo_panning_gains_fx( hMasaIsmData->azimuth_ism[ismDirIndex][dirac_read_idx],
    5101           0 :                                                   hMasaIsmData->elevation_ism[ismDirIndex][dirac_read_idx],
    5102             :                                                   panGainsIn_fx );
    5103             : 
    5104           0 :                 IF( hMasaIsmData->ism_is_edited[ismDirIndex] )
    5105             :                 {
    5106           0 :                     ivas_get_stereo_panning_gains_fx( hMasaIsmData->azimuth_ism_edited[ismDirIndex],
    5107           0 :                                                       hMasaIsmData->elevation_ism_edited[ismDirIndex],
    5108             :                                                       panGainsOut_fx );
    5109             :                 }
    5110             :                 ELSE
    5111             :                 {
    5112             :                     /* When not edited, input and output pan gains are the same */
    5113           0 :                     FOR( ch = 0; ch < 2; ch++ )
    5114             :                     {
    5115           0 :                         panGainsOut_fx[ch] = panGainsIn_fx[ch];
    5116           0 :                         move16();
    5117             :                     }
    5118             :                 }
    5119             : 
    5120             :                 /* Determine pan enes */
    5121           0 :                 FOR( ch = 0; ch < 2; ch++ )
    5122             :                 {
    5123           0 :                     panEnesOut_fx[ch] = mult( panGainsOut_fx[ch], panGainsOut_fx[ch] ); // Q15
    5124           0 :                     move16();
    5125           0 :                     panEnesIn_fx[ch] = mult( panGainsIn_fx[ch], panGainsIn_fx[ch] ); // Q15
    5126           0 :                     move16();
    5127             :                 }
    5128             : 
    5129           0 :                 IF( enableCentering )
    5130             :                 {
    5131           0 :                     centeringFactor_fx = s_max( 0, sub( mult( shl( 2, 13 ), abs_s( sub( panEnesIn_fx[0], panEnesOut_fx[0] ) ) ), ONE_IN_Q13 ) ); // Q13
    5132           0 :                     FOR( ch = 0; ch < 2; ch++ )
    5133             :                     {
    5134           0 :                         panEnesOut_fx[ch] = mult( panEnesOut_fx[ch], sub( ONE_IN_Q13, centeringFactor_fx ) ); // Q13
    5135           0 :                         move16();
    5136           0 :                         panEnesOut_fx[ch] = add( panEnesOut_fx[ch], shr( centeringFactor_fx, 1 ) ); // Q13
    5137           0 :                         move16();
    5138             :                     }
    5139             :                 }
    5140             : 
    5141           0 :                 FOR( ch = 0; ch < 2; ch++ )
    5142             :                 {
    5143             :                     Word16 eneMoveThis_fx;
    5144             :                     Word16 enePreserveThis_fx;
    5145             : 
    5146           0 :                     eneMoveThis_fx = s_max( 0, sub( shr( panEnesIn_fx[ch], 2 ), panEnesOut_fx[ch] ) ); // Q13
    5147           0 :                     enePreserveThis_fx = sub( shr( panEnesIn_fx[ch], 2 ), eneMoveThis_fx );            // Q13
    5148             : 
    5149           0 :                     eneMove_fx[ch] = mult( ratio, eneMoveThis_fx ); // Q = 14 + 13 - 15 = 12
    5150           0 :                     move16();
    5151           0 :                     enePreserve_fx[ch] = mult( ratio, enePreserveThis_fx ); // Q = 14 + 13 - 15 = 12
    5152           0 :                     move16();
    5153             : 
    5154             :                     /* Subtract object parts from normEnes */
    5155           0 :                     normEnes_fx[ch] = sub( normEnes_fx[ch], shr( mult( panEnesIn_fx[ch], ratio ), 2 ) ); // Q12
    5156           0 :                     move16();
    5157             :                 }
    5158             :             }
    5159             : 
    5160             :             /* Any remaining (non-object) energy is set to be preserved at both channels */
    5161           0 :             remainderNormEne_fx = s_max( 0, sub( sub( shr( sub( ONE_IN_Q14, ismRatioAcc_fx ), Q14 - Q12 ), normEnes_fx[0] ), normEnes_fx[1] ) ); // Q12
    5162             : 
    5163           0 :             FOR( ch = 0; ch < 2; ch++ )
    5164             :             {
    5165           0 :                 enePreserve_fx[ch] = add( enePreserve_fx[ch], s_max( 0, add( enePreserve_fx[ch], shr( remainderNormEne_fx, 1 ) ) ) ); // Q12
    5166           0 :                 move16();
    5167             :             }
    5168             : 
    5169             :             /* Temporally average energy moving and preserving, and generate the transport signal preprocessing matrix */
    5170           0 :             FOR( ch = 0; ch < 2; ch++ )
    5171             :             {
    5172             :                 Word32 normVal_fx;
    5173           0 :                 hMasaIsmData->eneMoveIIR_fx[ch][bin] = Mpy_32_16_1( hMasaIsmData->eneMoveIIR_fx[ch][bin], STEREO_PREPROCESS_IIR_FACTOR_Q15 );
    5174           0 :                 move32();
    5175           0 :                 temp = Mpy_32_16_1( subframeEne_fx, eneMove_fx[ch] );
    5176           0 :                 hMasaIsmData->eneMoveIIR_fx[ch][bin] = L_add( hMasaIsmData->eneMoveIIR_fx[ch][bin], temp ); // Q = *cldfb_buf_q + *cldfb_buf_q - 34 = Q-22
    5177           0 :                 move32();
    5178             : 
    5179           0 :                 hMasaIsmData->enePreserveIIR_fx[ch][bin] = Mpy_32_16_1( hMasaIsmData->enePreserveIIR_fx[ch][bin], STEREO_PREPROCESS_IIR_FACTOR_Q15 );
    5180           0 :                 move32();
    5181           0 :                 temp = Mpy_32_16_1( subframeEne_fx, enePreserve_fx[ch] );
    5182           0 :                 hMasaIsmData->enePreserveIIR_fx[ch][bin] = L_add( hMasaIsmData->enePreserveIIR_fx[ch][bin], temp ); // Q = *cldfb_buf_q + *cldfb_buf_q - 34 = Q-22
    5183           0 :                 move32();
    5184             : 
    5185           0 :                 normVal_fx = L_add( hMasaIsmData->eneMoveIIR_fx[ch][bin], hMasaIsmData->enePreserveIIR_fx[ch][bin] );
    5186           0 :                 IF( normVal_fx != 0 )
    5187             :                 {
    5188             : 
    5189           0 :                     temp1 = BASOP_Util_Divide3232_Scale( hMasaIsmData->enePreserveIIR_fx[ch][bin], normVal_fx, &temp_q );
    5190           0 :                     ismPreprocMtxNew_fx[ch][ch] = Sqrt16( temp1, &temp_q );
    5191           0 :                     move16();
    5192           0 :                     ismPreprocMtxNew_fx[ch][ch] = shl( ismPreprocMtxNew_fx[ch][ch], temp_q ); // Q15
    5193           0 :                     move16();
    5194           0 :                     temp1 = BASOP_Util_Divide3232_Scale( hMasaIsmData->eneMoveIIR_fx[ch][bin], normVal_fx, &temp_q );
    5195           0 :                     ismPreprocMtxNew_fx[sub( 1, ch )][ch] = Sqrt16( temp1, &temp_q );
    5196           0 :                     move16();
    5197           0 :                     ismPreprocMtxNew_fx[sub( 1, ch )][ch] = shl( ismPreprocMtxNew_fx[sub( 1, ch )][ch], temp_q ); // Q15
    5198           0 :                     move16();
    5199             :                 }
    5200             :                 ELSE
    5201             :                 {
    5202           0 :                     ismPreprocMtxNew_fx[ch][ch] = 0;
    5203           0 :                     move16();
    5204           0 :                     ismPreprocMtxNew_fx[sub( 1, ch )][ch] = 0;
    5205           0 :                     move16();
    5206             :                 }
    5207             :             }
    5208             : 
    5209             :             /* Get increment value for temporal interpolation */
    5210           0 :             FOR( inCh = 0; inCh < 2; inCh++ )
    5211             :             {
    5212           0 :                 FOR( outCh = 0; outCh < 2; outCh++ )
    5213           0 :                 ismPreprocMtxIncrement_fx[outCh][inCh] = BASOP_Util_Divide1616_Scale( sub( ismPreprocMtxNew_fx[outCh][inCh], hMasaIsmData->ismPreprocMatrix_fx[outCh][inCh][bin] ), nSlots, &temp_q );
    5214           0 :                 move16();
    5215           0 :                 ismPreprocMtxIncrement_fx[outCh][inCh] = shl( ismPreprocMtxIncrement_fx[outCh][inCh], temp_q ); // Q15
    5216           0 :                 move16();
    5217             :             }
    5218             :         }
    5219             : 
    5220             :         /* Mix signals */
    5221           0 :         FOR( slot = 0; slot < nSlots; slot++ )
    5222             :         {
    5223           0 :             Word16 eqVal_fx = 0;
    5224           0 :             Word16 eqVal_q_fx = 0;
    5225           0 :             move16();
    5226           0 :             move16();
    5227             :             Word32 outSlotRe_fx[2];
    5228             :             Word32 outSlotIm_fx[2];
    5229             : 
    5230           0 :             set_zero_fx( outSlotRe_fx, 2 );
    5231           0 :             set_zero_fx( outSlotIm_fx, 2 );
    5232             : 
    5233           0 :             FOR( outCh = 0; outCh < 2; outCh++ )
    5234             :             {
    5235           0 :                 FOR( inCh = 0; inCh < 2; inCh++ )
    5236             :                 {
    5237           0 :                     hMasaIsmData->ismPreprocMatrix_fx[outCh][inCh][bin] = add( hMasaIsmData->ismPreprocMatrix_fx[outCh][inCh][bin], ismPreprocMtxIncrement_fx[outCh][inCh] ); // Q = 15
    5238           0 :                     move16();
    5239           0 :                     outSlotRe_fx[outCh] = Mpy_32_16_1( inRe_fx[inCh][slot][bin], hMasaIsmData->ismPreprocMatrix_fx[outCh][inCh][bin] ); // Q = *cldfb_buf_q;
    5240           0 :                     move32();
    5241           0 :                     outSlotIm_fx[outCh] = Mpy_32_16_1( inIm_fx[inCh][slot][bin], hMasaIsmData->ismPreprocMatrix_fx[outCh][inCh][bin] ); // Q = *cldfb_buf_q;
    5242           0 :                     move32();
    5243             :                 }
    5244             :             }
    5245             : 
    5246             :             /* IIR average the energy measures and determine and apply energy-preserving equalizer */
    5247           0 :             hMasaIsmData->preprocEneTarget_fx[bin] = Mpy_32_16_1( hMasaIsmData->preprocEneTarget_fx[bin], STEREO_PREPROCESS_IIR_FACTOR_Q15 );
    5248           0 :             move32();
    5249           0 :             hMasaIsmData->preprocEneRealized_fx[bin] = Mpy_32_16_1( hMasaIsmData->preprocEneRealized_fx[bin], STEREO_PREPROCESS_IIR_FACTOR_Q15 );
    5250           0 :             move32();
    5251           0 :             FOR( ch = 0; ch < 2; ch++ )
    5252             :             {
    5253           0 :                 hMasaIsmData->preprocEneTarget_fx[bin] = L_add( hMasaIsmData->preprocEneTarget_fx[bin], Madd_32_32( Mpy_32_32( inRe_fx[ch][slot][bin], inRe_fx[ch][slot][bin] ), inIm_fx[ch][slot][bin], inIm_fx[ch][slot][bin] ) ); // Q= *cldfb_buf_q + *cldfb_buf_q - 31 = Q-19
    5254           0 :                 move32();
    5255           0 :                 hMasaIsmData->preprocEneRealized_fx[bin] = L_add( hMasaIsmData->preprocEneRealized_fx[bin], Madd_32_32( Mpy_32_32( outSlotRe_fx[ch], outSlotRe_fx[ch] ), outSlotIm_fx[ch], outSlotIm_fx[ch] ) ); // Q= *cldfb_buf_q + *cldfb_buf_q - 31 = Q-19
    5256           0 :                 move32();
    5257             :             }
    5258           0 :             temp1 = BASOP_Util_Divide3232_Scale( hMasaIsmData->preprocEneTarget_fx[bin], L_max( EPSILON_FX, hMasaIsmData->preprocEneRealized_fx[bin] ), &eqVal_q_fx );
    5259           0 :             eqVal_fx = Sqrt16( temp1, &eqVal_q_fx );
    5260           0 :             temp1 = 4 << Q12; // Q12
    5261           0 :             move16();
    5262           0 :             IF( LT_16( eqVal_q_fx, Q12 ) )
    5263             :             {
    5264           0 :                 IF( GT_16( eqVal_fx, shr( temp1, sub( Q12, eqVal_q_fx ) ) ) )
    5265             :                 {
    5266           0 :                     eqVal_fx = temp1;
    5267           0 :                     move16();
    5268           0 :                     eqVal_q_fx = Q12;
    5269           0 :                     move16();
    5270             :                 }
    5271             :             }
    5272             :             ELSE
    5273             :             {
    5274           0 :                 if ( GT_16( shr( eqVal_fx, sub( eqVal_q_fx, Q12 ) ), temp1 ) )
    5275             :                 {
    5276           0 :                     eqVal_fx = temp1; // eqVal_q_fx
    5277           0 :                     move16();
    5278             :                 }
    5279             :             }
    5280             : 
    5281           0 :             FOR( ch = 0; ch < 2; ch++ )
    5282             :             {
    5283           0 :                 inRe_fx[ch][slot][bin] = Mpy_32_16_1( outSlotRe_fx[ch], eqVal_fx );
    5284           0 :                 move32();
    5285           0 :                 inIm_fx[ch][slot][bin] = Mpy_32_16_1( outSlotIm_fx[ch], eqVal_fx );
    5286           0 :                 move32();
    5287             :             }
    5288           0 :             *cldfb_buf_q = sub( add( *cldfb_buf_q, eqVal_q_fx ), 15 );
    5289           0 :             move16();
    5290             :         }
    5291             :     }
    5292             : 
    5293           0 :     return;
    5294             : }
    5295             : 
    5296             : 
    5297        7200 : static void ivas_masa_ext_rend_parambin_internal_fx(
    5298             :     MASA_EXT_REND_HANDLE hMasaExtRend,
    5299             :     COMBINED_ORIENTATION_HANDLE hCombinedOrientationData,
    5300             :     Word32 *output_fx[], /* Q11*/
    5301             :     const Word16 subframe )
    5302             : {
    5303             : 
    5304             :     DIRAC_DEC_BIN_HANDLE hDiracDecBin;
    5305             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
    5306             :     PARAMBIN_REND_CONFIG config_data;
    5307             :     Word16 slot, ch, numInChannels;
    5308             :     Word16 max_band_decorr;
    5309             :     Word16 nBins;
    5310             :     Word16 i, j;
    5311             :     Word16 nchan_transport;
    5312             :     Word16 q_mat;
    5313        7200 :     hDiracDecBin = hMasaExtRend->hDiracDecBin;
    5314        7200 :     hSpatParamRendCom = hMasaExtRend->hSpatParamRendCom;
    5315             : 
    5316             :     Word32 Cldfb_RealBuffer_in_fx[6][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
    5317             :     Word32 Cldfb_ImagBuffer_in_fx[6][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
    5318             : 
    5319       50400 :     FOR( i = 0; i < 6; i++ )
    5320             :     {
    5321      216000 :         FOR( j = 0; j < CLDFB_SLOTS_PER_SUBFRAME; j++ )
    5322             :         {
    5323      172800 :             set32_fx( Cldfb_RealBuffer_in_fx[i][j], 0, CLDFB_NO_CHANNELS_MAX );
    5324      172800 :             set32_fx( Cldfb_ImagBuffer_in_fx[i][j], 0, CLDFB_NO_CHANNELS_MAX );
    5325             :         }
    5326             :     }
    5327             :     Word32 Rmat_fx[3][3];
    5328             : 
    5329        7200 :     hDiracDecBin = hMasaExtRend->hDiracDecBin;
    5330        7200 :     assert( hDiracDecBin );
    5331        7200 :     hSpatParamRendCom = hMasaExtRend->hSpatParamRendCom;
    5332        7200 :     nBins = hSpatParamRendCom->num_freq_bands;
    5333             : 
    5334             :     /* Setup internal config. MASA EXT renderer is quite strict. */
    5335        7200 :     config_data.separateCenterChannelRendering = 0;
    5336        7200 :     move16();
    5337        7200 :     config_data.ivas_format = MASA_FORMAT;
    5338        7200 :     move32();
    5339        7200 :     config_data.mc_mode = MC_MODE_NONE;
    5340        7200 :     move32();
    5341        7200 :     config_data.ivas_total_brate = IVAS_512k; /* Maximum bitrate set for external renderer */
    5342        7200 :     move32();
    5343        7200 :     config_data.nchan_transport = hMasaExtRend->nchan_input;
    5344        7200 :     move16();
    5345        7200 :     config_data.qualityBasedSmFactor_fx = ONE_IN_Q31;
    5346        7200 :     move32();
    5347        7200 :     IF( EQ_16( hMasaExtRend->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) )
    5348             :     {
    5349           0 :         config_data.processReverb = 1;
    5350           0 :         move16();
    5351             :     }
    5352             :     ELSE
    5353             :     {
    5354        7200 :         config_data.processReverb = 0;
    5355        7200 :         move16();
    5356             :     }
    5357        7200 :     config_data.ism_mode = ISM_MODE_NONE;
    5358        7200 :     move32();
    5359             : 
    5360             :     /* Set nchan_transport to number of transport channels in MASA input */
    5361        7200 :     nchan_transport = hMasaExtRend->nchan_input;
    5362        7200 :     move16();
    5363             : 
    5364             :     /* The input channel number at this processing function (not nchan_transport) */
    5365        7200 :     numInChannels = BINAURAL_CHANNELS;
    5366        7200 :     move16();
    5367             : 
    5368        7200 :     Rmat_fx[0][0] = ONE_IN_Q30;
    5369        7200 :     Rmat_fx[0][1] = 0;
    5370        7200 :     Rmat_fx[0][2] = 0;
    5371        7200 :     move32();
    5372        7200 :     move32();
    5373        7200 :     move32();
    5374             : 
    5375        7200 :     Rmat_fx[1][0] = 0;
    5376        7200 :     Rmat_fx[1][1] = ONE_IN_Q30;
    5377        7200 :     Rmat_fx[1][2] = 0;
    5378        7200 :     move32();
    5379        7200 :     move32();
    5380        7200 :     move32();
    5381             : 
    5382        7200 :     Rmat_fx[2][0] = 0;
    5383        7200 :     Rmat_fx[2][1] = 0;
    5384        7200 :     Rmat_fx[2][2] = ONE_IN_Q30;
    5385        7200 :     move32();
    5386        7200 :     move32();
    5387        7200 :     move32();
    5388             : 
    5389             :     /* CLDFB Analysis of input */
    5390             : 
    5391       36000 :     FOR( slot = 0; slot < hSpatParamRendCom->subframe_nbslots[subframe]; slot++ )
    5392             :     {
    5393       86400 :         FOR( ch = 0; ch < numInChannels; ch++ )
    5394             :         {
    5395       57600 :             test();
    5396       57600 :             IF( ch == 0 || EQ_16( nchan_transport, 2 ) )
    5397       43200 :             {
    5398       43200 :                 Word16 q_cldfb = Q11;
    5399       43200 :                 move16();
    5400       43200 :                 cldfbAnalysis_ts_fx_fixed_q(
    5401       43200 :                     &( output_fx[ch][nBins * slot] ),
    5402       43200 :                     Cldfb_RealBuffer_in_fx[ch][slot],
    5403       43200 :                     Cldfb_ImagBuffer_in_fx[ch][slot],
    5404             :                     nBins, hMasaExtRend->cldfbAnaRend[ch], &q_cldfb );
    5405             :             }
    5406             :             ELSE /* when nchan_transport == 1 and ch == 1 */
    5407             :             {
    5408             :                 /* At mono input duplicate the channel to dual-mono, and apply gain
    5409             :                 correction to ensure same overall level as in stereo mode  */
    5410       14400 :                 v_multc_fixed( Cldfb_RealBuffer_in_fx[0][slot], 1518500224 /* INV_SQRT_2 in Q31 */, Cldfb_RealBuffer_in_fx[0][slot], nBins );
    5411       14400 :                 v_multc_fixed( Cldfb_ImagBuffer_in_fx[0][slot], 1518500224 /* INV_SQRT_2 in Q31 */, Cldfb_ImagBuffer_in_fx[0][slot], nBins );
    5412             : 
    5413       14400 :                 Copy32( Cldfb_RealBuffer_in_fx[0][slot], Cldfb_RealBuffer_in_fx[1][slot], nBins );
    5414       14400 :                 Copy32( Cldfb_ImagBuffer_in_fx[0][slot], Cldfb_ImagBuffer_in_fx[1][slot], nBins );
    5415             :             }
    5416             :         }
    5417             :     }
    5418        7200 :     Word16 q_inp = Q6;
    5419        7200 :     move16();
    5420        7200 :     IF( hCombinedOrientationData )
    5421             :     {
    5422       28800 :         FOR( i = 0; i < 3; i++ )
    5423             :         {
    5424       86400 :             FOR( j = 0; j < 3; j++ )
    5425             :             {
    5426       64800 :                 Rmat_fx[i][j] = hCombinedOrientationData->Rmat_fx[hCombinedOrientationData->subframe_idx][i][j]; // Q30//
    5427       64800 :                 move32();
    5428             :             }
    5429             :         }
    5430             : 
    5431        7200 :         IF( EQ_16( nchan_transport, 2 ) )
    5432             :         {
    5433        3600 :             adaptTransportSignalsHeadtracked_fx( hCombinedOrientationData, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, q_inp, nBins, hSpatParamRendCom->subframe_nbslots[subframe], Rmat_fx );
    5434        3600 :             ivas_dirac_dec_binaural_check_and_switch_transports_headtracked_fx( hCombinedOrientationData, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, nBins, hSpatParamRendCom->subframe_nbslots[subframe], Rmat_fx );
    5435             :         }
    5436             :     }
    5437             : 
    5438        7200 :     test();
    5439        7200 :     ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, Rmat_fx, subframe,
    5440        7200 :                                                                                hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, NULL, q_inp );
    5441             : 
    5442             :     /* Always using CLDFB decorrelation in MASA EXT renderer */
    5443        7200 :     max_band_decorr = hDiracDecBin->h_freq_domain_decorr_ap_params->max_band_decorr;
    5444             : 
    5445        7200 :     ivas_dirac_dec_binaural_determine_processing_matrices_fx( hDiracDecBin, hSpatParamRendCom, &config_data, max_band_decorr, Rmat_fx, subframe,
    5446        7200 :                                                               hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0,
    5447             :                                                               0, NULL );
    5448             : 
    5449             :     Word16 q_out;
    5450        7200 :     q_inp = Q6;
    5451        7200 :     move16();
    5452             : 
    5453       21600 :     FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
    5454             :     {
    5455       14400 :         hMasaExtRend->cldfbSynRend[ch]->Q_cldfb_state = Q11;
    5456       14400 :         move16();
    5457             :     }
    5458             : 
    5459        7200 :     q_mat = hDiracDecBin->q_processMtx;
    5460        7200 :     move16();
    5461        7200 :     q_mat = s_min( q_mat, hDiracDecBin->q_processMtxPrev );
    5462        7200 :     q_mat = s_min( q_mat, hDiracDecBin->q_processMtxDec );
    5463        7200 :     q_mat = s_min( q_mat, hDiracDecBin->q_processMtxDecPrev );
    5464             : 
    5465       21600 :     FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
    5466             :     {
    5467       43200 :         FOR( slot = 0; slot < BINAURAL_CHANNELS; slot++ )
    5468             :         {
    5469       28800 :             Scale_sig( hDiracDecBin->processMtxDecRe_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDec ) );         // scaling to q_mat
    5470       28800 :             Scale_sig( hDiracDecBin->processMtxDecIm_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDec ) );         // scaling to q_mat
    5471       28800 :             Scale_sig( hDiracDecBin->processMtxDecRePrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDecPrev ) ); // scaling to q_mat
    5472       28800 :             Scale_sig( hDiracDecBin->processMtxDecImPrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDecPrev ) ); // scaling to q_mat
    5473             :         }
    5474             :     }
    5475       21600 :     FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
    5476             :     {
    5477       43200 :         FOR( slot = 0; slot < numInChannels; slot++ )
    5478             :         {
    5479       28800 :             Scale_sig( hDiracDecBin->processMtxRe_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) );         // scaling to q_mat
    5480       28800 :             Scale_sig( hDiracDecBin->processMtxIm_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) );         // scaling to q_mat
    5481       28800 :             Scale_sig( hDiracDecBin->processMtxRePrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); // scaling to q_mat
    5482       28800 :             Scale_sig( hDiracDecBin->processMtxImPrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); // scaling to q_mat
    5483             :         }
    5484             :     }
    5485        7200 :     hDiracDecBin->q_processMtx = q_mat;
    5486        7200 :     hDiracDecBin->q_processMtxPrev = q_mat;
    5487        7200 :     hDiracDecBin->q_processMtxDec = q_mat;
    5488        7200 :     hDiracDecBin->q_processMtxDecPrev = q_mat;
    5489        7200 :     move16();
    5490        7200 :     move16();
    5491        7200 :     move16();
    5492        7200 :     move16();
    5493             : 
    5494        7200 :     ivas_dirac_dec_binaural_process_output_fx( hDiracDecBin, hSpatParamRendCom, hMasaExtRend->cldfbSynRend, output_fx, &q_out, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, q_inp, max_band_decorr, numInChannels, config_data.processReverb, subframe, q_mat );
    5495             : 
    5496             : 
    5497        7200 :     hDiracDecBin->hDiffuseDist = NULL;
    5498             : 
    5499        7200 :     hSpatParamRendCom->slots_rendered = add( hSpatParamRendCom->slots_rendered, hSpatParamRendCom->subframe_nbslots[subframe] );
    5500        7200 :     hSpatParamRendCom->subframes_rendered = add( hSpatParamRendCom->subframes_rendered, 1 );
    5501        7200 :     move16();
    5502        7200 :     move16();
    5503             : 
    5504       21600 :     FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
    5505             :     {
    5506       14400 :         scale_sig32( output_fx[ch], nBins * hSpatParamRendCom->subframe_nbslots[subframe], sub( Q11, q_out ) );                                                               // Q11
    5507       14400 :         scale_sig32( hMasaExtRend->cldfbSynRend[ch]->cldfb_state_fx, hMasaExtRend->cldfbSynRend[ch]->cldfb_size, sub( Q11, hMasaExtRend->cldfbSynRend[ch]->Q_cldfb_state ) ); // Q11
    5508       14400 :         hMasaExtRend->cldfbSynRend[ch]->Q_cldfb_state = Q11;
    5509             :     }
    5510             : 
    5511        7200 :     return;
    5512             : }
    5513             : 
    5514        4500 : void ivas_masa_ext_rend_parambin_render_fx(
    5515             :     MASA_EXT_REND_HANDLE hMasaExtRend,                    /* i/o: MASA ext rend structure                                   */
    5516             :     COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i  : combined orientation handle                               */
    5517             :     Word32 *output_f[],                                   /* i/o: synthesized core-coder transport channels/DirAC output Q11*/
    5518             :     const Word16 num_subframes )                          /* i  : number of subframes to render                             */
    5519             : {
    5520             :     Word16 subframe;
    5521             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
    5522             :     Word32 *p_output[BINAURAL_CHANNELS];
    5523             :     Word16 ch;
    5524             : 
    5525        4500 :     hSpatParamRendCom = hMasaExtRend->hSpatParamRendCom;
    5526             : 
    5527       13500 :     FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
    5528             :     {
    5529        9000 :         p_output[ch] = output_f[ch];
    5530             :     }
    5531             : 
    5532        4500 :     hSpatParamRendCom->subframes_rendered = hSpatParamRendCom->dirac_read_idx;
    5533        4500 :     move16();
    5534       11700 :     FOR( subframe = 0; subframe < num_subframes; subframe++ )
    5535             :     {
    5536        7200 :         Word16 n_samples_sf = i_mult( hSpatParamRendCom->slot_size, CLDFB_SLOTS_PER_SUBFRAME );
    5537        7200 :         hSpatParamRendCom->slots_rendered = 0;
    5538        7200 :         move16();
    5539             : 
    5540        7200 :         ivas_masa_ext_rend_parambin_internal_fx( hMasaExtRend, hCombinedOrientationData, p_output, hSpatParamRendCom->dirac_read_idx );
    5541             : 
    5542       21600 :         FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
    5543             :         {
    5544       14400 :             p_output[ch] += n_samples_sf;
    5545             :         }
    5546             : 
    5547        7200 :         ivas_combined_orientation_update_index( hCombinedOrientationData, n_samples_sf );
    5548             : 
    5549        7200 :         hSpatParamRendCom->dirac_read_idx = ( add( hSpatParamRendCom->dirac_read_idx, 1 ) ) % hSpatParamRendCom->dirac_md_buffer_length;
    5550        7200 :         move16();
    5551             :     }
    5552             : 
    5553        4500 :     return;
    5554             : }

Generated by: LCOV version 1.14